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