rust/vec2d/src/lib.rs
changeset 14032 2869c2ccb1b8
parent 14030 2ebd505e62c1
child 14121 69db1d2e4cec
equal deleted inserted replaced
14031:c47283feafac 14032:2869c2ccb1b8
       
     1 extern crate integral_geometry;
       
     2 
     1 use std::ops::{Index, IndexMut};
     3 use std::ops::{Index, IndexMut};
     2 use std::slice::SliceIndex;
     4 use std::slice::SliceIndex;
       
     5 use integral_geometry::Size;
     3 
     6 
     4 pub struct Vec2D<T> {
     7 pub struct Vec2D<T> {
     5     data: Vec<T>,
     8     data: Vec<T>,
     6     width: usize,
     9     size: Size,
     7     height: usize,
       
     8 }
    10 }
     9 
    11 
    10 impl<T> Index<usize> for Vec2D<T> {
    12 impl<T> Index<usize> for Vec2D<T> {
    11     type Output = [T];
    13     type Output = [T];
    12 
    14 
    13     #[inline]
    15     #[inline]
    14     fn index(&self, row: usize) -> &[T] {
    16     fn index(&self, row: usize) -> &[T] {
    15         debug_assert!(row < self.height);
    17         debug_assert!(row < self.height());
    16 
    18 
    17         let pos = row * self.width;
    19         let pos = row * self.width();
    18 
    20 
    19         &self.data[pos..pos + self.width]
    21         &self.data[pos..pos + self.width()]
    20     }
    22     }
    21 }
    23 }
    22 
    24 
    23 impl<T> IndexMut<usize> for Vec2D<T> {
    25 impl<T> IndexMut<usize> for Vec2D<T> {
    24     #[inline]
    26     #[inline]
    25     fn index_mut(&mut self, row: usize) -> &mut [T] {
    27     fn index_mut(&mut self, row: usize) -> &mut [T] {
    26         debug_assert!(row < self.height);
    28         debug_assert!(row < self.height());
    27 
    29 
    28         let pos = row * self.width;
    30         let pos = row * self.width();
    29 
    31 
    30         &mut self.data[pos..pos + self.width]
    32         &mut self.data[pos..pos + self.size.width]
       
    33     }
       
    34 }
       
    35 
       
    36 impl <T> Vec2D<T> {
       
    37     #[inline]
       
    38     pub fn width(&self) -> usize {
       
    39         self.size.width
       
    40     }
       
    41 
       
    42     #[inline]
       
    43     pub fn height(&self) -> usize {
       
    44         self.size.height
       
    45     }
       
    46 
       
    47     #[inline]
       
    48     pub fn size(&self) -> Size {
       
    49         self.size
    31     }
    50     }
    32 }
    51 }
    33 
    52 
    34 impl<T: Copy> Vec2D<T> {
    53 impl<T: Copy> Vec2D<T> {
    35     pub fn new(width: usize, height: usize, value: T) -> Self {
    54     pub fn new(size: Size, value: T) -> Self {
    36         Self {
    55         Self { size, data: vec![value; size.area()] }
    37             data: vec![value; width * height],
       
    38             width,
       
    39             height,
       
    40         }
       
    41     }
       
    42 
       
    43     #[inline]
       
    44     pub fn width(&self) -> usize {
       
    45         self.width
       
    46     }
       
    47 
       
    48     #[inline]
       
    49     pub fn height(&self) -> usize {
       
    50         self.height
       
    51     }
    56     }
    52 
    57 
    53     #[inline]
    58     #[inline]
    54     pub fn get(&self, row: usize, column: usize) -> Option<&<usize as SliceIndex<[T]>>::Output> {
    59     pub fn get(&self, row: usize, column: usize) -> Option<&<usize as SliceIndex<[T]>>::Output> {
    55         self.data.get(row * self.width + column)
    60         self.data.get(row * self.width() + column)
    56     }
    61     }
    57 
    62 
    58     #[inline]
    63     #[inline]
    59     pub fn get_mut(&mut self, row: usize, column: usize) -> Option<&mut <usize as SliceIndex<[T]>>::Output> {
    64     pub fn get_mut(&mut self, row: usize, column: usize) -> Option<&mut <usize as SliceIndex<[T]>>::Output> {
    60         self.data.get_mut(row * self.width + column)
    65         self.data.get_mut(row * self.size.width + column)
    61     }
    66     }
    62 
    67 
    63     #[inline]
    68     #[inline]
    64     pub unsafe fn get_unchecked(&self, row: usize, column: usize) -> &<usize as SliceIndex<[T]>>::Output {
    69     pub unsafe fn get_unchecked(&self, row: usize, column: usize) -> &<usize as SliceIndex<[T]>>::Output {
    65         self.data.get_unchecked(row * self.width + column)
    70         self.data.get_unchecked(row * self.width() + column)
    66     }
    71     }
    67 
    72 
    68     #[inline]
    73     #[inline]
    69     pub unsafe fn get_unchecked_mut(&mut self, row: usize, column: usize) -> &mut <usize as SliceIndex<[T]>>::Output {
    74     pub unsafe fn get_unchecked_mut(&mut self, row: usize, column: usize) -> &mut <usize as SliceIndex<[T]>>::Output {
    70         self.data.get_unchecked_mut(row * self.width + column)
    75         self.data.get_unchecked_mut(row * self.size.width + column)
    71     }
    76     }
    72 
    77 
    73     #[inline]
    78     #[inline]
    74     pub fn rows(&self) -> impl Iterator<Item = &[T]> {
    79     pub fn rows(&self) -> impl Iterator<Item = &[T]> {
    75         self.data.chunks(self.width)
    80         self.data.chunks(self.width())
    76     }
    81     }
    77 }
    82 }
    78 
    83 
    79 #[cfg(test)]
    84 #[cfg(test)]
    80 mod tests {
    85 mod tests {
    81     use super::*;
    86     use super::*;
    82 
    87 
    83     #[test]
    88     #[test]
    84     fn basics() {
    89     fn basics() {
    85         let mut v: Vec2D<u8> = Vec2D::new(2, 3, 0xff);
    90         let mut v: Vec2D<u8> = Vec2D::new(Size::new(2, 3), 0xff);
    86 
    91 
    87         assert_eq!(v.width, 2);
    92         assert_eq!(v.width(), 2);
    88         assert_eq!(v.height, 3);
    93         assert_eq!(v.height(), 3);
    89 
    94 
    90         assert_eq!(v[0][0], 0xff);
    95         assert_eq!(v[0][0], 0xff);
    91         assert_eq!(v[2][1], 0xff);
    96         assert_eq!(v[2][1], 0xff);
    92 
    97 
    93         v[2][1] = 0;
    98         v[2][1] = 0;