1
2#[derive (Clone)]
5pub struct Vec2d<T> {
6 data: Vec<T>,
7 width: usize,
8}
9
10
11impl<T: Default> Vec2d<T> {
12 pub fn new_with_default(rows: usize, cols: usize) -> Vec2d<T> {
14 Vec2d::new_empty(rows, cols).initialize_to_default()
15 }
16
17 pub fn add_row_of_default(&mut self) {
20 if self.width == 0 { self.width += 1; }
23 let size = self.count() + self.width;
24 while self.data.len() < size {
25 self.data.push(T::default());
26 }
27 }
28
29 pub fn add_col_of_default(&mut self) {
31 let new_width = self.width + 1;
34 let mut idx = self.width;
35 for _row in 0..self.count_rows() {
36 self.data.insert(idx, T::default());
37 idx += new_width;
38 }
39 self.width = new_width;
40 }
41
42 fn initialize_to_default(mut self) -> Vec2d<T> {
44 let size = self.data.capacity();
45 while self.data.len() < size {
46 self.data.push(T::default());
47 }
48 self
49 }
50}
51
52impl<T: Copy> Vec2d<T> {
53 pub fn new_with_value(rows: usize, cols: usize, val:T) -> Vec2d<T> {
55 Vec2d::new_empty(rows, cols).initialize_to_value(val)
56 }
57
58 pub fn from(width: usize, arr: &[T]) -> Vec2d<T> {
62 let size = arr.len();
63 assert_eq!(size % width, 0);
64 let mut data: Vec<T> = Vec::with_capacity(size);
65 for idx in 0..size {
66 data.push(arr[idx]);
67 }
68 Vec2d {
69 data,
70 width,
71 }
72 }
73
74 pub fn insert_col(&mut self, index: usize, data: &[T]) {
76 let size: usize = data.len();
77 if self.width == 0 {
79 self.width = 1;
80 for item in data {
81 self.data.push(*item);
82 }
83 }
84 else {
85 assert_eq!(size, self.count_rows());
86 let mut idx = index;
87 self.width += 1;
88 for row in 0..size {
89 self.data.insert(idx, data[row]);
90 idx += self.width;
91 }
92 }
93 }
94
95 pub fn insert_row(&mut self, index: usize, data: &[T]) {
98 if self.width > 0 {
102 assert_eq!(self.width, data.len());
103 let mut idx = self.width * index;
106 for item in data {
107 self.data.insert(idx, *item);
108 idx += 1;
109 }
110 }
111 else { self.push_row(data); }
112 }
113
114 pub fn push_col(&mut self, data: &[T]) {
117 self.insert_col(self.count_cols(), data);
118 }
119
120 pub fn push_row(&mut self, data: &[T]) {
123 if self.width > 0 { assert_eq!(self.width, data.len()); }
127 else { self.width = data.len(); }
128 for item in data {
129 self.data.push(*item);
130 }
131 }
132
133 fn initialize_to_value(mut self, val: T) -> Vec2d<T> {
135 let size = self.data.capacity();
136 while self.data.len() < size {
137 self.data.push(val);
138 }
139 self
140 }
141}
142
143impl<T: PartialEq> Vec2d<T> {
144
145 pub fn contains(&self, val: &T) -> bool {
148 for idx in 0..self.count() {
149 if *val == self.data[idx] { return true; }
150 }
151 false
152 }
153}
154
155
156impl<T> Vec2d<T> {
157 pub fn new() -> Vec2d<T> {
159 Vec2d {
161 data: Vec::new(),
162 width: 0,
163 }
164 }
165
166 pub fn from_fn(rows: usize, cols: usize, initializer: &dyn Fn(usize, usize) -> T) -> Vec2d<T> {
170 Vec2d::new_empty(rows, cols).initialize_from_fn(initializer)
171 }
172
173 pub fn as_ptr(&self) -> *const T {
175 self.data.as_ptr()
176 }
177
178 pub fn as_vec(&self) -> &Vec<T> {
180 &self.data
181 }
182
183 pub fn count(&self) -> usize {
186 self.width * self.count_rows()
187 }
188
189 pub fn count_cols(&self) -> usize {
191 self.width
192 }
193
194 pub fn count_rows(&self) -> usize {
196 if self.width == 0 { 0 } else { self.data.len() / self.width }
197 }
198
199 pub fn size(&self) -> (usize, usize) {
201 (self.count_rows(), self.count_cols())
202 }
203
204 fn new_empty(rows: usize, cols: usize) -> Vec2d<T> {
206 Vec2d {
207 data: Vec::with_capacity(rows*cols),
208 width: cols,
209 }
210 }
211
212 fn initialize_from_fn(mut self, initializer: &dyn Fn(usize, usize) -> T) -> Vec2d<T> {
213 let size = self.data.capacity();
214 for idx in 0..size {
215 let row = idx / self.width;
216 let col = idx - (row * self.width);
217 self.data.push(initializer(row, col));
218 }
219 self
220 }
221}
222
223impl<T> std::ops::Index<usize> for Vec2d<T> {
224 type Output = [T];
225
226 fn index(&self, row: usize) -> &[T] {
227 let start = row * self.width;
228 let end = start + self.width;
229 &self.data[start..end]
230 }
231}
232
233impl<T> std::ops::IndexMut<usize> for Vec2d<T> {
234 fn index_mut(&mut self, row: usize) -> &mut Self::Output {
235 let start = row * self.width;
236 let end = start + self.width;
237 &mut self.data[start..end]
238 }
239}
240
241#[cfg(test)]
242mod tests {
243 use super::*;
244
245 #[test]
246 fn check_initializer() {
247 let v = Vec2d::from_fn(3, 3, &|row, col| row + col);
248 for idx in 0..v.count() {
249 let row = idx / v.count_cols();
250 let col = idx - (row * v.count_cols());
251 assert_eq!(v[row][col], row+col);
252 }
253 }
254
255 #[test]
256 #[should_panic]
257 fn panics_on_mismatched_arr_size() {
258 let arr: [i32;4] = [1,2,3,4];
259 let slc: &[i32] = &arr[0..3];
260 let _v: Vec2d<i32> = Vec2d::from(2, slc);
261 let arr: [i32;5] = [1,2,3,4,5];
262 let _v = Vec2d::from(2, &arr);
263 }
264
265 #[test]
266 fn build_from_data() {
267 let data: [i32;12] = [1,2,3,4,5,6,7,8,9,10,11,12];
268 for divs in 1..13 {
269 if 12 % divs == 0 {
270 let _v = Vec2d::from(divs, &data);
271 for row in 0.._v.count_rows() {
272 for col in 0.._v.count_cols() {
273 let idx = row * _v.count_cols() + col;
274 assert_eq!(data[idx], _v[row][col]);
275 }
276 }
277 }
278 }
279 }
280
281 #[test]
282 fn build_from_defaults() {
283 type DataType = i32;
284 let mut v:Vec2d<DataType> = Vec2d::new();
285 assert_eq!(v.count(), 0);
286 v.add_row_of_default();
287 assert_eq!(v.count_rows(), 1);
288 v.add_row_of_default();
289 v.add_col_of_default();
290 assert_eq!(v.count(), 4);
291 assert_eq!(v.count_rows(), 2);
292 assert_eq!(v.count_cols(), 2);
293 }
294
295 #[test]
296 fn test_data_pushing() {
297 type DataType = i32;
298 let mut v: Vec2d<DataType> = Vec2d::new();
299 let data = [1,2,3,4,5,6,7,8,9,10,11,12];
300 v.push_row(&data[0..1]);
301 v.push_col(&data[1..2]);
302 v.push_row(&data[2..4]);
303 v.push_row(&data[4..6]);
304 v.push_col(&data[6..9]);
305 v.push_col(&data[9..12]);
306 assert_eq!(v.count(), 12);
307 assert_eq!(v.count_rows(), 3);
308 assert_eq!(v.count_cols(), 4);
309 let answers = [1,2,7,10,3,4,8,11,5,6,9,12];
310 let mut idx: usize = 0;
311 for row in 0..v.count_rows() {
312 for col in 0..v.count_cols() {
313 assert_eq!(v[row][col], answers[idx]);
314 idx += 1;
315 }
316 }
317 }
318
319 #[test]
320 fn test_data_insertion() {
321 type DataType = i32;
322 let mut v: Vec2d<DataType> = Vec2d::new();
323 let data = [1,2,3,4,5,6,7,8,9,10,11,12];
324 v.insert_row(0,&data[0..1]);
325 v.insert_col(0,&data[1..2]);
326 v.insert_row(1,&data[2..4]);
327 v.insert_row(1, &data[4..6]);
328 v.insert_col(1,&data[6..9]);
329 v.insert_col(3,&data[9..12]);
330 assert_eq!(v.count(), 12);
331 assert_eq!(v.count_rows(), 3);
332 assert_eq!(v.count_cols(), 4);
333 let answers = [2,7,1,10,5,8,6,11,3,9,4,12];
334 let mut idx: usize = 0;
335 for row in 0..v.count_rows() {
336 for col in 0..v.count_cols() {
337 assert_eq!(v[row][col], answers[idx]);
338 idx += 1;
339 }
340 }
341 }
342}