summaryrefslogtreecommitdiffstats
path: root/third_party/rust/num-bigint/src/macros.rs
diff options
context:
space:
mode:
Diffstat (limited to 'third_party/rust/num-bigint/src/macros.rs')
-rw-r--r--third_party/rust/num-bigint/src/macros.rs445
1 files changed, 445 insertions, 0 deletions
diff --git a/third_party/rust/num-bigint/src/macros.rs b/third_party/rust/num-bigint/src/macros.rs
new file mode 100644
index 0000000000..0ba6e48c72
--- /dev/null
+++ b/third_party/rust/num-bigint/src/macros.rs
@@ -0,0 +1,445 @@
+#![allow(unknown_lints)] // older rustc doesn't know `unused_macros`
+#![allow(unused_macros)]
+
+macro_rules! forward_val_val_binop {
+ (impl $imp:ident for $res:ty, $method:ident) => {
+ impl $imp<$res> for $res {
+ type Output = $res;
+
+ #[inline]
+ fn $method(self, other: $res) -> $res {
+ // forward to val-ref
+ $imp::$method(self, &other)
+ }
+ }
+ };
+}
+
+macro_rules! forward_val_val_binop_commutative {
+ (impl $imp:ident for $res:ty, $method:ident) => {
+ impl $imp<$res> for $res {
+ type Output = $res;
+
+ #[inline]
+ fn $method(self, other: $res) -> $res {
+ // forward to val-ref, with the larger capacity as val
+ if self.capacity() >= other.capacity() {
+ $imp::$method(self, &other)
+ } else {
+ $imp::$method(other, &self)
+ }
+ }
+ }
+ };
+}
+
+macro_rules! forward_ref_val_binop {
+ (impl $imp:ident for $res:ty, $method:ident) => {
+ impl<'a> $imp<$res> for &'a $res {
+ type Output = $res;
+
+ #[inline]
+ fn $method(self, other: $res) -> $res {
+ // forward to ref-ref
+ $imp::$method(self, &other)
+ }
+ }
+ };
+}
+
+macro_rules! forward_ref_val_binop_commutative {
+ (impl $imp:ident for $res:ty, $method:ident) => {
+ impl<'a> $imp<$res> for &'a $res {
+ type Output = $res;
+
+ #[inline]
+ fn $method(self, other: $res) -> $res {
+ // reverse, forward to val-ref
+ $imp::$method(other, self)
+ }
+ }
+ };
+}
+
+macro_rules! forward_val_ref_binop {
+ (impl $imp:ident for $res:ty, $method:ident) => {
+ impl<'a> $imp<&'a $res> for $res {
+ type Output = $res;
+
+ #[inline]
+ fn $method(self, other: &$res) -> $res {
+ // forward to ref-ref
+ $imp::$method(&self, other)
+ }
+ }
+ };
+}
+
+macro_rules! forward_ref_ref_binop {
+ (impl $imp:ident for $res:ty, $method:ident) => {
+ impl<'a, 'b> $imp<&'b $res> for &'a $res {
+ type Output = $res;
+
+ #[inline]
+ fn $method(self, other: &$res) -> $res {
+ // forward to val-ref
+ $imp::$method(self.clone(), other)
+ }
+ }
+ };
+}
+
+macro_rules! forward_ref_ref_binop_commutative {
+ (impl $imp:ident for $res:ty, $method:ident) => {
+ impl<'a, 'b> $imp<&'b $res> for &'a $res {
+ type Output = $res;
+
+ #[inline]
+ fn $method(self, other: &$res) -> $res {
+ // forward to val-ref, choosing the larger to clone
+ if self.len() >= other.len() {
+ $imp::$method(self.clone(), other)
+ } else {
+ $imp::$method(other.clone(), self)
+ }
+ }
+ }
+ };
+}
+
+macro_rules! forward_val_assign {
+ (impl $imp:ident for $res:ty, $method:ident) => {
+ impl $imp<$res> for $res {
+ #[inline]
+ fn $method(&mut self, other: $res) {
+ self.$method(&other);
+ }
+ }
+ };
+}
+
+macro_rules! forward_val_assign_scalar {
+ (impl $imp:ident for $res:ty, $scalar:ty, $method:ident) => {
+ impl $imp<$res> for $scalar {
+ #[inline]
+ fn $method(&mut self, other: $res) {
+ self.$method(&other);
+ }
+ }
+ };
+}
+
+/// use this if val_val_binop is already implemented and the reversed order is required
+macro_rules! forward_scalar_val_val_binop_commutative {
+ (impl $imp:ident < $scalar:ty > for $res:ty, $method:ident) => {
+ impl $imp<$res> for $scalar {
+ type Output = $res;
+
+ #[inline]
+ fn $method(self, other: $res) -> $res {
+ $imp::$method(other, self)
+ }
+ }
+ };
+}
+
+// Forward scalar to ref-val, when reusing storage is not helpful
+macro_rules! forward_scalar_val_val_binop_to_ref_val {
+ (impl $imp:ident<$scalar:ty> for $res:ty, $method:ident) => {
+ impl $imp<$scalar> for $res {
+ type Output = $res;
+
+ #[inline]
+ fn $method(self, other: $scalar) -> $res {
+ $imp::$method(&self, other)
+ }
+ }
+
+ impl $imp<$res> for $scalar {
+ type Output = $res;
+
+ #[inline]
+ fn $method(self, other: $res) -> $res {
+ $imp::$method(self, &other)
+ }
+ }
+ };
+}
+
+macro_rules! forward_scalar_ref_ref_binop_to_ref_val {
+ (impl $imp:ident<$scalar:ty> for $res:ty, $method:ident) => {
+ impl<'a, 'b> $imp<&'b $scalar> for &'a $res {
+ type Output = $res;
+
+ #[inline]
+ fn $method(self, other: &$scalar) -> $res {
+ $imp::$method(self, *other)
+ }
+ }
+
+ impl<'a, 'b> $imp<&'a $res> for &'b $scalar {
+ type Output = $res;
+
+ #[inline]
+ fn $method(self, other: &$res) -> $res {
+ $imp::$method(*self, other)
+ }
+ }
+ };
+}
+
+macro_rules! forward_scalar_val_ref_binop_to_ref_val {
+ (impl $imp:ident<$scalar:ty> for $res:ty, $method:ident) => {
+ impl<'a> $imp<&'a $scalar> for $res {
+ type Output = $res;
+
+ #[inline]
+ fn $method(self, other: &$scalar) -> $res {
+ $imp::$method(&self, *other)
+ }
+ }
+
+ impl<'a> $imp<$res> for &'a $scalar {
+ type Output = $res;
+
+ #[inline]
+ fn $method(self, other: $res) -> $res {
+ $imp::$method(*self, &other)
+ }
+ }
+ };
+}
+
+macro_rules! forward_scalar_val_ref_binop_to_val_val {
+ (impl $imp:ident<$scalar:ty> for $res:ty, $method:ident) => {
+ impl<'a> $imp<&'a $scalar> for $res {
+ type Output = $res;
+
+ #[inline]
+ fn $method(self, other: &$scalar) -> $res {
+ $imp::$method(self, *other)
+ }
+ }
+
+ impl<'a> $imp<$res> for &'a $scalar {
+ type Output = $res;
+
+ #[inline]
+ fn $method(self, other: $res) -> $res {
+ $imp::$method(*self, other)
+ }
+ }
+ };
+}
+
+macro_rules! forward_scalar_ref_val_binop_to_val_val {
+ (impl $imp:ident < $scalar:ty > for $res:ty, $method:ident) => {
+ impl<'a> $imp<$scalar> for &'a $res {
+ type Output = $res;
+
+ #[inline]
+ fn $method(self, other: $scalar) -> $res {
+ $imp::$method(self.clone(), other)
+ }
+ }
+
+ impl<'a> $imp<&'a $res> for $scalar {
+ type Output = $res;
+
+ #[inline]
+ fn $method(self, other: &$res) -> $res {
+ $imp::$method(self, other.clone())
+ }
+ }
+ };
+}
+
+macro_rules! forward_scalar_ref_ref_binop_to_val_val {
+ (impl $imp:ident<$scalar:ty> for $res:ty, $method:ident) => {
+ impl<'a, 'b> $imp<&'b $scalar> for &'a $res {
+ type Output = $res;
+
+ #[inline]
+ fn $method(self, other: &$scalar) -> $res {
+ $imp::$method(self.clone(), *other)
+ }
+ }
+
+ impl<'a, 'b> $imp<&'a $res> for &'b $scalar {
+ type Output = $res;
+
+ #[inline]
+ fn $method(self, other: &$res) -> $res {
+ $imp::$method(*self, other.clone())
+ }
+ }
+ };
+}
+
+macro_rules! promote_scalars {
+ (impl $imp:ident<$promo:ty> for $res:ty, $method:ident, $( $scalar:ty ),*) => {
+ $(
+ forward_all_scalar_binop_to_val_val!(impl $imp<$scalar> for $res, $method);
+
+ impl $imp<$scalar> for $res {
+ type Output = $res;
+
+ #[cfg_attr(feature = "cargo-clippy", allow(renamed_and_removed_lints))]
+ #[cfg_attr(feature = "cargo-clippy", allow(cast_lossless))]
+ #[inline]
+ fn $method(self, other: $scalar) -> $res {
+ $imp::$method(self, other as $promo)
+ }
+ }
+
+ impl $imp<$res> for $scalar {
+ type Output = $res;
+
+ #[cfg_attr(feature = "cargo-clippy", allow(renamed_and_removed_lints))]
+ #[cfg_attr(feature = "cargo-clippy", allow(cast_lossless))]
+ #[inline]
+ fn $method(self, other: $res) -> $res {
+ $imp::$method(self as $promo, other)
+ }
+ }
+ )*
+ }
+}
+macro_rules! promote_scalars_assign {
+ (impl $imp:ident<$promo:ty> for $res:ty, $method:ident, $( $scalar:ty ),*) => {
+ $(
+ impl $imp<$scalar> for $res {
+ #[cfg_attr(feature = "cargo-clippy", allow(renamed_and_removed_lints))]
+ #[cfg_attr(feature = "cargo-clippy", allow(cast_lossless))]
+ #[inline]
+ fn $method(&mut self, other: $scalar) {
+ self.$method(other as $promo);
+ }
+ }
+ )*
+ }
+}
+
+macro_rules! promote_unsigned_scalars {
+ (impl $imp:ident for $res:ty, $method:ident) => {
+ promote_scalars!(impl $imp<u32> for $res, $method, u8, u16);
+ promote_scalars!(impl $imp<UsizePromotion> for $res, $method, usize);
+ }
+}
+
+macro_rules! promote_unsigned_scalars_assign {
+ (impl $imp:ident for $res:ty, $method:ident) => {
+ promote_scalars_assign!(impl $imp<u32> for $res, $method, u8, u16);
+ promote_scalars_assign!(impl $imp<UsizePromotion> for $res, $method, usize);
+ }
+}
+
+macro_rules! promote_signed_scalars {
+ (impl $imp:ident for $res:ty, $method:ident) => {
+ promote_scalars!(impl $imp<i32> for $res, $method, i8, i16);
+ promote_scalars!(impl $imp<IsizePromotion> for $res, $method, isize);
+ }
+}
+
+macro_rules! promote_signed_scalars_assign {
+ (impl $imp:ident for $res:ty, $method:ident) => {
+ promote_scalars_assign!(impl $imp<i32> for $res, $method, i8, i16);
+ promote_scalars_assign!(impl $imp<UsizePromotion> for $res, $method, isize);
+ }
+}
+
+// Forward everything to ref-ref, when reusing storage is not helpful
+macro_rules! forward_all_binop_to_ref_ref {
+ (impl $imp:ident for $res:ty, $method:ident) => {
+ forward_val_val_binop!(impl $imp for $res, $method);
+ forward_val_ref_binop!(impl $imp for $res, $method);
+ forward_ref_val_binop!(impl $imp for $res, $method);
+ };
+}
+
+// Forward everything to val-ref, so LHS storage can be reused
+macro_rules! forward_all_binop_to_val_ref {
+ (impl $imp:ident for $res:ty, $method:ident) => {
+ forward_val_val_binop!(impl $imp for $res, $method);
+ forward_ref_val_binop!(impl $imp for $res, $method);
+ forward_ref_ref_binop!(impl $imp for $res, $method);
+ };
+}
+
+// Forward everything to val-ref, commutatively, so either LHS or RHS storage can be reused
+macro_rules! forward_all_binop_to_val_ref_commutative {
+ (impl $imp:ident for $res:ty, $method:ident) => {
+ forward_val_val_binop_commutative!(impl $imp for $res, $method);
+ forward_ref_val_binop_commutative!(impl $imp for $res, $method);
+ forward_ref_ref_binop_commutative!(impl $imp for $res, $method);
+ };
+}
+
+macro_rules! forward_all_scalar_binop_to_ref_val {
+ (impl $imp:ident<$scalar:ty> for $res:ty, $method:ident) => {
+ forward_scalar_val_val_binop_to_ref_val!(impl $imp<$scalar> for $res, $method);
+ forward_scalar_val_ref_binop_to_ref_val!(impl $imp<$scalar> for $res, $method);
+ forward_scalar_ref_ref_binop_to_ref_val!(impl $imp<$scalar> for $res, $method);
+ }
+}
+
+macro_rules! forward_all_scalar_binop_to_val_val {
+ (impl $imp:ident<$scalar:ty> for $res:ty, $method:ident) => {
+ forward_scalar_val_ref_binop_to_val_val!(impl $imp<$scalar> for $res, $method);
+ forward_scalar_ref_val_binop_to_val_val!(impl $imp<$scalar> for $res, $method);
+ forward_scalar_ref_ref_binop_to_val_val!(impl $imp<$scalar> for $res, $method);
+ }
+}
+
+macro_rules! forward_all_scalar_binop_to_val_val_commutative {
+ (impl $imp:ident<$scalar:ty> for $res:ty, $method:ident) => {
+ forward_scalar_val_val_binop_commutative!(impl $imp<$scalar> for $res, $method);
+ forward_all_scalar_binop_to_val_val!(impl $imp<$scalar> for $res, $method);
+ }
+}
+
+macro_rules! promote_all_scalars {
+ (impl $imp:ident for $res:ty, $method:ident) => {
+ promote_unsigned_scalars!(impl $imp for $res, $method);
+ promote_signed_scalars!(impl $imp for $res, $method);
+ }
+}
+
+macro_rules! promote_all_scalars_assign {
+ (impl $imp:ident for $res:ty, $method:ident) => {
+ promote_unsigned_scalars_assign!(impl $imp for $res, $method);
+ promote_signed_scalars_assign!(impl $imp for $res, $method);
+ }
+}
+
+macro_rules! impl_sum_iter_type {
+ ($res:ty) => {
+ impl<T> Sum<T> for $res
+ where
+ $res: Add<T, Output = $res>,
+ {
+ fn sum<I>(iter: I) -> Self
+ where
+ I: Iterator<Item = T>,
+ {
+ iter.fold(Zero::zero(), <$res>::add)
+ }
+ }
+ };
+}
+
+macro_rules! impl_product_iter_type {
+ ($res:ty) => {
+ impl<T> Product<T> for $res
+ where
+ $res: Mul<T, Output = $res>,
+ {
+ fn product<I>(iter: I) -> Self
+ where
+ I: Iterator<Item = T>,
+ {
+ iter.fold(One::one(), <$res>::mul)
+ }
+ }
+ };
+}