1 #![allow(unknown_lints)] // older rustc doesn't know `unused_macros` 2 #![allow(unused_macros)] 3 4 macro_rules! forward_val_val_binop { 5 (impl $imp:ident for $res:ty, $method:ident) => { 6 impl $imp<$res> for $res { 7 type Output = $res; 8 9 #[inline] 10 fn $method(self, other: $res) -> $res { 11 // forward to val-ref 12 $imp::$method(self, &other) 13 } 14 } 15 }; 16 } 17 18 macro_rules! forward_val_val_binop_commutative { 19 (impl $imp:ident for $res:ty, $method:ident) => { 20 impl $imp<$res> for $res { 21 type Output = $res; 22 23 #[inline] 24 fn $method(self, other: $res) -> $res { 25 // forward to val-ref, with the larger capacity as val 26 if self.capacity() >= other.capacity() { 27 $imp::$method(self, &other) 28 } else { 29 $imp::$method(other, &self) 30 } 31 } 32 } 33 }; 34 } 35 36 macro_rules! forward_ref_val_binop { 37 (impl $imp:ident for $res:ty, $method:ident) => { 38 impl<'a> $imp<$res> for &'a $res { 39 type Output = $res; 40 41 #[inline] 42 fn $method(self, other: $res) -> $res { 43 // forward to ref-ref 44 $imp::$method(self, &other) 45 } 46 } 47 }; 48 } 49 50 macro_rules! forward_ref_val_binop_commutative { 51 (impl $imp:ident for $res:ty, $method:ident) => { 52 impl<'a> $imp<$res> for &'a $res { 53 type Output = $res; 54 55 #[inline] 56 fn $method(self, other: $res) -> $res { 57 // reverse, forward to val-ref 58 $imp::$method(other, self) 59 } 60 } 61 }; 62 } 63 64 macro_rules! forward_val_ref_binop { 65 (impl $imp:ident for $res:ty, $method:ident) => { 66 impl<'a> $imp<&'a $res> for $res { 67 type Output = $res; 68 69 #[inline] 70 fn $method(self, other: &$res) -> $res { 71 // forward to ref-ref 72 $imp::$method(&self, other) 73 } 74 } 75 }; 76 } 77 78 macro_rules! forward_ref_ref_binop { 79 (impl $imp:ident for $res:ty, $method:ident) => { 80 impl<'a, 'b> $imp<&'b $res> for &'a $res { 81 type Output = $res; 82 83 #[inline] 84 fn $method(self, other: &$res) -> $res { 85 // forward to val-ref 86 $imp::$method(self.clone(), other) 87 } 88 } 89 }; 90 } 91 92 macro_rules! forward_ref_ref_binop_commutative { 93 (impl $imp:ident for $res:ty, $method:ident) => { 94 impl<'a, 'b> $imp<&'b $res> for &'a $res { 95 type Output = $res; 96 97 #[inline] 98 fn $method(self, other: &$res) -> $res { 99 // forward to val-ref, choosing the larger to clone 100 if self.len() >= other.len() { 101 $imp::$method(self.clone(), other) 102 } else { 103 $imp::$method(other.clone(), self) 104 } 105 } 106 } 107 }; 108 } 109 110 macro_rules! forward_val_assign { 111 (impl $imp:ident for $res:ty, $method:ident) => { 112 impl $imp<$res> for $res { 113 #[inline] 114 fn $method(&mut self, other: $res) { 115 self.$method(&other); 116 } 117 } 118 }; 119 } 120 macro_rules! forward_val_assign_scalar { 121 (impl $imp:ident for $res:ty, $scalar:ty, $method:ident) => { 122 impl $imp<$res> for $scalar { 123 #[inline] 124 fn $method(&mut self, other: $res) { 125 self.$method(&other); 126 } 127 } 128 }; 129 } 130 131 macro_rules! forward_scalar_val_val_binop_commutative { 132 (impl $imp:ident < $scalar:ty > for $res:ty, $method:ident) => { 133 impl $imp<$res> for $scalar { 134 type Output = $res; 135 136 #[inline] 137 fn $method(self, other: $res) -> $res { 138 $imp::$method(other, self) 139 } 140 } 141 }; 142 } 143 144 macro_rules! forward_scalar_val_ref_binop { 145 (impl $imp:ident < $scalar:ty > for $res:ty, $method:ident) => { 146 impl<'a> $imp<&'a $scalar> for $res { 147 type Output = $res; 148 149 #[inline] 150 fn $method(self, other: &$scalar) -> $res { 151 $imp::$method(self, *other) 152 } 153 } 154 155 impl<'a> $imp<$res> for &'a $scalar { 156 type Output = $res; 157 158 #[inline] 159 fn $method(self, other: $res) -> $res { 160 $imp::$method(*self, other) 161 } 162 } 163 }; 164 } 165 166 macro_rules! forward_scalar_ref_val_binop { 167 (impl $imp:ident < $scalar:ty > for $res:ty, $method:ident) => { 168 impl<'a> $imp<$scalar> for &'a $res { 169 type Output = $res; 170 171 #[inline] 172 fn $method(self, other: $scalar) -> $res { 173 $imp::$method(self.clone(), other) 174 } 175 } 176 177 impl<'a> $imp<&'a $res> for $scalar { 178 type Output = $res; 179 180 #[inline] 181 fn $method(self, other: &$res) -> $res { 182 $imp::$method(self, other.clone()) 183 } 184 } 185 }; 186 } 187 188 macro_rules! forward_scalar_ref_ref_binop { 189 (impl $imp:ident < $scalar:ty > for $res:ty, $method:ident) => { 190 impl<'a, 'b> $imp<&'b $scalar> for &'a $res { 191 type Output = $res; 192 193 #[inline] 194 fn $method(self, other: &$scalar) -> $res { 195 $imp::$method(self.clone(), *other) 196 } 197 } 198 199 impl<'a, 'b> $imp<&'a $res> for &'b $scalar { 200 type Output = $res; 201 202 #[inline] 203 fn $method(self, other: &$res) -> $res { 204 $imp::$method(*self, other.clone()) 205 } 206 } 207 }; 208 } 209 210 macro_rules! promote_scalars { 211 (impl $imp:ident<$promo:ty> for $res:ty, $method:ident, $( $scalar:ty ),*) => { 212 $( 213 forward_all_scalar_binop_to_val_val!(impl $imp<$scalar> for $res, $method); 214 215 impl $imp<$scalar> for $res { 216 type Output = $res; 217 218 #[inline] 219 fn $method(self, other: $scalar) -> $res { 220 $imp::$method(self, other as $promo) 221 } 222 } 223 224 impl $imp<$res> for $scalar { 225 type Output = $res; 226 227 #[inline] 228 fn $method(self, other: $res) -> $res { 229 $imp::$method(self as $promo, other) 230 } 231 } 232 )* 233 } 234 } 235 macro_rules! promote_scalars_assign { 236 (impl $imp:ident<$promo:ty> for $res:ty, $method:ident, $( $scalar:ty ),*) => { 237 $( 238 impl $imp<$scalar> for $res { 239 #[inline] 240 fn $method(&mut self, other: $scalar) { 241 self.$method(other as $promo); 242 } 243 } 244 )* 245 } 246 } 247 248 macro_rules! promote_unsigned_scalars { 249 (impl $imp:ident for $res:ty, $method:ident) => { 250 promote_scalars!(impl $imp<u32> for $res, $method, u8, u16); 251 promote_scalars!(impl $imp<UsizePromotion> for $res, $method, usize); 252 } 253 } 254 255 macro_rules! promote_unsigned_scalars_assign { 256 (impl $imp:ident for $res:ty, $method:ident) => { 257 promote_scalars_assign!(impl $imp<u32> for $res, $method, u8, u16); 258 promote_scalars_assign!(impl $imp<UsizePromotion> for $res, $method, usize); 259 } 260 } 261 262 macro_rules! promote_signed_scalars { 263 (impl $imp:ident for $res:ty, $method:ident) => { 264 promote_scalars!(impl $imp<i32> for $res, $method, i8, i16); 265 promote_scalars!(impl $imp<IsizePromotion> for $res, $method, isize); 266 } 267 } 268 269 macro_rules! promote_signed_scalars_assign { 270 (impl $imp:ident for $res:ty, $method:ident) => { 271 promote_scalars_assign!(impl $imp<i32> for $res, $method, i8, i16); 272 promote_scalars_assign!(impl $imp<UsizePromotion> for $res, $method, isize); 273 } 274 } 275 276 // Forward everything to ref-ref, when reusing storage is not helpful 277 macro_rules! forward_all_binop_to_ref_ref { 278 (impl $imp:ident for $res:ty, $method:ident) => { 279 forward_val_val_binop!(impl $imp for $res, $method); 280 forward_val_ref_binop!(impl $imp for $res, $method); 281 forward_ref_val_binop!(impl $imp for $res, $method); 282 }; 283 } 284 285 // Forward everything to val-ref, so LHS storage can be reused 286 macro_rules! forward_all_binop_to_val_ref { 287 (impl $imp:ident for $res:ty, $method:ident) => { 288 forward_val_val_binop!(impl $imp for $res, $method); 289 forward_ref_val_binop!(impl $imp for $res, $method); 290 forward_ref_ref_binop!(impl $imp for $res, $method); 291 }; 292 } 293 294 // Forward everything to val-ref, commutatively, so either LHS or RHS storage can be reused 295 macro_rules! forward_all_binop_to_val_ref_commutative { 296 (impl $imp:ident for $res:ty, $method:ident) => { 297 forward_val_val_binop_commutative!(impl $imp for $res, $method); 298 forward_ref_val_binop_commutative!(impl $imp for $res, $method); 299 forward_ref_ref_binop_commutative!(impl $imp for $res, $method); 300 }; 301 } 302 303 macro_rules! forward_all_scalar_binop_to_val_val { 304 (impl $imp:ident<$scalar:ty> for $res:ty, $method:ident) => { 305 forward_scalar_val_ref_binop!(impl $imp<$scalar> for $res, $method); 306 forward_scalar_ref_val_binop!(impl $imp<$scalar> for $res, $method); 307 forward_scalar_ref_ref_binop!(impl $imp<$scalar> for $res, $method); 308 } 309 } 310 311 macro_rules! forward_all_scalar_binop_to_val_val_commutative { 312 (impl $imp:ident<$scalar:ty> for $res:ty, $method:ident) => { 313 forward_scalar_val_val_binop_commutative!(impl $imp<$scalar> for $res, $method); 314 forward_all_scalar_binop_to_val_val!(impl $imp<$scalar> for $res, $method); 315 } 316 } 317 318 macro_rules! promote_all_scalars { 319 (impl $imp:ident for $res:ty, $method:ident) => { 320 promote_unsigned_scalars!(impl $imp for $res, $method); 321 promote_signed_scalars!(impl $imp for $res, $method); 322 } 323 } 324 325 macro_rules! promote_all_scalars_assign { 326 (impl $imp:ident for $res:ty, $method:ident) => { 327 promote_unsigned_scalars_assign!(impl $imp for $res, $method); 328 promote_signed_scalars_assign!(impl $imp for $res, $method); 329 } 330 } 331 332 macro_rules! impl_sum_iter_type { 333 ($res:ty) => { 334 impl<T> Sum<T> for $res 335 where 336 $res: Add<T, Output = $res>, 337 { 338 fn sum<I>(iter: I) -> Self 339 where 340 I: Iterator<Item = T>, 341 { 342 iter.fold(Zero::zero(), <$res>::add) 343 } 344 } 345 }; 346 } 347 348 macro_rules! impl_product_iter_type { 349 ($res:ty) => { 350 impl<T> Product<T> for $res 351 where 352 $res: Mul<T, Output = $res>, 353 { 354 fn product<I>(iter: I) -> Self 355 where 356 I: Iterator<Item = T>, 357 { 358 iter.fold(One::one(), <$res>::mul) 359 } 360 } 361 }; 362 } 363