diff -r c47283feafac -r 2869c2ccb1b8 rust/integral-geometry/src/lib.rs --- a/rust/integral-geometry/src/lib.rs Tue Oct 30 05:55:58 2018 +0300 +++ b/rust/integral-geometry/src/lib.rs Tue Oct 30 19:05:52 2018 +0300 @@ -45,6 +45,73 @@ } } +#[derive(PartialEq, Eq, Clone, Copy, Debug)] +pub struct Size { + pub width: usize, + pub height: usize, +} + +impl Size { + #[inline] + pub fn new(width: usize, height: usize) -> Self { + Size { width, height } + } + + #[inline] + pub fn square(size: usize) -> Self { + Size { width: size, height: size } + } + + #[inline] + pub fn area(&self) -> usize { + self.width * self.height + } + + #[inline] + pub fn linear_index(&self, x: usize, y: usize) -> usize { + y * self.width + x + } + + #[inline] + pub fn is_power_of_two(&self) -> bool { + self.width.is_power_of_two() && self.height.is_power_of_two() + } + + #[inline] + pub fn to_mask(&self) -> SizeMask { + SizeMask::new(*self) + } +} + +pub struct SizeMask{ size: Size } + +impl SizeMask { + #[inline] + pub fn new(size: Size) -> Self { + assert!(size.is_power_of_two()); + let size = Size { + width: !(size.width - 1), + height: !(size.height - 1) + }; + SizeMask { size } + } + + #[inline] + pub fn contains_x>(&self, x: T) -> bool { + (self.size.width & x.into()) == 0 + } + + #[inline] + pub fn contains_y>(&self, y: T) -> bool { + (self.size.height & y.into()) == 0 + } + + #[inline] + pub fn contains(&self, point: Point) -> bool { + self.contains_x(point.x as usize) && self.contains_y(point.y as usize) + } +} + macro_rules! bin_op_impl { ($op: ty, $name: tt) => { impl $op for Point {