num_bigint/
macros.rs

1#![allow(unused_macros)]
2
3macro_rules! cfg_32 {
4    ($($any:tt)+) => {
5        #[cfg(not(target_pointer_width = "64"))] $($any)+
6    }
7}
8
9macro_rules! cfg_32_or_test {
10    ($($any:tt)+) => {
11        #[cfg(any(not(target_pointer_width = "64"), test))] $($any)+
12    }
13}
14
15macro_rules! cfg_64 {
16    ($($any:tt)+) => {
17        #[cfg(target_pointer_width = "64")] $($any)+
18    }
19}
20
21macro_rules! cfg_digit {
22    ($item32:item $item64:item) => {
23        cfg_32!($item32);
24        cfg_64!($item64);
25    };
26}
27
28macro_rules! cfg_digit_expr {
29    ($expr32:expr, $expr64:expr) => {
30        cfg_32!($expr32);
31        cfg_64!($expr64);
32    };
33}
34
35macro_rules! forward_val_val_binop {
36    (impl $imp:ident for $res:ty, $method:ident) => {
37        impl $imp<$res> for $res {
38            type Output = $res;
39
40            #[inline]
41            fn $method(self, other: $res) -> $res {
42                // forward to val-ref
43                $imp::$method(self, &other)
44            }
45        }
46    };
47}
48
49macro_rules! forward_val_val_binop_commutative {
50    (impl $imp:ident for $res:ty, $method:ident) => {
51        impl $imp<$res> for $res {
52            type Output = $res;
53
54            #[inline]
55            fn $method(self, other: $res) -> $res {
56                // forward to val-ref, with the larger capacity as val
57                if self.capacity() >= other.capacity() {
58                    $imp::$method(self, &other)
59                } else {
60                    $imp::$method(other, &self)
61                }
62            }
63        }
64    };
65}
66
67macro_rules! forward_ref_val_binop {
68    (impl $imp:ident for $res:ty, $method:ident) => {
69        impl $imp<$res> for &$res {
70            type Output = $res;
71
72            #[inline]
73            fn $method(self, other: $res) -> $res {
74                // forward to ref-ref
75                $imp::$method(self, &other)
76            }
77        }
78    };
79}
80
81macro_rules! forward_ref_val_binop_commutative {
82    (impl $imp:ident for $res:ty, $method:ident) => {
83        impl $imp<$res> for &$res {
84            type Output = $res;
85
86            #[inline]
87            fn $method(self, other: $res) -> $res {
88                // reverse, forward to val-ref
89                $imp::$method(other, self)
90            }
91        }
92    };
93}
94
95macro_rules! forward_val_ref_binop {
96    (impl $imp:ident for $res:ty, $method:ident) => {
97        impl $imp<&$res> for $res {
98            type Output = $res;
99
100            #[inline]
101            fn $method(self, other: &$res) -> $res {
102                // forward to ref-ref
103                $imp::$method(&self, other)
104            }
105        }
106    };
107}
108
109macro_rules! forward_ref_ref_binop {
110    (impl $imp:ident for $res:ty, $method:ident) => {
111        impl $imp<&$res> for &$res {
112            type Output = $res;
113
114            #[inline]
115            fn $method(self, other: &$res) -> $res {
116                // forward to val-ref
117                $imp::$method(self.clone(), other)
118            }
119        }
120    };
121}
122
123macro_rules! forward_ref_ref_binop_commutative {
124    (impl $imp:ident for $res:ty, $method:ident) => {
125        impl $imp<&$res> for &$res {
126            type Output = $res;
127
128            #[inline]
129            fn $method(self, other: &$res) -> $res {
130                // forward to val-ref, choosing the larger to clone
131                if self.len() >= other.len() {
132                    $imp::$method(self.clone(), other)
133                } else {
134                    $imp::$method(other.clone(), self)
135                }
136            }
137        }
138    };
139}
140
141macro_rules! forward_val_assign {
142    (impl $imp:ident for $res:ty, $method:ident) => {
143        impl $imp<$res> for $res {
144            #[inline]
145            fn $method(&mut self, other: $res) {
146                self.$method(&other);
147            }
148        }
149    };
150}
151
152macro_rules! forward_val_assign_scalar {
153    (impl $imp:ident for $res:ty, $scalar:ty, $method:ident) => {
154        impl $imp<$res> for $scalar {
155            #[inline]
156            fn $method(&mut self, other: $res) {
157                self.$method(&other);
158            }
159        }
160    };
161}
162
163/// use this if val_val_binop is already implemented and the reversed order is required
164macro_rules! forward_scalar_val_val_binop_commutative {
165    (impl $imp:ident < $scalar:ty > for $res:ty, $method:ident) => {
166        impl $imp<$res> for $scalar {
167            type Output = $res;
168
169            #[inline]
170            fn $method(self, other: $res) -> $res {
171                $imp::$method(other, self)
172            }
173        }
174    };
175}
176
177// Forward scalar to ref-val, when reusing storage is not helpful
178macro_rules! forward_scalar_val_val_binop_to_ref_val {
179    (impl $imp:ident<$scalar:ty> for $res:ty, $method:ident) => {
180        impl $imp<$scalar> for $res {
181            type Output = $res;
182
183            #[inline]
184            fn $method(self, other: $scalar) -> $res {
185                $imp::$method(&self, other)
186            }
187        }
188
189        impl $imp<$res> for $scalar {
190            type Output = $res;
191
192            #[inline]
193            fn $method(self, other: $res) -> $res {
194                $imp::$method(self, &other)
195            }
196        }
197    };
198}
199
200macro_rules! forward_scalar_ref_ref_binop_to_ref_val {
201    (impl $imp:ident<$scalar:ty> for $res:ty, $method:ident) => {
202        impl $imp<&$scalar> for &$res {
203            type Output = $res;
204
205            #[inline]
206            fn $method(self, other: &$scalar) -> $res {
207                $imp::$method(self, *other)
208            }
209        }
210
211        impl $imp<&$res> for &$scalar {
212            type Output = $res;
213
214            #[inline]
215            fn $method(self, other: &$res) -> $res {
216                $imp::$method(*self, other)
217            }
218        }
219    };
220}
221
222macro_rules! forward_scalar_val_ref_binop_to_ref_val {
223    (impl $imp:ident<$scalar:ty> for $res:ty, $method:ident) => {
224        impl $imp<&$scalar> for $res {
225            type Output = $res;
226
227            #[inline]
228            fn $method(self, other: &$scalar) -> $res {
229                $imp::$method(&self, *other)
230            }
231        }
232
233        impl $imp<$res> for &$scalar {
234            type Output = $res;
235
236            #[inline]
237            fn $method(self, other: $res) -> $res {
238                $imp::$method(*self, &other)
239            }
240        }
241    };
242}
243
244macro_rules! forward_scalar_val_ref_binop_to_val_val {
245    (impl $imp:ident<$scalar:ty> for $res:ty, $method:ident) => {
246        impl $imp<&$scalar> for $res {
247            type Output = $res;
248
249            #[inline]
250            fn $method(self, other: &$scalar) -> $res {
251                $imp::$method(self, *other)
252            }
253        }
254
255        impl $imp<$res> for &$scalar {
256            type Output = $res;
257
258            #[inline]
259            fn $method(self, other: $res) -> $res {
260                $imp::$method(*self, other)
261            }
262        }
263    };
264}
265
266macro_rules! forward_scalar_ref_val_binop_to_val_val {
267    (impl $imp:ident < $scalar:ty > for $res:ty, $method:ident) => {
268        impl $imp<$scalar> for &$res {
269            type Output = $res;
270
271            #[inline]
272            fn $method(self, other: $scalar) -> $res {
273                $imp::$method(self.clone(), other)
274            }
275        }
276
277        impl $imp<&$res> for $scalar {
278            type Output = $res;
279
280            #[inline]
281            fn $method(self, other: &$res) -> $res {
282                $imp::$method(self, other.clone())
283            }
284        }
285    };
286}
287
288macro_rules! forward_scalar_ref_ref_binop_to_val_val {
289    (impl $imp:ident<$scalar:ty> for $res:ty, $method:ident) => {
290        impl $imp<&$scalar> for &$res {
291            type Output = $res;
292
293            #[inline]
294            fn $method(self, other: &$scalar) -> $res {
295                $imp::$method(self.clone(), *other)
296            }
297        }
298
299        impl $imp<&$res> for &$scalar {
300            type Output = $res;
301
302            #[inline]
303            fn $method(self, other: &$res) -> $res {
304                $imp::$method(*self, other.clone())
305            }
306        }
307    };
308}
309
310macro_rules! promote_scalars {
311    (impl $imp:ident<$promo:ty> for $res:ty, $method:ident, $( $scalar:ty ),*) => {
312        $(
313            forward_all_scalar_binop_to_val_val!(impl $imp<$scalar> for $res, $method);
314
315            impl $imp<$scalar> for $res {
316                type Output = $res;
317
318                #[allow(clippy::cast_lossless)]
319                #[inline]
320                fn $method(self, other: $scalar) -> $res {
321                    $imp::$method(self, other as $promo)
322                }
323            }
324
325            impl $imp<$res> for $scalar {
326                type Output = $res;
327
328                #[allow(clippy::cast_lossless)]
329                #[inline]
330                fn $method(self, other: $res) -> $res {
331                    $imp::$method(self as $promo, other)
332                }
333            }
334        )*
335    }
336}
337macro_rules! promote_scalars_assign {
338    (impl $imp:ident<$promo:ty> for $res:ty, $method:ident, $( $scalar:ty ),*) => {
339        $(
340            impl $imp<$scalar> for $res {
341                #[allow(clippy::cast_lossless)]
342                #[inline]
343                fn $method(&mut self, other: $scalar) {
344                    self.$method(other as $promo);
345                }
346            }
347        )*
348    }
349}
350
351macro_rules! promote_unsigned_scalars {
352    (impl $imp:ident for $res:ty, $method:ident) => {
353        promote_scalars!(impl $imp<u32> for $res, $method, u8, u16);
354        promote_scalars!(impl $imp<UsizePromotion> for $res, $method, usize);
355    }
356}
357
358macro_rules! promote_unsigned_scalars_assign {
359    (impl $imp:ident for $res:ty, $method:ident) => {
360        promote_scalars_assign!(impl $imp<u32> for $res, $method, u8, u16);
361        promote_scalars_assign!(impl $imp<UsizePromotion> for $res, $method, usize);
362    }
363}
364
365macro_rules! promote_signed_scalars {
366    (impl $imp:ident for $res:ty, $method:ident) => {
367        promote_scalars!(impl $imp<i32> for $res, $method, i8, i16);
368        promote_scalars!(impl $imp<IsizePromotion> for $res, $method, isize);
369    }
370}
371
372macro_rules! promote_signed_scalars_assign {
373    (impl $imp:ident for $res:ty, $method:ident) => {
374        promote_scalars_assign!(impl $imp<i32> for $res, $method, i8, i16);
375        promote_scalars_assign!(impl $imp<IsizePromotion> for $res, $method, isize);
376    }
377}
378
379// Forward everything to ref-ref, when reusing storage is not helpful
380macro_rules! forward_all_binop_to_ref_ref {
381    (impl $imp:ident for $res:ty, $method:ident) => {
382        forward_val_val_binop!(impl $imp for $res, $method);
383        forward_val_ref_binop!(impl $imp for $res, $method);
384        forward_ref_val_binop!(impl $imp for $res, $method);
385    };
386}
387
388// Forward everything to val-ref, so LHS storage can be reused
389macro_rules! forward_all_binop_to_val_ref {
390    (impl $imp:ident for $res:ty, $method:ident) => {
391        forward_val_val_binop!(impl $imp for $res, $method);
392        forward_ref_val_binop!(impl $imp for $res, $method);
393        forward_ref_ref_binop!(impl $imp for $res, $method);
394    };
395}
396
397// Forward everything to val-ref, commutatively, so either LHS or RHS storage can be reused
398macro_rules! forward_all_binop_to_val_ref_commutative {
399    (impl $imp:ident for $res:ty, $method:ident) => {
400        forward_val_val_binop_commutative!(impl $imp for $res, $method);
401        forward_ref_val_binop_commutative!(impl $imp for $res, $method);
402        forward_ref_ref_binop_commutative!(impl $imp for $res, $method);
403    };
404}
405
406macro_rules! forward_all_scalar_binop_to_ref_val {
407    (impl $imp:ident<$scalar:ty> for $res:ty, $method:ident) => {
408        forward_scalar_val_val_binop_to_ref_val!(impl $imp<$scalar> for $res, $method);
409        forward_scalar_val_ref_binop_to_ref_val!(impl $imp<$scalar> for $res, $method);
410        forward_scalar_ref_ref_binop_to_ref_val!(impl $imp<$scalar> for $res, $method);
411    }
412}
413
414macro_rules! forward_all_scalar_binop_to_val_val {
415    (impl $imp:ident<$scalar:ty> for $res:ty, $method:ident) => {
416        forward_scalar_val_ref_binop_to_val_val!(impl $imp<$scalar> for $res, $method);
417        forward_scalar_ref_val_binop_to_val_val!(impl $imp<$scalar> for $res, $method);
418        forward_scalar_ref_ref_binop_to_val_val!(impl $imp<$scalar> for $res, $method);
419    }
420}
421
422macro_rules! forward_all_scalar_binop_to_val_val_commutative {
423    (impl $imp:ident<$scalar:ty> for $res:ty, $method:ident) => {
424        forward_scalar_val_val_binop_commutative!(impl $imp<$scalar> for $res, $method);
425        forward_all_scalar_binop_to_val_val!(impl $imp<$scalar> for $res, $method);
426    }
427}
428
429macro_rules! promote_all_scalars {
430    (impl $imp:ident for $res:ty, $method:ident) => {
431        promote_unsigned_scalars!(impl $imp for $res, $method);
432        promote_signed_scalars!(impl $imp for $res, $method);
433    }
434}
435
436macro_rules! promote_all_scalars_assign {
437    (impl $imp:ident for $res:ty, $method:ident) => {
438        promote_unsigned_scalars_assign!(impl $imp for $res, $method);
439        promote_signed_scalars_assign!(impl $imp for $res, $method);
440    }
441}
442
443macro_rules! impl_sum_iter_type {
444    ($res:ty) => {
445        impl<T> Sum<T> for $res
446        where
447            $res: Add<T, Output = $res>,
448        {
449            fn sum<I>(iter: I) -> Self
450            where
451                I: Iterator<Item = T>,
452            {
453                iter.fold(Self::ZERO, <$res>::add)
454            }
455        }
456    };
457}
458
459macro_rules! impl_product_iter_type {
460    ($res:ty) => {
461        impl<T> Product<T> for $res
462        where
463            $res: Mul<T, Output = $res>,
464        {
465            fn product<I>(iter: I) -> Self
466            where
467                I: Iterator<Item = T>,
468            {
469                iter.fold(One::one(), <$res>::mul)
470            }
471        }
472    };
473}