From: Simon Tatham Date: Fri, 11 Apr 2025 18:18:29 +0000 (+0100) Subject: Hide some of the boring boilerplate. X-Git-Url: https://www.chiark.greenend.org.uk/ucgi/~ian/git?a=commitdiff_plain;h=6c65e9afc6e1d86b040296ffcf6f018f1f3bc0ed;p=nimber.git Hide some of the boring boilerplate. --- diff --git a/src/finitenimber.rs b/src/finitenimber.rs index 7197401..82a2ec9 100644 --- a/src/finitenimber.rs +++ b/src/finitenimber.rs @@ -198,6 +198,64 @@ impl From for FiniteNimber { } } +macro_rules! impl_binop_wrappers { + ($trait:tt, $fn:ident) => { + impl $trait> 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 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 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 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> for FiniteNimberRef<'b> { type Output = FiniteNimber; fn add(self, other: FiniteNimberRef<'a>) -> FiniteNimber { @@ -211,42 +269,6 @@ impl<'a, 'b> Add> 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 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 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> 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> 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 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 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 {