• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 #![allow(unused_macros)]
2 
3 macro_rules! cfg_32 {
4     ($($any:tt)+) => {
5         #[cfg(not(target_pointer_width = "64"))] $($any)+
6     }
7 }
8 
9 macro_rules! cfg_32_or_test {
10     ($($any:tt)+) => {
11         #[cfg(any(not(target_pointer_width = "64"), test))] $($any)+
12     }
13 }
14 
15 macro_rules! cfg_64 {
16     ($($any:tt)+) => {
17         #[cfg(target_pointer_width = "64")] $($any)+
18     }
19 }
20 
21 macro_rules! cfg_digit {
22     ($item32:item $item64:item) => {
23         cfg_32!($item32);
24         cfg_64!($item64);
25     };
26 }
27 
28 macro_rules! cfg_digit_expr {
29     ($expr32:expr, $expr64:expr) => {
30         cfg_32!($expr32);
31         cfg_64!($expr64);
32     };
33 }
34 
35 macro_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 
49 macro_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 
67 macro_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 
81 macro_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 
95 macro_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 
109 macro_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 
123 macro_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 
141 macro_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 
152 macro_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
164 macro_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
178 macro_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 
200 macro_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 
222 macro_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 
244 macro_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 
266 macro_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 
288 macro_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 
310 macro_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 }
337 macro_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 
351 macro_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 
358 macro_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 
365 macro_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 
372 macro_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
380 macro_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
389 macro_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
398 macro_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 
406 macro_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 
414 macro_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 
422 macro_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 
429 macro_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 
436 macro_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 
443 macro_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 
459 macro_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 }
474