array2ds/
lib.rs

1pub mod array2d {
2    use core::iter::{DoubleEndedIterator, Iterator};
3    use core::mem;
4    use core::ops::{Index, IndexMut};
5
6    /// trait that is used for indexing the 2d array
7    pub trait GridIdx {
8        fn no_row(&self) -> usize;
9        fn no_column(&self) -> usize;
10    }
11
12    #[derive(Debug)]
13    pub struct ColumMut<'a, T>
14    {
15        pub(super) v: &'a mut [T],
16        pub(super) skip: usize,
17    }
18
19    impl<'a, T> Index<usize> for ColumMut<'a, T>
20    {
21        type Output = T;
22
23        fn index(&self, idx: usize) -> &Self::Output {
24            let pos = idx * (1 + self.skip);
25            &self.v[pos]
26        }
27    }
28
29    impl<'a, T> IndexMut<usize> for ColumMut<'a, T>
30    {
31        /// indexing the column, mutable
32        fn index_mut(&mut self, idx: usize) -> &mut Self::Output {
33            let pos = idx * (1 + self.skip);
34            &mut self.v[pos]
35        }
36    }
37
38    impl<'a, T> Iterator for ColumMut<'a, T>
39    {
40        type Item = &'a mut T;
41
42        /// next item in the column, mutable
43        fn next(&mut self) -> Option<Self::Item> {
44            let tmp = mem::take(&mut self.v);
45            if let Some((fst, snd)) = tmp.split_first_mut() {
46                if snd.is_empty() {
47                    self.v = &mut [];
48                } else {
49                    self.v = snd.get_mut(self.skip..).unwrap();
50                }
51                Some(fst)
52            } else {
53                None
54            }
55        }
56    }
57
58    #[derive(Debug)]
59    pub struct Column<'a, T>
60    {
61        pub(super) v: &'a [T],
62        pub(super) skip: usize,
63    }
64
65    impl<'a, T> Index<usize> for Column<'a, T>
66    {
67        type Output = T;
68
69        fn index(&self, idx: usize) -> &Self::Output {
70            let pos = idx * (1 + self.skip);
71            &self.v[pos]
72        }
73    }
74
75    impl<'a, T> Iterator for Column<'a, T>
76    {
77        type Item = &'a T;
78
79        /// next item in the column
80        fn next(&mut self) -> Option<Self::Item> {
81            if let Some((fst, snd)) = self.v.split_first() {
82                if snd.is_empty() {
83                    self.v = &[];
84                } else {
85                    self.v = snd.get(self.skip..).unwrap();
86                }
87                Some(fst)
88            } else {
89                None
90            }
91        }
92    }
93
94    /// wrapper struct for iterating over rows
95    #[derive(Debug)]
96    pub struct Rows<'a, T> {
97        pub(super) v: &'a [T],
98        pub(super) columns: usize,
99        pub(super) skip_columns: usize,
100    }
101
102    impl<'a, T> DoubleEndedIterator for Rows<'a, T>
103    {
104        fn next_back(&mut self) -> Option<Self::Item> {
105            if self.v.is_empty() {
106                None
107            } else {
108                let (fst, snd) = self.v.split_at(self.v.len() - self.columns);
109                if fst.is_empty() {
110                    self.v = &[];
111                } else {
112                    self.v = fst.get(..fst.len() - self.skip_columns).unwrap();
113                }
114                Some(snd)
115            }
116        }
117
118        fn nth_back(&mut self, n: usize) -> Option<Self::Item> {
119            let (adj,overflow) = n.overflowing_mul(self.columns + self.skip_columns);
120            if adj >= self.v.len() || overflow{
121                self.v = &[];
122            }else{
123                self.v = self.v.get(..self.v.len() - adj).unwrap();
124            }
125            self.next_back()
126        }
127
128
129    }
130
131    impl<'a, T> Iterator for Rows<'a, T>
132    {
133        type Item = &'a [T];
134
135        fn next(&mut self) -> Option<Self::Item> {
136            if self.v.is_empty() {
137                None
138            } else {
139                let (fst, snd) = self.v.split_at(self.columns);
140                if snd.is_empty() {
141                    self.v = &[];
142                } else {
143                    self.v = snd.get(self.skip_columns..).unwrap();
144                }
145
146                Some(fst)
147            }
148        }
149    }
150
151    /// wrapper struct for iterating over mutable rows
152    #[derive(Debug)]
153    pub struct RowsMut<'a, T> {
154        pub(super) v: &'a mut [T],
155        pub(super) no_columns: usize,
156        pub(super) skip_columns: usize,
157    }
158
159    impl<'a, T> DoubleEndedIterator for RowsMut<'a, T>
160    {
161        fn next_back(&mut self) -> Option<Self::Item> {
162            if self.v.is_empty() {
163                None
164            } else {
165                let tmp = mem::take(&mut self.v);
166                let tmp_len = tmp.len();
167                let (fst, snd) = tmp.split_at_mut(tmp_len - self.no_columns);
168                if fst.is_empty() {
169                    self.v = &mut [];
170                } else {
171                    self.v = fst.get_mut(..tmp_len - self.no_columns - self.skip_columns).unwrap();
172                }
173                Some(snd)
174            }
175        }
176
177        fn nth_back(&mut self, n: usize) -> Option<Self::Item> {
178            let (adj,overflow)  = n.overflowing_mul(self.no_columns + self.skip_columns);
179            if adj >= self.v.len() || overflow{
180                self.v = &mut [];
181            }
182            else {
183                let tmp = mem::take(&mut self.v);
184                self.v = tmp.get_mut(..self.v.len() - adj).unwrap();
185            }
186
187            self.next_back()
188        }
189    }
190
191    impl<'a, T> Iterator for RowsMut<'a, T> {
192        type Item = &'a mut [T];
193
194        fn next(&mut self) -> Option<Self::Item> {
195            if !self.v.is_empty() && self.skip_columns < self.no_columns {
196                let tmp = mem::take(&mut self.v);
197                let (head, tail) = tmp.split_at_mut(self.no_columns);
198                if tail.is_empty() {
199                    self.v = &mut [];
200                } else {
201                    self.v = tail.get_mut(self.skip_columns..).unwrap()
202                }
203                return Some(head);
204            }
205            None
206        }
207    }
208
209    /// struct that expresses index in 2d array
210    pub struct GridPos {
211        pub row: usize,
212        pub column: usize,
213    }
214
215    impl GridPos {
216        pub fn new(r: usize, c: usize) -> Self {
217            Self { row: r, column: c }
218        }
219    }
220
221    impl GridIdx for GridPos {
222        fn no_row(&self) -> usize {
223            self.row
224        }
225
226        fn no_column(&self) -> usize {
227            self.column
228        }
229    }
230
231    impl GridIdx for (usize, usize) {
232        fn no_row(&self) -> usize {
233            self.0
234        }
235
236        fn no_column(&self) -> usize {
237            self.1
238        }
239    }
240
241    impl GridIdx for [usize; 2] {
242        fn no_row(&self) -> usize {
243            self[0]
244        }
245
246        fn no_column(&self) -> usize {
247            self[1]
248        }
249    }
250
251    #[derive(Debug)]
252    /// the main struct for the 2d array
253    pub struct Array2d<T> {
254        vec_slice: Box<[T]>,
255        no_rows: usize,
256        no_columns: usize,
257    }
258
259    /// default implementation, creates an empty array
260    impl<T> Default for Array2d<T> {
261        fn default() -> Self {
262            Array2d {
263                vec_slice: Box::new([]),
264                no_rows: 0,
265                no_columns: 0,
266            }
267        }
268    }
269
270    impl<T> Array2d<T> {
271        /// create a new 2d array each elem of type T where T is clonable
272        pub fn filled_with(element: T, r: usize, c: usize) -> Self
273            where
274                T: Clone,
275        {
276            assert!(r >= 1 && c >= 1);
277            let v = vec![element; r * c];
278            let vb = v.into_boxed_slice();
279            Array2d {
280                vec_slice: vb,
281                no_rows: r,
282                no_columns: c,
283            }
284        }
285
286        // get mutable column
287        pub fn column_mut(&mut self, no_column: usize) -> ColumMut<'_, T>
288        {
289            assert!(no_column < self.column_count());
290            let c = self.column_count();
291            ColumMut {
292                v: self.vec_slice.get_mut(no_column..self.vec_slice.len() - self.column_count() + no_column + 1).unwrap(),
293                skip: c - 1,
294            }
295        }
296
297        /// get column
298        pub fn column(&self, no_column: usize) -> Column<'_, T>
299        {
300            assert!(no_column < self.column_count());
301            Column {
302                v: self.vec_slice.get(no_column..self.vec_slice.len() - self.column_count() + no_column + 1).unwrap(),
303                skip: self.column_count() - 1,
304            }
305        }
306
307        /// create a new 2d array each elem of type T where T is the default implementation
308        pub fn filled_with_default(r: usize, c: usize) -> Self
309            where
310                T: Default,
311        {
312            assert!(r >= 1 && c >= 1);
313            let mut v = Vec::with_capacity(r * c);
314            for _ in 0..(r * c) {
315                v.push(T::default());
316            }
317            let vb = v.into_boxed_slice();
318            Array2d {
319                vec_slice: vb,
320                no_rows: r,
321                no_columns: c,
322            }
323        }
324
325        /// return the 2d array as 1d slice iterable
326        pub fn iter(&self) -> impl Iterator<Item=&T> {
327            self.vec_slice.iter()
328        }
329
330        /// return the row count
331        pub fn row_count(&self) -> usize {
332            self.no_rows
333        }
334
335        /// return the column count
336        pub fn column_count(&self) -> usize {
337            self.no_columns
338        }
339
340        /// convert 2d position to 1d position row_to * column_count + column_to, row_major
341        pub fn d2_index_d1<F>(&self, pos: &F) -> usize
342            where
343                F: GridIdx,
344        {
345            pos.no_row() * self.column_count() + pos.no_column()
346        }
347
348        /// swap two position values
349        pub fn swap<F, K>(&mut self, pos1: &F, pos2: &K)
350            where
351                F: GridIdx,
352                K: GridIdx,
353        {
354            let converted_rc1 = self.d2_index_d1(pos1);
355            let converted_rc2 = self.d2_index_d1(pos2);
356            self.vec_slice.swap(converted_rc1, converted_rc2);
357        }
358
359        /// return the row between containing the index
360        pub fn row_between(&self, row_index: usize) -> (usize, usize) {
361            assert!(row_index < self.row_count());
362            let start = row_index * self.column_count();
363            let end = start + self.column_count();
364            (start, end)
365        }
366
367        /// return row as iterable
368        pub fn iter_row(&self, row_index: usize) -> impl Iterator<Item=&T> {
369            let (start, end) = self.row_between(row_index);
370            self.vec_slice[start..end].iter()
371        }
372
373        /// return row as mutable
374        pub fn mut_row(&mut self, row_index: usize) -> &mut [T] {
375            let (start, end) = self.row_between(row_index);
376            &mut self.vec_slice[start..end]
377        }
378
379        /// return row as mutable iterable
380        pub fn iter_mut_row(&mut self, row_index: usize) -> impl Iterator<Item=&mut T> {
381            let (start, end) = self.row_between(row_index);
382            self.vec_slice[start..end].iter_mut()
383        }
384
385        /// iterate over the rows as mutable
386        pub fn iter_mut_rows(&mut self) -> RowsMut<'_, T> {
387            let c = self.column_count();
388            RowsMut {
389                v: &mut self.vec_slice,
390                no_columns: c,
391                skip_columns: 0,
392            }
393        }
394
395        /// iterate over the rows
396        pub fn iter_rows(&self) -> Rows<'_, T> {
397            //impl Iterator<Item=impl Iterator<Item=&T>> {
398            //(0_usize..self.row_count()).map(move |row_index| self.iter_row(row_index))
399            let c = self.column_count();
400            Rows {
401                v: &self.vec_slice,
402                columns: c,
403                skip_columns: 0,
404            }
405        }
406
407        pub fn as_slice(&self) -> &[T] {
408            &self.vec_slice
409        }
410    }
411
412    impl<T, Idx: GridIdx> Index<Idx> for Array2d<T> {
413        type Output = T;
414        fn index(&self, index: Idx) -> &Self::Output {
415            &self.vec_slice[self.d2_index_d1(&GridPos::new(index.no_row(), index.no_column()))]
416        }
417    }
418
419    impl<T, Idx: GridIdx> IndexMut<Idx> for Array2d<T> {
420        fn index_mut(&mut self, index: Idx) -> &mut Self::Output {
421            &mut self.vec_slice[self.d2_index_d1(&GridPos::new(index.no_row(), index.no_column()))]
422        }
423    }
424}