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`.
5 macro_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`.
23 macro_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 
40 macro_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     }) => {
59 impl<$($typarm)*> NdProducer for $fulltype {
60     $(
61         type $atyn = $atyv;
62     )*
63     type Ptr = *mut A;
64     type Stride = isize;
65 
66     #[doc(hidden)]
67     fn raw_dim(&self) -> D {
68         self.$base.raw_dim()
69     }
70 
71     #[doc(hidden)]
72     fn layout(&self) -> Layout {
73         self.$base.layout()
74     }
75 
76     #[doc(hidden)]
77     fn as_ptr(&self) -> *mut A {
78         self.$base.as_ptr() as *mut _
79     }
80 
81     #[doc(hidden)]
82     fn contiguous_stride(&self) -> isize {
83         self.$base.contiguous_stride()
84     }
85 
86     #[doc(hidden)]
87     unsafe fn as_ref(&$self_, $ptr: *mut A) -> Self::Item {
88         $refexpr
89     }
90 
91     #[doc(hidden)]
92     unsafe fn uget_ptr(&self, i: &Self::Dim) -> *mut A {
93         self.$base.uget_ptr(i)
94     }
95 
96     #[doc(hidden)]
97     fn stride_of(&self, axis: Axis) -> isize {
98         self.$base.stride_of(axis)
99     }
100 
101     #[doc(hidden)]
102     fn split_at(self, axis: Axis, index: usize) -> (Self, Self) {
103         let (a, b) = self.$base.split_at(axis, index);
104         ($typename {
105             $base: a,
106             $(
107             $fieldname: self.$fieldname.clone(),
108             )*
109         },
110         $typename {
111             $base: b,
112             $(
113             $fieldname: self.$fieldname,
114             )*
115         })
116     }
117     private_impl!{}
118 }
119 
120 expand_if!(@nonempty [$($cloneparm)*]
121     impl<$($cloneparm)*> Clone for $fulltype {
122         fn clone(&self) -> Self {
123             $typename {
124                 $base: self.base.clone(),
125                 $(
126                 $fieldname: self.$fieldname.clone(),
127                 )*
128             }
129         }
130     }
131 );
132 
133     }
134 }
135 
136 macro_rules! impl_iterator {
137     (
138     [$($typarm:tt)*]
139     [Clone => $($cloneparm:tt)*]
140      $typename:ident {
141          $base:ident,
142          $(
143              $fieldname:ident,
144          )*
145      }
146      $fulltype:ty {
147         type Item = $ity:ty;
148 
149         fn item(&mut $self_:ident, $elt:pat) {
150             $refexpr:expr
151         }
152     }) => {
153          expand_if!(@nonempty [$($cloneparm)*]
154 
155             impl<$($cloneparm)*> Clone for $fulltype {
156                 fn clone(&self) -> Self {
157                     $typename {
158                         $base: self.$base.clone(),
159                         $(
160                             $fieldname: self.$fieldname.clone(),
161                         )*
162                     }
163                 }
164             }
165 
166          );
167         impl<$($typarm)*> Iterator for $fulltype {
168             type Item = $ity;
169 
170             fn next(&mut $self_) -> Option<Self::Item> {
171                 $self_.$base.next().map(|$elt| {
172                     $refexpr
173                 })
174             }
175 
176             fn size_hint(&self) -> (usize, Option<usize>) {
177                 self.$base.size_hint()
178             }
179         }
180     }
181 }
182