ndarray/iterators/
macros.rs

1// Send and Sync
2// All the iterators are thread safe the same way the slice's iterator are
3
4// read-only iterators use Sync => Send rules, same as `std::slice::Iter`.
5macro_rules! send_sync_read_only {
6    ($name:ident) => {
7        unsafe impl<'a, A, D> Send for $name<'a, A, D>
8        where
9            A: Sync,
10            D: Send,
11        {
12        }
13        unsafe impl<'a, A, D> Sync for $name<'a, A, D>
14        where
15            A: Sync,
16            D: Sync,
17        {
18        }
19    };
20}
21
22// read-write iterators use Send => Send rules, same as `std::slice::IterMut`.
23macro_rules! send_sync_read_write {
24    ($name:ident) => {
25        unsafe impl<'a, A, D> Send for $name<'a, A, D>
26        where
27            A: Send,
28            D: Send,
29        {
30        }
31        unsafe impl<'a, A, D> Sync for $name<'a, A, D>
32        where
33            A: Sync,
34            D: Sync,
35        {
36        }
37    };
38}
39
40macro_rules! impl_ndproducer {
41    (
42    [$($typarm:tt)*]
43    [Clone => $($cloneparm:tt)*]
44     $typename:ident {
45         $base:ident,
46         $(
47             $fieldname:ident,
48         )*
49     }
50     $fulltype:ty {
51        $(
52            type $atyn:ident = $atyv:ty;
53        )*
54
55        unsafe fn item(&$self_:ident, $ptr:pat) {
56            $refexpr:expr
57        }
58    }) => {
59impl<$($typarm)*> NdProducer for $fulltype {
60    $(
61        type $atyn = $atyv;
62    )*
63    type Ptr = *mut A;
64    type Stride = isize;
65
66    fn raw_dim(&self) -> D {
67        self.$base.raw_dim()
68    }
69
70    fn layout(&self) -> Layout {
71        self.$base.layout()
72    }
73
74    fn as_ptr(&self) -> *mut A {
75        self.$base.as_ptr() as *mut _
76    }
77
78    fn contiguous_stride(&self) -> isize {
79        self.$base.contiguous_stride()
80    }
81
82    unsafe fn as_ref(&$self_, $ptr: *mut A) -> Self::Item {
83        $refexpr
84    }
85
86    unsafe fn uget_ptr(&self, i: &Self::Dim) -> *mut A {
87        self.$base.uget_ptr(i)
88    }
89
90    fn stride_of(&self, axis: Axis) -> isize {
91        self.$base.stride_of(axis)
92    }
93
94    fn split_at(self, axis: Axis, index: usize) -> (Self, Self) {
95        let (a, b) = self.$base.split_at(axis, index);
96        ($typename {
97            $base: a,
98            $(
99            $fieldname: self.$fieldname.clone(),
100            )*
101        },
102        $typename {
103            $base: b,
104            $(
105            $fieldname: self.$fieldname,
106            )*
107        })
108    }
109
110    private_impl!{}
111}
112
113expand_if!(@nonempty [$($cloneparm)*]
114    impl<$($cloneparm)*> Clone for $fulltype {
115        fn clone(&self) -> Self {
116            $typename {
117                $base: self.base.clone(),
118                $(
119                $fieldname: self.$fieldname.clone(),
120                )*
121            }
122        }
123    }
124);
125
126    }
127}
128
129macro_rules! impl_iterator {
130    (
131    [$($typarm:tt)*]
132    [Clone => $($cloneparm:tt)*]
133     $typename:ident {
134         $base:ident,
135         $(
136             $fieldname:ident,
137         )*
138     }
139     $fulltype:ty {
140        type Item = $ity:ty;
141
142        fn item(&mut $self_:ident, $elt:pat) {
143            $refexpr:expr
144        }
145    }) => {
146         expand_if!(@nonempty [$($cloneparm)*]
147
148            impl<$($cloneparm)*> Clone for $fulltype {
149                fn clone(&self) -> Self {
150                    $typename {
151                        $base: self.$base.clone(),
152                        $(
153                            $fieldname: self.$fieldname.clone(),
154                        )*
155                    }
156                }
157            }
158
159         );
160        impl<$($typarm)*> Iterator for $fulltype {
161            type Item = $ity;
162
163            fn next(&mut $self_) -> Option<Self::Item> {
164                $self_.$base.next().map(|$elt| {
165                    $refexpr
166                })
167            }
168
169            fn size_hint(&self) -> (usize, Option<usize>) {
170                self.$base.size_hint()
171            }
172        }
173    }
174}