diff options
Diffstat (limited to 'rust/vendor/num-bigint/src/bigint/multiplication.rs')
-rw-r--r-- | rust/vendor/num-bigint/src/bigint/multiplication.rs | 217 |
1 files changed, 217 insertions, 0 deletions
diff --git a/rust/vendor/num-bigint/src/bigint/multiplication.rs b/rust/vendor/num-bigint/src/bigint/multiplication.rs new file mode 100644 index 0000000..82e64c2 --- /dev/null +++ b/rust/vendor/num-bigint/src/bigint/multiplication.rs @@ -0,0 +1,217 @@ +use super::CheckedUnsignedAbs::{Negative, Positive}; +use super::Sign::{self, Minus, NoSign, Plus}; +use super::{BigInt, UnsignedAbs}; + +use crate::{IsizePromotion, UsizePromotion}; + +use core::iter::Product; +use core::ops::{Mul, MulAssign}; +use num_traits::{CheckedMul, One, Zero}; + +impl Mul<Sign> for Sign { + type Output = Sign; + + #[inline] + fn mul(self, other: Sign) -> Sign { + match (self, other) { + (NoSign, _) | (_, NoSign) => NoSign, + (Plus, Plus) | (Minus, Minus) => Plus, + (Plus, Minus) | (Minus, Plus) => Minus, + } + } +} + +macro_rules! impl_mul { + ($(impl Mul<$Other:ty> for $Self:ty;)*) => {$( + impl Mul<$Other> for $Self { + type Output = BigInt; + + #[inline] + fn mul(self, other: $Other) -> BigInt { + // automatically match value/ref + let BigInt { data: x, .. } = self; + let BigInt { data: y, .. } = other; + BigInt::from_biguint(self.sign * other.sign, x * y) + } + } + )*} +} +impl_mul! { + impl Mul<BigInt> for BigInt; + impl Mul<BigInt> for &BigInt; + impl Mul<&BigInt> for BigInt; + impl Mul<&BigInt> for &BigInt; +} + +macro_rules! impl_mul_assign { + ($(impl MulAssign<$Other:ty> for BigInt;)*) => {$( + impl MulAssign<$Other> for BigInt { + #[inline] + fn mul_assign(&mut self, other: $Other) { + // automatically match value/ref + let BigInt { data: y, .. } = other; + self.data *= y; + if self.data.is_zero() { + self.sign = NoSign; + } else { + self.sign = self.sign * other.sign; + } + } + } + )*} +} +impl_mul_assign! { + impl MulAssign<BigInt> for BigInt; + impl MulAssign<&BigInt> for BigInt; +} + +promote_all_scalars!(impl Mul for BigInt, mul); +promote_all_scalars_assign!(impl MulAssign for BigInt, mul_assign); +forward_all_scalar_binop_to_val_val_commutative!(impl Mul<u32> for BigInt, mul); +forward_all_scalar_binop_to_val_val_commutative!(impl Mul<u64> for BigInt, mul); +forward_all_scalar_binop_to_val_val_commutative!(impl Mul<u128> for BigInt, mul); + +impl Mul<u32> for BigInt { + type Output = BigInt; + + #[inline] + fn mul(self, other: u32) -> BigInt { + BigInt::from_biguint(self.sign, self.data * other) + } +} + +impl MulAssign<u32> for BigInt { + #[inline] + fn mul_assign(&mut self, other: u32) { + self.data *= other; + if self.data.is_zero() { + self.sign = NoSign; + } + } +} + +impl Mul<u64> for BigInt { + type Output = BigInt; + + #[inline] + fn mul(self, other: u64) -> BigInt { + BigInt::from_biguint(self.sign, self.data * other) + } +} + +impl MulAssign<u64> for BigInt { + #[inline] + fn mul_assign(&mut self, other: u64) { + self.data *= other; + if self.data.is_zero() { + self.sign = NoSign; + } + } +} + +impl Mul<u128> for BigInt { + type Output = BigInt; + + #[inline] + fn mul(self, other: u128) -> BigInt { + BigInt::from_biguint(self.sign, self.data * other) + } +} + +impl MulAssign<u128> for BigInt { + #[inline] + fn mul_assign(&mut self, other: u128) { + self.data *= other; + if self.data.is_zero() { + self.sign = NoSign; + } + } +} + +forward_all_scalar_binop_to_val_val_commutative!(impl Mul<i32> for BigInt, mul); +forward_all_scalar_binop_to_val_val_commutative!(impl Mul<i64> for BigInt, mul); +forward_all_scalar_binop_to_val_val_commutative!(impl Mul<i128> for BigInt, mul); + +impl Mul<i32> for BigInt { + type Output = BigInt; + + #[inline] + fn mul(self, other: i32) -> BigInt { + match other.checked_uabs() { + Positive(u) => self * u, + Negative(u) => -self * u, + } + } +} + +impl MulAssign<i32> for BigInt { + #[inline] + fn mul_assign(&mut self, other: i32) { + match other.checked_uabs() { + Positive(u) => *self *= u, + Negative(u) => { + self.sign = -self.sign; + self.data *= u; + } + } + } +} + +impl Mul<i64> for BigInt { + type Output = BigInt; + + #[inline] + fn mul(self, other: i64) -> BigInt { + match other.checked_uabs() { + Positive(u) => self * u, + Negative(u) => -self * u, + } + } +} + +impl MulAssign<i64> for BigInt { + #[inline] + fn mul_assign(&mut self, other: i64) { + match other.checked_uabs() { + Positive(u) => *self *= u, + Negative(u) => { + self.sign = -self.sign; + self.data *= u; + } + } + } +} + +impl Mul<i128> for BigInt { + type Output = BigInt; + + #[inline] + fn mul(self, other: i128) -> BigInt { + match other.checked_uabs() { + Positive(u) => self * u, + Negative(u) => -self * u, + } + } +} + +impl MulAssign<i128> for BigInt { + #[inline] + fn mul_assign(&mut self, other: i128) { + match other.checked_uabs() { + Positive(u) => *self *= u, + Negative(u) => { + self.sign = -self.sign; + self.data *= u; + } + } + } +} + +impl CheckedMul for BigInt { + #[inline] + fn checked_mul(&self, v: &BigInt) -> Option<BigInt> { + Some(self.mul(v)) + } +} + +impl_product_iter_type!(BigInt); |