1use std::ops::{Index, IndexMut};
2
3#[derive(Debug)]
5pub struct Vec2D<T> {
6 data: Box<[T]>,
7 cols: usize,
8}
9
10impl<T> Vec2D<T> {
11 pub fn init(data: T, size: (usize, usize)) -> Vec2D<T>
13 where
14 T: Clone,
15 {
16 let (rows, cols) = size;
17 let len = rows
18 .checked_mul(cols)
19 .unwrap_or_else(|| panic!("{} rows by {} cols exceeds usize::MAX", rows, cols));
20 Vec2D {
21 data: vec![data; len].into_boxed_slice(),
22 cols,
23 }
24 }
25
26 pub fn fill(&mut self, value: T)
28 where
29 T: Clone,
30 {
31 self.data.fill(value)
32 }
33}
34
35impl<T> Index<usize> for Vec2D<T> {
36 type Output = [T];
37
38 #[inline]
39 fn index(&self, row: usize) -> &Self::Output {
40 let start_row = row
41 .checked_mul(self.cols)
42 .unwrap_or_else(|| panic!("{} row by {} cols exceeds usize::MAX", row, self.cols));
43 &self.data[start_row..start_row + self.cols]
44 }
45}
46
47impl<T> IndexMut<usize> for Vec2D<T> {
48 #[inline]
49 fn index_mut(&mut self, row: usize) -> &mut Self::Output {
50 let start_row = row
51 .checked_mul(self.cols)
52 .unwrap_or_else(|| panic!("{} row by {} cols exceeds usize::MAX", row, self.cols));
53 &mut self.data[start_row..start_row + self.cols]
54 }
55}
56
57#[cfg(test)]
58mod test {
59 use super::*;
60
61 #[test]
62 fn init() {
63 let vec2d = Vec2D::init(1, (2, 3));
64 assert_eq!(vec2d[0], [1, 1, 1]);
65 assert_eq!(vec2d[1], [1, 1, 1]);
66 }
67
68 #[test]
69 #[should_panic]
70 fn init_overflow() {
71 Vec2D::init(1, (usize::MAX, usize::MAX));
72 }
73
74 #[test]
75 fn fill() {
76 let mut vec2d = Vec2D::init(0, (2, 3));
77 vec2d.fill(7);
78 assert_eq!(vec2d[0], [7, 7, 7]);
79 assert_eq!(vec2d[1], [7, 7, 7]);
80 }
81
82 #[test]
83 fn index() {
84 let vec2d = Vec2D {
85 data: vec![0, 1, 2, 3, 4, 5, 6, 7].into_boxed_slice(),
86 cols: 2,
87 };
88 assert_eq!(vec2d[0], [0, 1]);
89 assert_eq!(vec2d[1], [2, 3]);
90 assert_eq!(vec2d[2], [4, 5]);
91 assert_eq!(vec2d[3], [6, 7]);
92 }
93
94 #[test]
95 fn indexmut() {
96 let mut vec2d = Vec2D {
97 data: vec![0, 1, 2, 3, 4, 5, 6, 7].into_boxed_slice(),
98 cols: 2,
99 };
100
101 vec2d[1][1] = 9;
102 assert_eq!(vec2d[0], [0, 1]);
103 assert_eq!(vec2d[1], [2, 9]);
105 assert_eq!(vec2d[2], [4, 5]);
106 assert_eq!(vec2d[3], [6, 7]);
107 }
108
109 #[test]
110 #[should_panic]
111 fn index_out_of_bounds() {
112 let vec2d = Vec2D::init(1, (2, 3));
113 let _x = vec2d[2][3];
114 }
115
116 #[test]
117 #[should_panic]
118 fn index_out_of_bounds_vec_edge() {
119 let vec2d = Vec2D::init(1, (2, 3));
120 let _x = vec2d[1][3];
121 }
122
123 #[test]
124 #[should_panic]
125 fn index_column_out_of_bounds() {
126 let vec2d = Vec2D::init(1, (2, 3));
127 let _x = vec2d[0][3];
128 }
129
130 #[test]
131 #[should_panic]
132 fn index_row_out_of_bounds() {
133 let vec2d = Vec2D::init(1, (2, 3));
134 let _x = vec2d[2][0];
135 }
136
137 #[test]
138 #[should_panic]
139 fn index_mul_overflow() {
140 let matrix = Vec2D::init(0, (3, 4));
142 let row = (usize::MAX / 4) + 1;
144 let _ = matrix[row];
146 }
147
148 #[test]
149 #[should_panic]
150 fn index_add_overflow() {
151 let matrix = Vec2D::init(0, (3, 5));
153 let row = usize::MAX / 5;
156 let _ = matrix[row];
158 }
159
160 #[test]
161 #[should_panic]
162 fn indexmut_out_of_bounds() {
163 let mut vec2d = Vec2D::init(1, (2, 3));
164 vec2d[2][3] = 0;
165 }
166
167 #[test]
168 #[should_panic]
169 fn indexmut_out_of_bounds_vec_edge() {
170 let mut vec2d = Vec2D::init(1, (2, 3));
171 vec2d[1][3] = 0;
172 }
173
174 #[test]
175 #[should_panic]
176 fn indexmut_column_out_of_bounds() {
177 let mut vec2d = Vec2D::init(1, (2, 3));
178 vec2d[0][3] = 0;
179 }
180
181 #[test]
182 #[should_panic]
183 fn indexmut_row_out_of_bounds() {
184 let mut vec2d = Vec2D::init(1, (2, 3));
185 vec2d[2][0] = 0;
186 }
187
188 #[test]
189 #[should_panic]
190 fn indexmut_mul_overflow() {
191 let mut matrix = Vec2D::init(0, (3, 4));
193 let row = (usize::MAX / 4) + 1;
195 matrix[row][0] = 9;
197 }
198
199 #[test]
200 #[should_panic]
201 fn indexmut_add_overflow() {
202 let mut matrix = Vec2D::init(0, (3, 5));
204 let row = usize::MAX / 5;
207 matrix[row][0] = 9;
209 }
210}