chiark / gitweb /
Hide some of the boring boilerplate.
authorSimon Tatham <anakin@pobox.com>
Fri, 11 Apr 2025 18:18:29 +0000 (19:18 +0100)
committerSimon Tatham <anakin@pobox.com>
Fri, 11 Apr 2025 18:19:07 +0000 (19:19 +0100)
src/finitenimber.rs

index 7197401d147a42e1bd4ad12413b0a53803c9d0a0..82a2ec94ff1a6f354e6c0b42ae0be6210e572686 100644 (file)
@@ -198,6 +198,64 @@ impl From<Word> for FiniteNimber {
     }
 }
 
+macro_rules! impl_binop_wrappers {
+    ($trait:tt, $fn:ident) => {
+        impl $trait<FiniteNimberRef<'_>> for FiniteNimber {
+            type Output = FiniteNimber;
+            fn $fn(self, other: FiniteNimberRef<'_>) -> FiniteNimber {
+                let aref: FiniteNimberRef = (&self).into();
+                let bref: FiniteNimberRef = other;
+                $trait::$fn(aref, bref)
+            }
+        }
+
+        impl $trait<FiniteNimber> for FiniteNimberRef<'_> {
+            type Output = FiniteNimber;
+            fn $fn(self, other: FiniteNimber) -> FiniteNimber {
+                let aref: FiniteNimberRef = self;
+                let bref: FiniteNimberRef = (&other).into();
+                $trait::$fn(aref, bref)
+            }
+        }
+
+        impl $trait<&FiniteNimber> for &FiniteNimber {
+            type Output = FiniteNimber;
+            fn $fn(self, other: &FiniteNimber) -> FiniteNimber {
+                let aref: FiniteNimberRef = self.into();
+                let bref: FiniteNimberRef = other.into();
+                $trait::$fn(aref, bref)
+            }
+        }
+
+        impl $trait<&FiniteNimber> for FiniteNimber {
+            type Output = FiniteNimber;
+            fn $fn(self, other: &FiniteNimber) -> FiniteNimber {
+                let aref: FiniteNimberRef = (&self).into();
+                let bref: FiniteNimberRef = other.into();
+                $trait::$fn(aref, bref)
+            }
+        }
+
+        impl $trait<FiniteNimber> for &FiniteNimber {
+            type Output = FiniteNimber;
+            fn $fn(self, other: FiniteNimber) -> FiniteNimber {
+                let aref: FiniteNimberRef = self.into();
+                let bref: FiniteNimberRef = (&other).into();
+                $trait::$fn(aref, bref)
+            }
+        }
+
+        impl $trait<FiniteNimber> for FiniteNimber {
+            type Output = FiniteNimber;
+            fn $fn(self, other: FiniteNimber) -> FiniteNimber {
+                let aref: FiniteNimberRef = (&self).into();
+                let bref: FiniteNimberRef = (&other).into();
+                $trait::$fn(aref, bref)
+            }
+        }
+    };
+}
+
 impl<'a, 'b> Add<FiniteNimberRef<'a>> for FiniteNimberRef<'b> {
     type Output = FiniteNimber;
     fn add(self, other: FiniteNimberRef<'a>) -> FiniteNimber {
@@ -211,42 +269,6 @@ impl<'a, 'b> Add<FiniteNimberRef<'a>> for FiniteNimberRef<'b> {
     }
 }
 
-impl Add<&FiniteNimber> for &FiniteNimber {
-    type Output = FiniteNimber;
-    fn add(self, other: &FiniteNimber) -> FiniteNimber {
-        let aref: FiniteNimberRef = self.into();
-        let bref: FiniteNimberRef = other.into();
-        aref + bref
-    }
-}
-
-impl Add<&FiniteNimber> for FiniteNimber {
-    type Output = FiniteNimber;
-    fn add(self, other: &FiniteNimber) -> FiniteNimber {
-        let aref: FiniteNimberRef = (&self).into();
-        let bref: FiniteNimberRef = other.into();
-        aref + bref
-    }
-}
-
-impl Add<FiniteNimber> for &FiniteNimber {
-    type Output = FiniteNimber;
-    fn add(self, other: FiniteNimber) -> FiniteNimber {
-        let aref: FiniteNimberRef = self.into();
-        let bref: FiniteNimberRef = (&other).into();
-        aref + bref
-    }
-}
-
-impl Add<FiniteNimber> for FiniteNimber {
-    type Output = FiniteNimber;
-    fn add(self, other: FiniteNimber) -> FiniteNimber {
-        let aref: FiniteNimberRef = (&self).into();
-        let bref: FiniteNimberRef = (&other).into();
-        aref + bref
-    }
-}
-
 impl<'a> FiniteNimberRef<'a> {
     fn mul_by_h(self, level: usize) -> FiniteNimber {
         match level.checked_sub(1) {
@@ -279,12 +301,9 @@ impl<'a, 'b> Mul<FiniteNimberRef<'a>> for FiniteNimberRef<'b> {
                 let karatsuba = (alo + ahi) * (blo + bhi);
                 let albl = alo * blo;
                 let ahbh = ahi * bhi;
-                (albl.to_ref() + ahbh.to_ref().mul_by_h(sublevel).to_ref())
+                (&albl + ahbh.to_ref().mul_by_h(sublevel))
                     .to_ref()
-                    .join(
-                        (karatsuba.to_ref() + albl.to_ref()).to_ref(),
-                        sublevel,
-                    )
+                    .join((karatsuba + &albl).to_ref(), sublevel)
             }
 
             // At level 0, we're in GF(2), so multiplication looks
@@ -294,41 +313,8 @@ impl<'a, 'b> Mul<FiniteNimberRef<'a>> for FiniteNimberRef<'b> {
     }
 }
 
-impl Mul<&FiniteNimber> for &FiniteNimber {
-    type Output = FiniteNimber;
-    fn mul(self, other: &FiniteNimber) -> FiniteNimber {
-        let aref: FiniteNimberRef = self.into();
-        let bref: FiniteNimberRef = other.into();
-        aref * bref
-    }
-}
-
-impl Mul<&FiniteNimber> for FiniteNimber {
-    type Output = FiniteNimber;
-    fn mul(self, other: &FiniteNimber) -> FiniteNimber {
-        let aref: FiniteNimberRef = (&self).into();
-        let bref: FiniteNimberRef = other.into();
-        aref * bref
-    }
-}
-
-impl Mul<FiniteNimber> for &FiniteNimber {
-    type Output = FiniteNimber;
-    fn mul(self, other: FiniteNimber) -> FiniteNimber {
-        let aref: FiniteNimberRef = self.into();
-        let bref: FiniteNimberRef = (&other).into();
-        aref * bref
-    }
-}
-
-impl Mul<FiniteNimber> for FiniteNimber {
-    type Output = FiniteNimber;
-    fn mul(self, other: FiniteNimber) -> FiniteNimber {
-        let aref: FiniteNimberRef = (&self).into();
-        let bref: FiniteNimberRef = (&other).into();
-        aref * bref
-    }
-}
+impl_binop_wrappers!(Add, add);
+impl_binop_wrappers!(Mul, mul);
 
 #[cfg(test)]
 mod tests {