Figured out a clever way to do bounds checking, but is it too clever?
Let's say you have a 2D array grid and you want to find the left (or top, right, bottom) neighbor coordinates of a cell if it exists. That is, if the neighbor is not in the grid, return None, otherwise return the neighbor's x and y coordinates. Previously I was doing it like this:
\tfn get_neighbor(x: usize, y: usize, dx: isize, dy: isize, width: usize, height: usize) -> Option<(usize, usize)> {
\t let nx = x as isize + dx;
\t let ny = y as isize + dy;
\t if nx >= 0 && nx < width as isize && ny >= 0 && ny < height as isize {
\t\tSome((nx as usize, ny as usize))
\t } else {
\t\tNone
\t }
\t}
Makes sense. Indexes into an array are usize, but to check the left neighbor, dx has to be signed. As a result, 6 casts in total need to be performed, and 4 boolean checks. I was trying to get rid of the casts, and came up with this:
\tfn get_neighbor(x: usize, y: usize, dx: isize, dy: isize, width: usize, height: usize) -> Option<(usize, usize)> {
\t let nx = x.wrapping_add_signed(dx);
let ny = y.wrapping_add_signed(dy);
\t if nx < width && ny < height {
\t\tSome((nx, ny))
\t } else {
\t\tNone
\t }
\t}
Does this technique have a name? I've never seen it before, but I think it should basically always work? My grid sizes are like 5 columns wide and 20 rows tall, and I usually am only checking the left, right, top, or bottom neighbors, so dx and dy are generally always either -1, 0, or 1.
The idea is that you get two bounds checks for free because instead of the coordinate becoming negative, it wraps around over to usize::MAX (18446744073709551615). And then you can also get rid of two boolean checks because going off the grid to the left wraps all the way around and then 18446744073709551611 < 5 obviously fails (and you of course never need to check if a usize is positive, since it's guaranteed to be).
It seems a bit hacky, and I'm not sure if there's something I'm missing, or is this a valid optimization? Seems to get rid of 6 casts and 2 if checks.