nncombinator/
macros.rs

1/// Macros for automatic derivation of the implementation of the four arithmetic operations
2///
3/// # Arguments
4/// * `$lt` - the left hand side type
5/// * `$rt` - the right hand side type
6/// * `$clt` - Converted type of the left-hand side type
7/// * `$crt` - Converted type of the right-hand side type
8/// * `$ot` - output type
9#[macro_export]
10macro_rules! derive_arithmetic {
11    ( Broadcast<T> > $rt:ty = $ot:ty) => {
12        impl<'a,U,T> Add<$rt> for Broadcast<T>
13            where U: Send + Sync + Default + Clone + Copy + 'static + Add<Output=U>,
14                  for<'data> T: SliceSize + MakeView<'data,U> + Clone + Send + Sync,
15                  for<'data> &'data T: Add<<T as AsView<'data>>::ViewType,Output=T> + Send + Sync,
16                  $ot: From<Vec<T>> {
17            type Output = $ot;
18
19            #[inline]
20            fn add(self, rhs: $rt) -> Self::Output {
21                rhs.iter().map(|r| {
22                    &self.0 + r
23                }).collect::<Vec<T>>().into()
24            }
25        }
26
27        impl<'a,U,T> Sub<$rt> for Broadcast<T>
28            where U: Send + Sync + Default + Clone + Copy + 'static + Sub<Output=U>,
29                  for<'data> T: SliceSize + MakeView<'data,U> + Clone + Send + Sync,
30                  for<'data> &'data T: Sub<<T as AsView<'data>>::ViewType,Output=T> + Send + Sync,
31                  $ot: From<Vec<T>> {
32            type Output = $ot;
33
34            #[inline]
35            fn sub(self, rhs: $rt) -> Self::Output {
36                rhs.iter().map(|r| {
37                    &self.0 - r
38                }).collect::<Vec<T>>().into()
39            }
40        }
41
42        impl<'a,U,T> Mul<$rt> for Broadcast<T>
43            where U: Send + Sync + Default + Clone + Copy + 'static + Mul<Output=U>,
44                  for<'data> T: SliceSize + MakeView<'data,U> + Clone + Send + Sync,
45                  for<'data> &'data T: Mul<<T as AsView<'data>>::ViewType,Output=T> + Send + Sync,
46                  $ot: From<Vec<T>> {
47            type Output = $ot;
48
49            #[inline]
50            fn mul(self, rhs: $rt) -> Self::Output {
51                rhs.iter().map(|r| {
52                    &self.0 * r
53                }).collect::<Vec<T>>().into()
54            }
55        }
56
57        impl<'a,U,T> Div<$rt> for Broadcast<T>
58            where U: Send + Sync + Default + Clone + Copy + 'static + Div<Output=U>,
59                  for<'data> T: SliceSize + MakeView<'data,U> + Clone + Send + Sync,
60                  for<'data> &'data T: Div<<T as AsView<'data>>::ViewType,Output=T> + Send + Sync,
61                  $ot: From<Vec<T>> {
62            type Output = $ot;
63
64            #[inline]
65            fn div(self, rhs: $rt) -> Self::Output {
66                rhs.iter().map(|r| {
67                    &self.0 / r
68                }).collect::<Vec<T>>().into()
69            }
70        }
71    };
72    ( $lt:ty > Broadcast<T> = $ot:ty) => {
73        impl<'a,U,T> Add<Broadcast<T>> for $lt
74            where U: Send + Sync + Default + Clone + Copy + 'static + Add<Output=U>,
75                  for<'data> T: SliceSize + MakeView<'data,U> + Clone + Send + Sync,
76                  for<'data> <T as AsView<'data>>::ViewType: Send + Add<&'data T,Output=T> + Add<T,Output=T>,
77                  $ot: From<Vec<T>> {
78            type Output = $ot;
79        
80            #[inline]
81            fn add(self, rhs: Broadcast<T>) -> Self::Output {
82                self.iter().map(|l| {
83                    l + &rhs.0
84                }).collect::<Vec<T>>().into()
85            }
86        }
87
88        impl<'a,U,T> Sub<Broadcast<T>> for $lt
89            where U: Send + Sync + Default + Clone + Copy + 'static + Sub<Output=U>,
90                  for<'data> T: SliceSize + MakeView<'data,U> + Clone + Send + Sync,
91                  for<'data> <T as AsView<'data>>::ViewType: Send + Sub<&'data T,Output=T> + Add<T,Output=T>,
92                  $ot: From<Vec<T>> {
93            type Output = $ot;
94
95            #[inline]
96            fn sub(self, rhs: Broadcast<T>) -> Self::Output {
97                self.iter().map(|l| {
98                    l - &rhs.0
99                }).collect::<Vec<T>>().into()
100            }
101        }
102
103        impl<'a,U,T> Mul<Broadcast<T>> for $lt
104            where U: Send + Sync + Default + Clone + Copy + 'static + Mul<Output=U>,
105                  for<'data> T: SliceSize + MakeView<'data,U> + Clone + Send + Sync,
106                  for<'data> <T as AsView<'data>>::ViewType: Send + Mul<&'data T,Output=T> + Add<T,Output=T>,
107                  $ot: From<Vec<T>> {
108            type Output = $ot;
109
110            #[inline]
111            fn mul(self, rhs: Broadcast<T>) -> Self::Output {
112                self.iter().map(|l| {
113                    l * &rhs.0
114                }).collect::<Vec<T>>().into()
115            }
116        }
117
118        impl<'a,U,T> Div<Broadcast<T>> for $lt
119            where U: Send + Sync + Default + Clone + Copy + 'static + Div<Output=U>,
120                  for<'data> T: SliceSize + MakeView<'data,U> + Clone + Send + Sync,
121                  for<'data> <T as AsView<'data>>::ViewType: Send + Div<&'data T,Output=T> + Add<T,Output=T>,
122                  $ot: From<Vec<T>> {
123            type Output = $ot;
124
125            #[inline]
126            fn div(self, rhs: Broadcast<T>) -> Self::Output {
127                self.iter().map(|l| {
128                    l / &rhs.0
129                }).collect::<Vec<T>>().into()
130            }
131        }
132    };
133    ( $lt:ty > $rt:ty = $ot:ty) => {
134        impl<'a,U,T> Add<$rt> for $lt
135            where U: Send + Sync + Default + Clone + Copy + 'static + Add<Output=U>,
136                  for<'b> T: SliceSize + MakeView<'b,U> + Send + Sync,
137                  for<'b> <T as AsView<'b>>::ViewType: Send + Add<Output=T>,
138                  $ot: From<Vec<T>> {
139            type Output = $ot;
140
141            #[inline]
142            fn add(self, rhs: $rt) -> Self::Output {
143                self.iter().zip(rhs.iter()).map(|(l,r)| l + r).collect::<Vec<T>>().into()
144            }
145        }
146
147        impl<'a,U,T> Sub<$rt> for $lt
148            where U: Send + Sync + Default + Clone + Copy + 'static + Sub<Output=U>,
149                  for<'b> T: SliceSize + MakeView<'b,U> + Send + Sync,
150                  for<'b> <T as AsView<'b>>::ViewType: Send + Sub<Output=T>,
151                  $ot: From<Vec<T>> {
152            type Output = $ot;
153
154            #[inline]
155            fn sub(self, rhs: $rt) -> Self::Output {
156                self.iter().zip(rhs.iter()).map(|(l,r)| l - r).collect::<Vec<T>>().into()
157            }
158        }
159
160        impl<'a,U,T> Mul<$rt> for $lt
161            where U: Send + Sync + Default + Clone + Copy + 'static + Mul<Output=U>,
162                  for<'b> T: SliceSize + MakeView<'b,U> + Send + Sync,
163                  for<'b> <T as AsView<'b>>::ViewType: Send + Mul<Output=T>,
164                  $ot: From<Vec<T>> {
165            type Output = $ot;
166
167            #[inline]
168            fn mul(self, rhs: $rt) -> Self::Output {
169                self.iter().zip(rhs.iter()).map(|(l,r)| l * r).collect::<Vec<T>>().into()
170            }
171        }
172
173        impl<'a,U,T> Div<$rt> for $lt
174            where U: Send + Sync + Default + Clone + Copy + 'static + Div<Output=U>,
175                  for<'b> T: SliceSize + MakeView<'b,U> + Send + Sync,
176                  for<'b> <T as AsView<'b>>::ViewType: Send + Div<Output=T>,
177                  $ot: From<Vec<T>> {
178            type Output = $ot;
179
180            #[inline]
181            fn div(self, rhs: $rt) -> Self::Output {
182                self.iter().zip(rhs.iter()).map(|(l,r)| l / r).collect::<Vec<T>>().into()
183            }
184        }
185    };
186    ( $lt:ty > $rt:ty = r $clt:ty > r $crt:ty = $ot:ty) => {
187        impl<'a,U,T> Add<$rt> for $lt
188            where for<'b> &'b $clt: Add<&'b $crt,Output=$ot>,
189            for<'b> &'b $clt: From<&'b $lt>,
190            for<'b> &'b $crt: From<&'b $rt>,
191            T: Clone {
192            type Output = $ot;
193
194            #[inline]
195            fn add(self, rhs: $rt) -> Self::Output {
196                <&$clt>::from(&self) + <&$crt>::from(&rhs)
197            }
198        }
199
200        impl<'a,U,T> Sub<$rt> for $lt
201            where for<'b> &'b $clt: Sub<&'b $crt,Output=$ot>,
202            for<'b> &'b $clt: From<&'b $lt>,
203            for<'b> &'b $crt: From<&'b $rt>,
204            T: Clone {
205            type Output = $ot;
206
207            #[inline]
208            fn sub(self, rhs: $rt) -> Self::Output {
209                <&$clt>::from(&self) - <&$crt>::from(&rhs)
210            }
211        }
212
213        impl<'a,U,T> Mul<$rt> for $lt
214            where for<'b> &'b $clt: Mul<&'b $crt,Output=$ot>,
215            for<'b> &'b $clt: From<&'b $lt>,
216            for<'b> &'b $crt: From<&'b $rt>,
217            T: Clone {
218            type Output = $ot;
219
220            #[inline]
221            fn mul(self, rhs: $rt) -> Self::Output {
222                <&$clt>::from(&self) * <&$crt>::from(&rhs)
223            }
224        }
225
226        impl<'a,U,T> Div<$rt> for $lt
227            where for<'b> &'b $clt: Div<&'b $crt,Output=$ot>,
228            for<'b> &'b $clt: From<&'b $lt>,
229            for<'b> &'b $crt: From<&'b $rt>,
230            T: Clone {
231            type Output = $ot;
232
233            #[inline]
234            fn div(self, rhs: $rt) -> Self::Output {
235                <&$clt>::from(&self) / <&$crt>::from(&rhs)
236            }
237        }
238    };
239}
240/// Macro for automatic derivation of the implementation of the four arithmetic operations of Arr,ArrView.ss
241///
242/// # Arguments
243/// * `$lt` - the left hand side type
244/// * `$rt` - the right hand side type
245/// * `$clt` - Converted type of the left-hand side type
246/// * `$crt` - Converted type of the right-hand side type
247/// * `$ot` - output type
248#[macro_export]
249macro_rules! derive_arr_like_arithmetic {
250    ($lt:ty > $rt:ty = $ot:ty) => {
251        impl<'a,T,const N:usize> Add<$rt> for $lt
252            where T: Add<Output=T> + Clone + Copy + Default + Send + Sync + 'static {
253            type Output = $ot;
254
255            #[inline]
256            fn add(self, rhs: $rt) -> Self::Output {
257                self.iter().zip(rhs.iter()).map(|(&l,&r)| l + r)
258                    .collect::<Vec<T>>().try_into().expect("An error occurred in the add of Arr and Arr.")
259            }
260        }
261
262        impl<'a,T,const N:usize> Sub<$rt> for $lt
263            where T: Sub<Output=T> + Clone + Copy + Default + Send + Sync + 'static {
264            type Output = $ot;
265
266            #[inline]
267            fn sub(self, rhs: $rt) -> Self::Output {
268                self.iter().zip(rhs.iter()).map(|(&l,&r)| l - r)
269                    .collect::<Vec<T>>().try_into().expect("An error occurred in the sub of Arr and Arr.")
270            }
271        }
272
273        impl<'a,T,const N:usize> Mul<$rt> for $lt
274            where T: Mul<Output=T> + Clone + Copy + Default + Send + Sync + 'static {
275            type Output = $ot;
276
277            #[inline]
278            fn mul(self, rhs: $rt) -> Self::Output {
279                self.iter().zip(rhs.iter()).map(|(&l,&r)| l * r)
280                    .collect::<Vec<T>>().try_into().expect("An error occurred in the mul of Arr and Arr.")
281            }
282        }
283
284        impl<'a,T,const N:usize> Div<$rt> for $lt
285            where T: Div<Output=T> + Clone + Copy + Default + Send + Sync + 'static {
286            type Output = $ot;
287
288            #[inline]
289            fn div(self, rhs: $rt) -> Self::Output {
290                self.iter().zip(rhs.iter()).map(|(&l,&r)| l / r)
291                    .collect::<Vec<T>>().try_into().expect("An error occurred in the sub of Arr and Arr.")
292            }
293        }
294    };
295    ( $lt:ty > $rt:ty = r $clt:ty > r $crt:ty = $ot:ty) => {
296        impl<'a,T,const N:usize> Add<$rt> for $lt
297            where for<'b> &'b $clt: Add<&'b $crt,Output=$ot>,
298            for<'b> &'b $clt: From<&'b $lt>,
299            for<'b> &'b $crt: From<&'b $rt>,
300            T: Default + Clone + Send {
301            type Output = $ot;
302
303            #[inline]
304            fn add(self, rhs: $rt) -> Self::Output {
305                <&$clt>::from(&self) + <&$crt>::from(&rhs)
306            }
307        }
308
309        impl<'a,T,const N:usize> Sub<$rt> for $lt
310            where for<'b> &'b $clt: Sub<&'b $crt,Output=$ot>,
311            for<'b> &'b $clt: From<&'b $lt>,
312            for<'b> &'b $crt: From<&'b $rt>,
313            T: Default + Clone + Send {
314            type Output = $ot;
315
316            #[inline]
317            fn sub(self, rhs: $rt) -> Self::Output {
318                <&$clt>::from(&self) - <&$crt>::from(&rhs)
319            }
320        }
321
322        impl<'a,T,const N:usize> Mul<$rt> for $lt
323            where for<'b> &'b $clt: Mul<&'b $crt,Output=$ot>,
324            for<'b> &'b $clt: From<&'b $lt>,
325            for<'b> &'b $crt: From<&'b $rt>,
326            T: Default + Clone + Send {
327            type Output = $ot;
328
329            #[inline]
330            fn mul(self, rhs: $rt) -> Self::Output {
331                <&$clt>::from(&self) * <&$crt>::from(&rhs)
332            }
333        }
334
335        impl<'a,T,const N:usize> Div<$rt> for $lt
336            where for<'b> &'b $clt: Div<&'b $crt,Output=$ot>,
337            for<'b> &'b $clt: From<&'b $lt>,
338            for<'b> &'b $crt: From<&'b $rt>,
339            T: Default + Clone + Send {
340            type Output = $ot;
341
342            #[inline]
343            fn div(self, rhs: $rt) -> Self::Output {
344                <&$clt>::from(&self) / <&$crt>::from(&rhs)
345            }
346        }
347    }
348}