rust/integral-geometry/src/lib.rs
changeset 14032 2869c2ccb1b8
parent 14031 c47283feafac
child 14052 9c817b2eedae
--- 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<T: Into<usize>>(&self, x: T) -> bool {
+        (self.size.width & x.into()) == 0
+    }
+
+    #[inline]
+    pub fn contains_y<T: Into<usize>>(&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 {