mop_structs/matrix/dr_matrix/
dr_matrix_row_iter_impls.rs

1use crate::dim::Dim;
2use core::{
3  marker::PhantomData,
4  slice::{from_raw_parts, from_raw_parts_mut},
5};
6
7macro_rules! impl_iter (
8    ($dr_matrix_iter:ident, $data_ptr:ty, $data_type:ty, $from_raw_parts:ident) => (
9#[derive(Debug)]
10pub struct $dr_matrix_iter<'a, T> {
11    curr_row: usize,
12    data: $data_ptr,
13    dim: Dim<[usize; 2]>,
14    phantom: PhantomData<&'a T>,
15}
16
17impl<'a, T> $dr_matrix_iter<'a, T> {
18    pub(crate) fn new(
19        dim: [usize; 2],
20        data: $data_ptr,
21    ) -> Self {
22        $dr_matrix_iter {
23            curr_row: 0,
24            data,
25            dim: dim.into(),
26            phantom: PhantomData,
27        }
28    }
29
30    pub fn split_at(self, idx: usize) -> (Self, Self) {
31        let current_len = self.dim.rows() - self.curr_row;
32        assert!(idx <= current_len);
33        let slice_point = self.curr_row + idx;
34        (
35            $dr_matrix_iter {
36                curr_row: self.curr_row,
37                data: self.data,
38                dim: [slice_point, self.dim.cols()].into(),
39                phantom: PhantomData,
40            },
41            $dr_matrix_iter {
42                curr_row: slice_point,
43                data: self.data,
44                dim: self.dim,
45                phantom: PhantomData,
46            }
47        )
48    }
49}
50
51impl<'a, T> DoubleEndedIterator for $dr_matrix_iter<'a, T> {
52    fn next_back(&mut self) -> Option<Self::Item> {
53        if self.curr_row >= self.dim.rows() {
54            return None;
55        }
56        let data: $data_type = unsafe {
57            let offset = ((self.dim.rows() - 1) * self.dim.cols()) as isize;
58            let ptr = self.data.offset(offset);
59            $from_raw_parts(ptr, self.dim.cols())
60        };
61        *self.dim.rows_mut() -= 1;
62        Some(data)
63    }
64}
65
66impl<'a, T> ExactSizeIterator for $dr_matrix_iter<'a, T> {
67}
68
69
70impl<'a, T> Iterator for $dr_matrix_iter<'a, T> {
71    type Item = $data_type;
72
73    fn next(&mut self) -> Option<Self::Item> {
74        if self.curr_row >= self.dim.rows() {
75            return None;
76        }
77        let data: $data_type = unsafe {
78            let offset = (self.curr_row * self.dim.cols()) as isize;
79            let ptr = self.data.offset(offset);
80            $from_raw_parts(ptr, self.dim.cols())
81        };
82        self.curr_row += 1;
83        Some(data)
84    }
85
86    fn size_hint(&self) -> (usize, Option<usize>) {
87        (self.dim.rows(), Some(self.dim.rows()))
88    }
89}
90
91unsafe impl<'a, T> Send for $dr_matrix_iter<'a, T> {}
92unsafe impl<'a, T> Sync for $dr_matrix_iter<'a, T> {}
93
94    );
95);
96
97impl_iter!(DrMatrixRowIter, *const T, &'a [T], from_raw_parts);
98impl_iter!(DrMatrixRowIterMut, *mut T, &'a mut [T], from_raw_parts_mut);