toodee/
iter.rs

1use core::mem;
2use core::ops::{Index, IndexMut};
3
4/// An `Iterator` that knows how many columns it emits per row.
5pub trait TooDeeIterator : Iterator {
6    /// The number of columns the iterator emits per row
7    fn num_cols(&self) -> usize;
8}
9
10/// An `Iterator` over each row of a `TooDee[View]`, where each row is represented as a slice.
11#[derive(Debug)]
12pub struct Rows<'a, T> {
13    /// This reference contains row data at each end. When iterating in either direction the row will
14    /// be pulled off the end then `skip_cols` elements will be skipped in preparation for reading the
15    /// next row.
16    pub(super) v: &'a [T],
17    pub(super) cols: usize,
18    pub(super) skip_cols: usize,
19}
20
21impl<'a, T> Iterator for Rows<'a, T> {
22
23    type Item = &'a [T];
24
25    #[inline]
26    fn next(&mut self) -> Option<Self::Item> {
27        if self.v.is_empty() {
28            None
29        } else {
30            let (fst, snd) = self.v.split_at(self.cols);
31            if snd.is_empty() {
32                self.v = &[];
33            } else {
34                // snd must contain at least one row, so no check required
35                unsafe {
36                    self.v = snd.get_unchecked(self.skip_cols..);
37                }
38            }
39            Some(fst)
40        }
41    }
42
43    #[inline]
44    fn size_hint(&self) -> (usize, Option<usize>) {
45        if self.cols == 0 {
46            return (0, Some(0));
47        }
48        let len = self.v.len();
49        let denom = self.cols + self.skip_cols;
50        let n = len / denom + (len % denom) / self.cols;
51        (n, Some(n))
52    }
53
54    #[inline]
55    fn count(self) -> usize {
56        self.len()
57    }
58    
59    #[inline]
60    fn nth(&mut self, n: usize) -> Option<Self::Item> {
61        
62        let (start, overflow) = n.overflowing_mul(self.cols + self.skip_cols);
63        if start >= self.v.len() || overflow {
64            self.v = &[];
65        } else {
66            let (_, snd) = self.v.split_at(start);
67            self.v = snd;
68        }
69        self.next()
70    }
71
72    #[inline]
73    fn last(mut self) -> Option<Self::Item> {
74        self.next_back()
75    }    
76}
77
78impl<'a, T> DoubleEndedIterator for Rows<'a, T> {
79    #[inline]
80    fn next_back(&mut self) -> Option<Self::Item> {
81        if self.v.is_empty() {
82            None
83        } else {
84            let (fst, snd) = self.v.split_at(self.v.len() - self.cols);
85            if fst.is_empty() {
86                self.v = &[];
87            } else {
88                // skip_cols will be <= fst.len(), so no check required
89                unsafe {
90                    self.v = fst.get_unchecked(..fst.len() - self.skip_cols);
91                }
92            }
93            Some(snd)
94        }
95    }
96
97    #[inline]
98    fn nth_back(&mut self, n: usize) -> Option<Self::Item> {
99        let (adj, overflow) = n.overflowing_mul(self.cols + self.skip_cols);
100        if adj >= self.v.len() || overflow {
101            self.v = &[];
102        } else {
103            // adj < fst.len(), so no check required
104            unsafe {
105                self.v = self.v.get_unchecked(..self.v.len() - adj);
106            }
107        }
108        self.next_back()
109    }
110}
111
112impl<T> ExactSizeIterator for Rows<'_, T> {}
113
114impl<T> TooDeeIterator for Rows<'_, T> {
115    fn num_cols(&self) -> usize {
116        self.cols
117    }
118}
119
120/// A mutable Iterator over each row of a `TooDee[ViewMut]`, where each row is represented as a slice.
121#[derive(Debug)]
122pub struct RowsMut<'a, T> {
123    /// This reference contains row data at each end. When iterating in either direction the row will
124    /// be pulled off the end then `skip_cols` elements will be skipped in preparation for reading the
125    /// next row.
126    pub(super) v: &'a mut [T],
127    pub(super) cols: usize,
128    pub(super) skip_cols: usize,
129}
130
131impl<'a, T> Iterator for RowsMut<'a, T> {
132
133    type Item = &'a mut [T];
134
135    #[inline]
136    fn next(&mut self) -> Option<Self::Item> {
137        if self.v.is_empty() {
138            None
139        } else {
140            let tmp = mem::take(&mut self.v);
141            let (head, tail) = tmp.split_at_mut(self.cols);
142            if tail.is_empty() {
143                self.v = &mut [];
144            } else {
145                // tail must contain at least one row, so no check required
146                unsafe {
147                    self.v = tail.get_unchecked_mut(self.skip_cols..);
148                }
149            }
150            Some(head)
151        }
152    }
153
154    #[inline]
155    fn size_hint(&self) -> (usize, Option<usize>) {
156        if self.cols == 0 {
157            return (0, Some(0));
158        }
159        let len = self.v.len();
160        let denom = self.cols + self.skip_cols;
161        let n = len / denom + (len % denom) / self.cols;
162        (n, Some(n))
163    }
164
165    #[inline]
166    fn count(self) -> usize {
167        self.len()
168    }
169    
170    #[inline]
171    fn nth(&mut self, n: usize) -> Option<Self::Item> {
172        let (start, overflow) = n.overflowing_mul(self.cols + self.skip_cols);
173        if start >= self.v.len() || overflow {
174            self.v = &mut [];
175        } else {
176            let tmp = mem::take(&mut self.v);
177            let (_, snd) = tmp.split_at_mut(start);
178            self.v = snd;
179        }
180        self.next()
181    }
182    
183    #[inline]
184    fn last(mut self) -> Option<Self::Item> {
185        self.next_back()
186    }    
187}
188
189impl<'a, T> DoubleEndedIterator for RowsMut<'a, T> {
190    #[inline]
191    fn next_back(&mut self) -> Option<Self::Item> {
192        if self.v.is_empty() {
193            None
194        } else {
195            let tmp = mem::take(&mut self.v);
196            let tmp_len = tmp.len();
197            let (fst, snd) = tmp.split_at_mut(tmp_len - self.cols);
198            if fst.is_empty() {
199                self.v = &mut [];
200            } else {
201                // fst must contain at least one row, so no check required
202                unsafe {
203                    self.v = fst.get_unchecked_mut(..tmp_len - self.cols - self.skip_cols);
204                }
205            }
206            Some(snd)
207        }
208    }
209
210    #[inline]
211    fn nth_back(&mut self, n: usize) -> Option<Self::Item> {
212
213        let (adj, overflow) = n.overflowing_mul(self.cols + self.skip_cols);
214        if adj >= self.v.len() || overflow {
215            self.v = &mut [];
216        } else {
217            let tmp = mem::take(&mut self.v);
218            // adj < self.v.len(), so no check required
219            unsafe {
220                self.v = tmp.get_unchecked_mut(..self.v.len() - adj);
221            }
222        }
223        self.next_back()
224    }
225}
226
227impl<T> ExactSizeIterator for RowsMut<'_, T> {}
228
229impl<T> TooDeeIterator for RowsMut<'_, T> {
230    fn num_cols(&self) -> usize {
231        self.cols
232    }
233}
234
235/// An iterator over a single column.
236#[derive(Debug)]
237pub struct Col<'a, T> {
238    pub(super) v: &'a [T],
239    pub(super) skip: usize,
240}
241
242impl<'a, T> Index<usize> for Col<'a, T> {
243    type Output = T;
244    /// # Examples
245    /// 
246    /// ```
247    /// use toodee::{TooDee,TooDeeOps,TooDeeOpsMut};
248    /// let toodee : TooDee<u32> = TooDee::new(10, 5);
249    /// let col = toodee.col(2);
250    /// assert_eq!(col[3], 0);
251    /// ```
252    fn index(&self, idx: usize) -> &Self::Output {
253        let pos = idx * (1 + self.skip);
254        &self.v[pos]
255    }
256}
257
258impl<'a, T> Iterator for Col<'a, T> {
259
260    type Item = &'a T;
261
262    #[inline]
263    fn next(&mut self) -> Option<Self::Item> {
264        if let Some((fst, snd)) = self.v.split_first() {
265            if snd.is_empty() {
266                self.v = &[];
267            } else {
268                // snd must contain at least one row, so we don't need a bounds check
269                unsafe {
270                    self.v = snd.get_unchecked(self.skip..);
271                }
272            }
273            Some(fst)
274        } else {
275            None
276        }
277    }
278
279    #[inline]
280    fn size_hint(&self) -> (usize, Option<usize>) {
281        let len = self.v.len();
282        let denom = 1 + self.skip;
283        let n = len / denom + (len % denom);
284        (n, Some(n))
285    }
286
287    #[inline]
288    fn count(self) -> usize {
289        self.len()
290    }
291    
292    #[inline]
293    fn nth(&mut self, n: usize) -> Option<Self::Item> {
294        
295        let (start, overflow) = n.overflowing_mul(1 + self.skip);
296        if start >= self.v.len() || overflow {
297            self.v = &[];
298        } else {
299            let (_, snd) = self.v.split_at(start);
300            self.v = snd;
301        }
302        self.next()
303    }
304
305    #[inline]
306    fn last(mut self) -> Option<Self::Item> {
307        self.next_back()
308    }
309}
310
311impl<'a, T> DoubleEndedIterator for Col<'a, T> {
312    #[inline]
313    fn next_back(&mut self) -> Option<Self::Item> {
314        if let Some((last, fst)) = self.v.split_last() {
315            if fst.is_empty() {
316                self.v = &[];
317            } else {
318                // fst must contain at least one row, so we don't need a bounds check
319                unsafe {
320                    self.v = fst.get_unchecked(..fst.len() - self.skip);
321                }
322            }
323            Some(last)
324        } else {
325            None
326        }
327    }
328
329    #[inline]
330    fn nth_back(&mut self, n: usize) -> Option<Self::Item> {
331        let (adj, overflow) = n.overflowing_mul(1 + self.skip);
332        if adj >= self.v.len() || overflow {
333            self.v = &[];
334        } else {
335            // adj < self.v.len(), so no check required
336            unsafe {
337                self.v = self.v.get_unchecked(..self.v.len() - adj);
338            }
339        }
340        self.next_back()
341    }
342}
343
344impl<T> ExactSizeIterator for Col<'_, T> {}
345
346
347/// A mutable iterator over a single column.
348#[derive(Debug)]
349pub struct ColMut<'a, T> {
350    pub(super) v: &'a mut [T],
351    pub(super) skip: usize,
352}
353
354impl<'a, T> Index<usize> for ColMut<'a, T> {
355    type Output = T;
356    /// # Examples
357    /// 
358    /// ```
359    /// use toodee::{TooDee,TooDeeOps,TooDeeOpsMut};
360    /// let mut toodee : TooDee<u32> = TooDee::new(10, 5);
361    /// let col = toodee.col_mut(2);
362    /// assert_eq!(col[3], 0);
363    /// ```
364    fn index(&self, idx: usize) -> &Self::Output {
365        let pos = idx * (1 + self.skip);
366        &self.v[pos]
367    }
368}
369
370impl<'a, T> IndexMut<usize> for ColMut<'a, T> {
371
372    /// # Examples
373    /// 
374    /// ```
375    /// use toodee::{TooDee,TooDeeOps,TooDeeOpsMut};
376    /// let mut toodee : TooDee<u32> = TooDee::new(10, 5);
377    /// let mut col = toodee.col_mut(2);
378    /// col[3] = 42;
379    /// ```
380    fn index_mut(&mut self, idx: usize) -> &mut Self::Output {
381        let pos = idx * (1 + self.skip);
382        &mut self.v[pos]
383    }
384}
385
386impl<'a, T> Iterator for ColMut<'a, T> {
387
388    type Item = &'a mut T;
389
390    #[inline]
391    fn next(&mut self) -> Option<Self::Item> {
392        let tmp = mem::take(&mut self.v);
393        if let Some((fst, snd)) = tmp.split_first_mut() {
394            if snd.is_empty() {
395                self.v = &mut [];
396            } else {
397                // snd must contain at least one row, so no check required
398                unsafe {
399                    self.v = snd.get_unchecked_mut(self.skip..);
400                }
401            }
402            Some(fst)
403        } else {
404            None
405        }
406    }
407
408    #[inline]
409    fn size_hint(&self) -> (usize, Option<usize>) {
410        let len = self.v.len();
411        let denom = 1 + self.skip;
412        let n = len / denom + (len % denom);
413        (n, Some(n))
414    }
415
416    #[inline]
417    fn count(self) -> usize {
418        self.len()
419    }
420    
421    #[inline]
422    fn nth(&mut self, n: usize) -> Option<Self::Item> {
423        let (start, overflow) = n.overflowing_mul(1 + self.skip);
424        if start >= self.v.len() || overflow {
425            self.v = &mut [];
426        } else {
427            let tmp = mem::take(&mut self.v);
428            let (_, snd) = tmp.split_at_mut(start);
429            self.v = snd;
430        }
431        self.next()
432    }
433    
434    #[inline]
435    fn last(mut self) -> Option<Self::Item> {
436        self.next_back()
437    }    
438}
439
440impl<'a, T> DoubleEndedIterator for ColMut<'a, T> {
441    #[inline]
442    fn next_back(&mut self) -> Option<Self::Item> {
443        let tmp = mem::take(&mut self.v);
444        if let Some((last, fst)) = tmp.split_last_mut() {
445            if fst.is_empty() {
446                self.v = &mut [];
447            } else {
448                let new_len = fst.len() - self.skip;
449                // skip <= fst.len(), so no check required
450                unsafe {
451                    self.v = fst.get_unchecked_mut(..new_len);
452                }
453            }
454            Some(last)
455        } else {
456            None
457        }
458    }
459
460    #[inline]
461    fn nth_back(&mut self, n: usize) -> Option<Self::Item> {
462
463        let (adj, overflow) = n.overflowing_mul(1 + self.skip);
464        if adj >= self.v.len() || overflow {
465            self.v = &mut [];
466        } else {
467            let tmp = mem::take(&mut self.v);
468            // adj <= self.v.len(), so no check required
469            unsafe {
470                self.v = tmp.get_unchecked_mut(..self.v.len() - adj);
471            }
472        }
473        self.next_back()
474    }
475}
476
477impl<T> ExactSizeIterator for ColMut<'_, T> {}
478