|
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; |