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 | |