Ver código fonte

All variants of subtracting BigDigit from BigUint

Allow the subtraction to occur with either operand order and with any
combination of owned and borrowed arguments.
Sam Cappleman-Lynes 7 anos atrás
pai
commit
51408a9b3b
3 arquivos alterados com 42 adições e 12 exclusões
  1. 16 0
      bigint/src/biguint.rs
  2. 16 10
      bigint/src/macros.rs
  3. 10 2
      bigint/src/tests/biguint.rs

+ 16 - 0
bigint/src/biguint.rs

@@ -439,6 +439,8 @@ impl<'a> Sub<BigUint> for &'a BigUint {
     }
     }
 }
 }
 
 
+forward_all_scalar_binop_to_val_val!(impl Sub<BigDigit> for BigUint, sub);
+
 impl Sub<BigDigit> for BigUint {
 impl Sub<BigDigit> for BigUint {
     type Output = BigUint;
     type Output = BigUint;
 
 
@@ -449,6 +451,20 @@ impl Sub<BigDigit> for BigUint {
     }
     }
 }
 }
 
 
+impl Sub<BigUint> for BigDigit {
+    type Output = BigUint;
+
+    #[inline]
+    fn sub(self, mut other: BigUint) -> BigUint {
+        if other.data.len() == 0 {
+            other.data.push(0);
+        }
+
+        sub2rev(&[self], &mut other.data[..]);
+        other.normalize()
+    }
+}
+
 forward_all_binop_to_ref_ref!(impl Mul for BigUint, mul);
 forward_all_binop_to_ref_ref!(impl Mul for BigUint, mul);
 
 
 impl<'a, 'b> Mul<&'b BigUint> for &'a BigUint {
 impl<'a, 'b> Mul<&'b BigUint> for &'a BigUint {

+ 16 - 10
bigint/src/macros.rs

@@ -118,7 +118,7 @@ macro_rules! forward_scalar_val_val_binop_commutative {
     }
     }
 }
 }
 
 
-macro_rules! forward_scalar_val_ref_binop_commutative {
+macro_rules! forward_scalar_val_ref_binop {
     (impl $imp:ident<$scalar:ty> for $res:ty, $method:ident) => {
     (impl $imp:ident<$scalar:ty> for $res:ty, $method:ident) => {
         impl<'a> $imp<&'a $scalar> for $res {
         impl<'a> $imp<&'a $scalar> for $res {
             type Output = $res;
             type Output = $res;
@@ -134,13 +134,13 @@ macro_rules! forward_scalar_val_ref_binop_commutative {
 
 
             #[inline]
             #[inline]
             fn $method(self, other: $res) -> $res {
             fn $method(self, other: $res) -> $res {
-                $imp::$method(other, *self)
+                $imp::$method(*self, other)
             }
             }
         }
         }
     }
     }
 }
 }
 
 
-macro_rules! forward_scalar_ref_val_binop_commutative {
+macro_rules! forward_scalar_ref_val_binop {
     (impl $imp:ident<$scalar:ty> for $res:ty, $method:ident) => {
     (impl $imp:ident<$scalar:ty> for $res:ty, $method:ident) => {
         impl<'a> $imp<$scalar> for &'a $res {
         impl<'a> $imp<$scalar> for &'a $res {
             type Output = $res;
             type Output = $res;
@@ -156,13 +156,13 @@ macro_rules! forward_scalar_ref_val_binop_commutative {
 
 
             #[inline]
             #[inline]
             fn $method(self, other: &$res) -> $res {
             fn $method(self, other: &$res) -> $res {
-                $imp::$method(other.clone(), self)
+                $imp::$method(self, other.clone())
             }
             }
         }
         }
     }
     }
 }
 }
 
 
-macro_rules! forward_scalar_ref_ref_binop_commutative {
+macro_rules! forward_scalar_ref_ref_binop {
     (impl $imp:ident<$scalar:ty> for $res:ty, $method:ident) => {
     (impl $imp:ident<$scalar:ty> for $res:ty, $method:ident) => {
         impl<'a, 'b> $imp<&'b $scalar> for &'a $res {
         impl<'a, 'b> $imp<&'b $scalar> for &'a $res {
             type Output = $res;
             type Output = $res;
@@ -178,7 +178,7 @@ macro_rules! forward_scalar_ref_ref_binop_commutative {
 
 
             #[inline]
             #[inline]
             fn $method(self, other: &$res) -> $res {
             fn $method(self, other: &$res) -> $res {
-                $imp::$method(other.clone(), *self)
+                $imp::$method(*self, other.clone())
             }
             }
         }
         }
     }
     }
@@ -211,11 +211,17 @@ macro_rules! forward_all_binop_to_val_ref_commutative {
     };
     };
 }
 }
 
 
+macro_rules! forward_all_scalar_binop_to_val_val {
+    (impl $imp:ident<$scalar:ty> for $res:ty, $method:ident) => {
+        forward_scalar_val_ref_binop!(impl $imp<$scalar> for $res, $method);
+        forward_scalar_ref_val_binop!(impl $imp<$scalar> for $res, $method);
+        forward_scalar_ref_ref_binop!(impl $imp<$scalar> for $res, $method);
+    }
+}
+
 macro_rules! forward_all_scalar_binop_to_val_val_commutative {
 macro_rules! forward_all_scalar_binop_to_val_val_commutative {
     (impl $imp:ident<$scalar:ty> for $res:ty, $method:ident) => {
     (impl $imp:ident<$scalar:ty> for $res:ty, $method:ident) => {
         forward_scalar_val_val_binop_commutative!(impl $imp<$scalar> for $res, $method);
         forward_scalar_val_val_binop_commutative!(impl $imp<$scalar> for $res, $method);
-        forward_scalar_val_ref_binop_commutative!(impl $imp<$scalar> for $res, $method);
-        forward_scalar_ref_val_binop_commutative!(impl $imp<$scalar> for $res, $method);
-        forward_scalar_ref_ref_binop_commutative!(impl $imp<$scalar> for $res, $method);
+        forward_all_scalar_binop_to_val_val!(impl $imp<$scalar> for $res, $method);
     }
     }
-}
+}

+ 10 - 2
bigint/src/tests/biguint.rs

@@ -734,14 +734,22 @@ fn test_scalar_sub() {
             let a = a_vec[0];
             let a = a_vec[0];
             let b = BigUint::from_slice(b_vec);
             let b = BigUint::from_slice(b_vec);
             let c = BigUint::from_slice(c_vec);
             let c = BigUint::from_slice(c_vec);
-            assert!(c - a == b);
+            assert_op!(c - a == b);
         }
         }
 
 
         if b_vec.len() == 1 {
         if b_vec.len() == 1 {
             let a = BigUint::from_slice(a_vec);
             let a = BigUint::from_slice(a_vec);
             let b = b_vec[0];
             let b = b_vec[0];
             let c = BigUint::from_slice(c_vec);
             let c = BigUint::from_slice(c_vec);
-            assert!(c - b == a);
+            assert_op!(c - b == a);
+        }
+
+        if c_vec.len() == 1 {
+            let a = BigUint::from_slice(a_vec);
+            let b = BigUint::from_slice(b_vec);
+            let c = c_vec[0];
+            assert_op!(c - a == b);
+            assert_op!(c - b == a);
         }
         }
     }
     }
 }
 }