chiark / gitweb /
Implement compound assignment operators.
authorSimon Tatham <anakin@pobox.com>
Sat, 12 Apr 2025 09:44:20 +0000 (10:44 +0100)
committerSimon Tatham <anakin@pobox.com>
Sat, 12 Apr 2025 09:44:20 +0000 (10:44 +0100)
examples/a382121.rs
src/finitenimber.rs

index 967f665b526d4db54e37d58352c19c0f7567357c..1159fc1d15c14d7a1b94df86213e0756339b84e7 100644 (file)
@@ -3,7 +3,7 @@ use std::borrow::Borrow;
 use std::collections::hash_map::Entry;
 use std::collections::HashMap;
 use std::fmt::{Display, Formatter};
-use std::ops::Add;
+use std::ops::AddAssign;
 
 use nimber::{FiniteNimber, Word};
 
@@ -36,17 +36,15 @@ impl Polynomial {
     }
 }
 
-impl Add<&Polynomial> for Polynomial {
-    type Output = Polynomial;
-
-    fn add(self, other: &Polynomial) -> Self {
-        Self(
-            self.0
-                .into_iter()
-                .zip_longest(other.0.iter().cloned())
-                .map(|pair| pair.reduce(|a, b| a ^ b))
-                .collect(),
-        )
+impl AddAssign<&Polynomial> for Polynomial {
+    fn add_assign(&mut self, other: &Polynomial) {
+        self.0 = self
+            .0
+            .iter()
+            .cloned()
+            .zip_longest(other.0.iter().cloned())
+            .map(|pair| pair.reduce(|a, b| a ^ b))
+            .collect();
     }
 }
 
@@ -87,8 +85,8 @@ fn minimal_polynomial(n: &FiniteNimber) -> Polynomial {
             match map.entry(bit) {
                 Entry::Occupied(e) => {
                     let e: &(FiniteNimber, Polynomial) = e.get();
-                    val = val + &e.0;
-                    comb = comb + &e.1;
+                    val += &e.0;
+                    comb += &e.1;
                 }
                 Entry::Vacant(e) => {
                     e.insert((val.clone(), comb));
@@ -96,7 +94,7 @@ fn minimal_polynomial(n: &FiniteNimber) -> Polynomial {
                 }
             }
         }
-        power = power * n;
+        power *= n;
         exp += 1;
     }
 }
index 84bbb4c904f3f447b9edc37a7aaa3e464ab9e769..42c67a97f6cb3c66a0c213ced24164e06e75a7f3 100644 (file)
@@ -242,7 +242,7 @@ impl From<&[Word]> for FiniteNimber {
 }
 
 macro_rules! impl_binop_wrappers {
-    ($trait:tt, $fn:ident) => {
+    ($trait:tt, $fn:ident, $assigntrait:tt, $assignfn:ident) => {
         impl $trait<FiniteNimberRef<'_>> for FiniteNimber {
             type Output = FiniteNimber;
             fn $fn(self, other: FiniteNimberRef<'_>) -> FiniteNimber {
@@ -296,6 +296,22 @@ macro_rules! impl_binop_wrappers {
                 $trait::$fn(aref, bref)
             }
         }
+
+        impl core::ops::$assigntrait<&FiniteNimber> for FiniteNimber {
+            fn $assignfn(&mut self, other: &FiniteNimber) {
+                let aref: FiniteNimberRef = (&self as &FiniteNimber).into();
+                let bref: FiniteNimberRef = other.into();
+                *self = $trait::$fn(aref, bref);
+            }
+        }
+
+        impl core::ops::$assigntrait<FiniteNimber> for FiniteNimber {
+            fn $assignfn(&mut self, other: FiniteNimber) {
+                let aref: FiniteNimberRef = (&self as &FiniteNimber).into();
+                let bref: FiniteNimberRef = (&other).into();
+                *self = $trait::$fn(aref, bref);
+            }
+        }
     };
 }
 
@@ -372,9 +388,9 @@ impl<'a, 'b> Mul<FiniteNimberRef<'a>> for FiniteNimberRef<'b> {
     }
 }
 
-impl_binop_wrappers!(Add, add);
-impl_binop_wrappers!(Sub, sub);
-impl_binop_wrappers!(Mul, mul);
+impl_binop_wrappers!(Add, add, AddAssign, add_assign);
+impl_binop_wrappers!(Sub, sub, SubAssign, sub_assign);
+impl_binop_wrappers!(Mul, mul, MulAssign, mul_assign);
 
 #[cfg(test)]
 mod tests {
@@ -548,11 +564,15 @@ mod tests {
             9
         );
         assert_eq!(
-            FiniteNimber::from(vec![1, 1, 1, 1, 1, 1, 1, 1]).to_ref().level(),
+            FiniteNimber::from(vec![1, 1, 1, 1, 1, 1, 1, 1])
+                .to_ref()
+                .level(),
             9
         );
         assert_eq!(
-            FiniteNimber::from(vec![1, 1, 1, 1, 1, 1, 1, 1, 1]).to_ref().level(),
+            FiniteNimber::from(vec![1, 1, 1, 1, 1, 1, 1, 1, 1])
+                .to_ref()
+                .level(),
             10
         );
     }