restrict dev

Thu, 01 May 2025 01:55:57 -0500

author
Tuomo Valkonen <tuomov@iki.fi>
date
Thu, 01 May 2025 01:55:57 -0500
branch
dev
changeset 118
0fabd0b5914c
parent 117
9b782aa6b452
child 119
cc0c6a8d0933

restrict

src/direct_product.rs file | annotate | diff | comparison | revisions
--- a/src/direct_product.rs	Thu May 01 01:31:25 2025 -0500
+++ b/src/direct_product.rs	Thu May 01 01:55:57 2025 -0500
@@ -224,6 +224,9 @@
     };
 }
 
+impl_binary!(Add, add);
+impl_binary!(Sub, sub);
+
 macro_rules! impl_binary_mut {
     ($trait:ident, $fn:ident) => {
         impl<'a, A, B, C, D> $trait<Pair<C, D>> for Pair<A, B>
@@ -252,11 +255,28 @@
     };
 }
 
-impl_binary!(Add, add);
-impl_binary!(Sub, sub);
 impl_binary_mut!(AddAssign, add_assign);
 impl_binary_mut!(SubAssign, sub_assign);
 
+macro_rules! impl_scalar_mut {
+    ($trait:ident, $fn:ident) => {
+        impl<'a, A, B, F> $trait<F> for Pair<A, B>
+        where
+            A: $trait<F>,
+            B: $trait<F>,
+        {
+            fn $fn(&mut self, t: F) {
+                let Pair(ref mut a, ref mut b) = self;
+                a.$fn(t);
+                b.$fn(t);
+            }
+        }
+    };
+}
+
+impl_scalar_mut!(MulAssign, mul_assign);
+impl_scalar_mut!(DivAssign, div_assign);
+
 #[macro_export]
 macro_rules! impl_pair_vectorspace_ops {
     (($a:ty, $b:ty), $field:ty) => {
@@ -270,14 +290,6 @@
         // $(
         //     impl_pair_vectorspace_ops!(@scalar_lhs, ($a, $b), $field, $impl_scalarlhs_op, Mul, mul);
         // )*
-        impl_pair_vectorspace_ops!(@scalar_assign, ($a, $b), $field, MulAssign, mul_assign);
-        impl_pair_vectorspace_ops!(@scalar_assign, ($a, $b), $field, DivAssign, div_assign);
-    };
-    (@binary, ($a : ty, $b : ty), $trait : ident, $fn : ident) => {
-        impl_binop!(($a, $b), $trait, $fn, ref, ref);
-        impl_binop!(($a, $b), $trait, $fn, ref, noref);
-        impl_binop!(($a, $b), $trait, $fn, noref, ref);
-        impl_binop!(($a, $b), $trait, $fn, noref, noref);
     };
     (@scalar, ($a : ty, $b : ty), $field : ty, $trait : ident, $fn :ident) => {
         impl_scalarop!(($a, $b), $field, $trait, $fn, ref);
@@ -305,16 +317,6 @@
         // impl_pair_vectorspace_ops_gen!(@scalar_assign, $field, MulAssign, mul_assign);
         // impl_pair_vectorspace_ops_gen!(@scalar_assign, $field, DivAssign, div_assign);
     };
-    // (@binary, $trait : ident, $fn : ident) => {
-    //     impl_binop_gen!(($a, $b), $trait, $fn, ref, ref);
-    //     impl_binop_gen!(($a, $b), $trait, $fn, ref, noref);
-    //     impl_binop_gen!(($a, $b), $trait, $fn, noref, ref);
-    //     impl_binop_gen!(($a, $b), $trait, $fn, noref, noref);
-    // };
-    // (@assign, $trait : ident, $fn :ident) => {
-    //     impl_assignop_gen!(($a, $b), $trait, $fn, ref);
-    //     impl_assignop_gen!(($a, $b), $trait, $fn, noref);
-    // };
     (@scalar, $field : ty, $trait : ident, $fn :ident) => {
         impl_scalarop_gen!($field, $trait, $fn, ref);
         impl_scalarop_gen!($field, $trait, $fn, noref);
@@ -331,61 +333,48 @@
 impl_pair_vectorspace_ops_gen!(f32);
 impl_pair_vectorspace_ops_gen!(f64);
 
-impl_pair_vectorspace_ops!((f32, f32), f32);
-impl_pair_vectorspace_ops!((f64, f64), f64);
-
-type PairOutput<F, A, B> = Pair<<A as Euclidean<F>>::Output, <B as Euclidean<F>>::Output>;
+//impl_pair_vectorspace_ops!((f32, f32), f32);
+//impl_pair_vectorspace_ops!((f64, f64), f64);
 
 /// We need to restrict `A` and `B` as [`Euclidean`] to have closed `Output`
-/// to avoid compiler overflows that the requirement
-/// ```
-/// Pair<<A as Euclidean<F>>::Output, <B as Euclidean<F>>::Output> : Euclidean<F>
-/// ```
-/// would generate.
 
-macro_rules! impl_euclidean {
-    ($field:ty) => {
-        impl<A, B> Euclidean<$field> for Pair<A, B>
-        where
-            A: Euclidean<$field>,
-            B: Euclidean<$field>,
-            PairOutput<$field, A, B>: Euclidean<$field>,
-            Self: Sized
-                + Mul<$field, Output = PairOutput<$field, A, B>>
-                + MulAssign<$field>
-                + Div<$field, Output = PairOutput<$field, A, B>>
-                + DivAssign<$field>
-                + Add<Self, Output = PairOutput<$field, A, B>>
-                + Sub<Self, Output = PairOutput<$field, A, B>>
-                + for<'b> Add<&'b Self, Output = PairOutput<$field, A, B>>
-                + for<'b> Sub<&'b Self, Output = PairOutput<$field, A, B>>
-                + AddAssign<Self>
-                + for<'b> AddAssign<&'b Self>
-                + SubAssign<Self>
-                + for<'b> SubAssign<&'b Self>, //+ Neg<Output = PairOutput<$field, A, B>>,
-        {
-            type Output = PairOutput<$field, A, B>;
+impl<A, B, F: Float> Euclidean<F> for Pair<A, B>
+where
+    A: Euclidean<F>,
+    B: Euclidean<F>,
+    //Pair<A, B>: Euclidean<F>,
+    Self: Sized
+        + Mul<F, Output = Pair<A, B>>
+        + MulAssign<F>
+        + Div<F, Output = Pair<A, B>>
+        + DivAssign<F>
+        + Add<Self, Output = Pair<A, B>>
+        + Sub<Self, Output = Pair<A, B>>
+        + for<'b> Add<&'b Self, Output = Pair<A, B>>
+        + for<'b> Sub<&'b Self, Output = Pair<A, B>>
+        + AddAssign<Self>
+        + for<'b> AddAssign<&'b Self>
+        + SubAssign<Self>
+        + for<'b> SubAssign<&'b Self>
+        + Neg<Output = Pair<A, B>>,
+{
+    type Output = Pair<A, B>;
 
-            fn dot<I: Instance<Self>>(&self, other: I) -> $field {
-                let Pair(u, v) = other.decompose();
-                self.0.dot(u) + self.1.dot(v)
-            }
-
-            fn norm2_squared(&self) -> $field {
-                self.0.norm2_squared() + self.1.norm2_squared()
-            }
+    fn dot<I: Instance<Self>>(&self, other: I) -> F {
+        let Pair(u, v) = other.decompose();
+        self.0.dot(u) + self.1.dot(v)
+    }
 
-            fn dist2_squared<I: Instance<Self>>(&self, other: I) -> $field {
-                let Pair(u, v) = other.decompose();
-                self.0.dist2_squared(u) + self.1.dist2_squared(v)
-            }
-        }
-    };
+    fn norm2_squared(&self) -> F {
+        self.0.norm2_squared() + self.1.norm2_squared()
+    }
+
+    fn dist2_squared<I: Instance<Self>>(&self, other: I) -> F {
+        let Pair(u, v) = other.decompose();
+        self.0.dist2_squared(u) + self.1.dist2_squared(v)
+    }
 }
 
-impl_euclidean!(f32);
-impl_euclidean!(f64);
-
 impl<F, A, B, U, V> AXPY<F, Pair<U, V>> for Pair<A, B>
 where
     U: Space,

mercurial