Browse Source

Merge #104

104: Add inplace methods to `Zero` and `One` r=cuviper a=lcnr

Adds the following default implemented methods to `Zero` and `One`:

```rust
fn set_zero(&mut self) {
    *self = Zero::zero();
}
```

```rust
fn set_one(&mut self) {
    *self = One::one();
}
```

This allows for reuse of BigNums.


Co-authored-by: lcnr/Bastian Kauschke <bastian_kauschke@hotmail.de>
Co-authored-by: Josh Stone <cuviper@gmail.com>
bors[bot] 6 years ago
parent
commit
5404658360
1 changed files with 37 additions and 15 deletions
  1. 37 15
      src/identities.rs

+ 37 - 15
src/identities.rs

@@ -2,16 +2,15 @@ use core::num::Wrapping;
 use core::ops::{Add, Mul};
 
 /// Defines an additive identity element for `Self`.
+///
+/// # Laws
+///
+/// ```{.text}
+/// a + 0 = a       ∀ a ∈ Self
+/// 0 + a = a       ∀ a ∈ Self
+/// ```
 pub trait Zero: Sized + Add<Self, Output = Self> {
     /// Returns the additive identity element of `Self`, `0`.
-    ///
-    /// # Laws
-    ///
-    /// ```{.text}
-    /// a + 0 = a       ∀ a ∈ Self
-    /// 0 + a = a       ∀ a ∈ Self
-    /// ```
-    ///
     /// # Purity
     ///
     /// This function should return the same result at all times regardless of
@@ -20,6 +19,11 @@ pub trait Zero: Sized + Add<Self, Output = Self> {
     // This cannot be an associated constant, because of bignums.
     fn zero() -> Self;
 
+    /// Sets `self` to the additive identity element of `Self`, `0`.
+    fn set_zero(&mut self) {
+        *self = Zero::zero();
+    }
+
     /// Returns `true` if `self` is equal to the additive identity.
     #[inline]
     fn is_zero(&self) -> bool;
@@ -66,22 +70,27 @@ where
     fn is_zero(&self) -> bool {
         self.0.is_zero()
     }
+
+    fn set_zero(&mut self) {
+        self.0.set_zero();
+    }
+
     fn zero() -> Self {
         Wrapping(T::zero())
     }
 }
 
 /// Defines a multiplicative identity element for `Self`.
+///
+/// # Laws
+///
+/// ```{.text}
+/// a * 1 = a       ∀ a ∈ Self
+/// 1 * a = a       ∀ a ∈ Self
+/// ```
 pub trait One: Sized + Mul<Self, Output = Self> {
     /// Returns the multiplicative identity element of `Self`, `1`.
     ///
-    /// # Laws
-    ///
-    /// ```{.text}
-    /// a * 1 = a       ∀ a ∈ Self
-    /// 1 * a = a       ∀ a ∈ Self
-    /// ```
-    ///
     /// # Purity
     ///
     /// This function should return the same result at all times regardless of
@@ -90,6 +99,11 @@ pub trait One: Sized + Mul<Self, Output = Self> {
     // This cannot be an associated constant, because of bignums.
     fn one() -> Self;
 
+    /// Sets `self` to the multiplicative identity element of `Self`, `1`.
+    fn set_one(&mut self) {
+        *self = One::one();
+    }
+
     /// Returns `true` if `self` is equal to the multiplicative identity.
     ///
     /// For performance reasons, it's best to implement this manually.
@@ -111,6 +125,10 @@ macro_rules! one_impl {
             fn one() -> $t {
                 $v
             }
+            #[inline]
+            fn is_one(&self) -> bool {
+                *self == $v
+            }
         }
     };
 }
@@ -138,6 +156,10 @@ impl<T: One> One for Wrapping<T>
 where
     Wrapping<T>: Mul<Output = Wrapping<T>>,
 {
+    fn set_one(&mut self) {
+        self.0.set_one();
+    }
+
     fn one() -> Self {
         Wrapping(T::one())
     }