# HG changeset patch # User Tuomo Valkonen # Date 1746083390 18000 # Node ID cc0c6a8d0933d11e908bf9895623646a27319407 # Parent 0fabd0b5914c528b5aecdcb35f31b66cf70647fc simplify diff -r 0fabd0b5914c -r cc0c6a8d0933 src/direct_product.rs --- a/src/direct_product.rs Thu May 01 01:55:57 2025 -0500 +++ b/src/direct_product.rs Thu May 01 02:09:50 2025 -0500 @@ -39,109 +39,6 @@ } } -// macro_rules! impl_scalarop { -// (($a : ty, $b : ty), $field : ty, $trait : ident, $fn : ident, $refl:ident) => { -// impl_scalarop!(@doit: $field, -// $trait, $fn; -// maybe_lifetime!($refl, &'l Pair<$a,$b>), -// (maybe_lifetime!($refl, &'l $a), -// maybe_lifetime!($refl, &'l $b)); -// $refl); -// }; -// (@doit: $field : ty, -// $trait:ident, $fn:ident; -// $self:ty, ($aself:ty, $bself:ty); -// $refl:ident) => { -// // Scalar as Rhs -// impl<'l> $trait<$field> -// for $self -// where $aself: $trait<$field>, -// $bself: $trait<$field> { -// type Output = Pair<<$aself as $trait<$field>>::Output, -// <$bself as $trait<$field>>::Output>; -// #[inline] -// fn $fn(self, a : $field) -> Self::Output { -// Pair(maybe_ref!($refl, self.0).$fn(a), -// maybe_ref!($refl, self.1).$fn(a)) -// } -// } -// } -// } -// - -macro_rules! impl_scalarop_gen { - ($field : ty, $trait : ident, $fn : ident, $refl:ident) => { - impl_scalarop_gen!(@doit: $field, - $trait, $fn; - maybe_lifetime!($refl, &'l Pair), - (maybe_lifetime!($refl, &'l A), - maybe_lifetime!($refl, &'l B)); - $refl); - }; - (@doit: $field : ty, - $trait:ident, $fn:ident; - $self:ty, ($aself:ty, $bself:ty); - $refl:ident) => { - // Scalar as Rhs - impl<'l, A, B> $trait<$field> - for $self - where $aself: $trait<$field>, - $bself: $trait<$field> { - type Output = Pair<<$aself as $trait<$field>>::Output, - <$bself as $trait<$field>>::Output>; - #[inline] - fn $fn(self, a : $field) -> Self::Output { - Pair(maybe_ref!($refl, self.0).$fn(a), - maybe_ref!($refl, self.1).$fn(a)) - } - } - } -} - -// Not used due to compiler overflow -#[allow(unused_macros)] -macro_rules! impl_scalarlhs_op { - (($a : ty, $b : ty), $field : ty, $trait:ident, $fn:ident, $refr:ident) => { - impl_scalarlhs_op!(@doit: $trait, $fn, - maybe_lifetime!($refr, &'r Pair<$a,$b>), - (maybe_lifetime!($refr, &'r $a), - maybe_lifetime!($refr, &'r $b)); - $refr, $field); - }; - (@doit: $trait:ident, $fn:ident, - $in:ty, ($ain:ty, $bin:ty); - $refr:ident, $field:ty) => { - impl<'r> $trait<$in> - for $field - where $field : $trait<$ain> - + $trait<$bin> { - type Output = Pair<<$field as $trait<$ain>>::Output, - <$field as $trait<$bin>>::Output>; - #[inline] - fn $fn(self, x : $in) -> Self::Output { - Pair(self.$fn(maybe_ref!($refr, x.0)), - self.$fn(maybe_ref!($refr, x.1))) - } - } - }; -} - -macro_rules! impl_scalar_assignop { - (($a : ty, $b : ty), $field : ty, $trait : ident, $fn : ident) => { - impl<'r> $trait<$field> for Pair<$a, $b> - where - $a: $trait<$field>, - $b: $trait<$field>, - { - #[inline] - fn $fn(&mut self, a: $field) -> () { - self.0.$fn(a); - self.1.$fn(a); - } - } - }; -} - macro_rules! impl_unary { ($trait:ident, $fn:ident) => { impl $trait for Pair @@ -227,6 +124,93 @@ impl_binary!(Add, add); impl_binary!(Sub, sub); +macro_rules! impl_scalar { + ($trait:ident, $fn:ident, $F:ty) => { + impl $trait<$F> for Pair + where + A: $trait<$F>, + B: $trait<$F>, + { + type Output = Pair; + fn $fn(self, t: $F) -> Self::Output { + let Pair(a, b) = self; + Pair(a.$fn(t), b.$fn(t)) + } + } + + impl<'a, A, B> $trait<$F> for &'a Pair + where + &'a A: $trait<$F>, + &'a B: $trait<$F>, + { + type Output = Pair<<&'a A as $trait<$F>>::Output, <&'a B as $trait<$F>>::Output>; + fn $fn(self, t: $F) -> Self::Output { + let Pair(ref a, ref b) = self; + Pair(a.$fn(t), b.$fn(t)) + } + } + + // impl<'a, 'b, A, B> $trait<&'b $F> for &'a Pair + // where + // &'a A: $trait<&'b $F>, + // &'a B: $trait<&'b $F>, + // { + // type Output = + // Pair<<&'a A as $trait<&'b $F>>::Output, <&'a B as $trait<&'b $F>>::Output>; + // fn $fn(self, t: &'b $F) -> Self::Output { + // let Pair(ref a, ref b) = self; + // Pair(a.$fn(t), b.$fn(t)) + // } + // } + + // impl<'b, A, B> $trait<&'b $F> for Pair + // where + // A: $trait<&'b $F>, + // B: $trait<&'b $F>, + // { + // type Output = Pair<>::Output, >::Output>; + // fn $fn(self, t: &'b $F) -> Self::Output { + // let Pair(a, b) = self; + // Pair(a.$fn(t), b.$fn(t)) + // } + // } + }; +} + +impl_scalar!(Mul, mul, f32); +impl_scalar!(Mul, mul, f64); +impl_scalar!(Sub, sub, f32); +impl_scalar!(Sub, sub, f64); + +macro_rules! impl_scalar_lhs { + ($trait:ident, $fn:ident, $F:ty) => { + impl $trait> for $F + where + $F: $trait + $trait, + { + type Output = Pair<<$F as $trait>::Output, <$F as $trait>::Output>; + fn $fn(self, Pair(a, b): Pair) -> Self::Output { + Pair(self.$fn(a), self.$fn(b)) + } + } + + // Compiler overflow: + // + // impl<'a, A, B> $trait<&'a Pair> for $F + // where + // $F: $trait<&'a A> + $trait<&'a B>, + // { + // type Output = Pair<<$F as $trait<&'a A>>::Output, <$F as $trait<&'a B>>::Output>; + // fn $fn(self, Pair(a, b): &'a Pair) -> Self::Output { + // Pair(self.$fn(a), self.$fn(b)) + // } + // } + }; +} + +impl_scalar_lhs!(Mul, mul, f32); +impl_scalar_lhs!(Mul, mul, f64); + macro_rules! impl_binary_mut { ($trait:ident, $fn:ident) => { impl<'a, A, B, C, D> $trait> for Pair @@ -259,13 +243,13 @@ impl_binary_mut!(SubAssign, sub_assign); macro_rules! impl_scalar_mut { - ($trait:ident, $fn:ident) => { - impl<'a, A, B, F> $trait for Pair + ($trait:ident, $fn:ident, $F:ty) => { + impl<'a, A, B> $trait<$F> for Pair where - A: $trait, - B: $trait, + A: $trait<$F>, + B: $trait<$F>, { - fn $fn(&mut self, t: F) { + fn $fn(&mut self, t: $F) { let Pair(ref mut a, ref mut b) = self; a.$fn(t); b.$fn(t); @@ -274,70 +258,13 @@ }; } -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) => { - //impl_pair_vectorspace_ops!(@binary, ($a, $b), Add, add); - //impl_pair_vectorspace_ops!(@binary, ($a, $b), Sub, sub); - //impl_pair_vectorspace_ops!(@assign, ($a, $b), AddAssign, add_assign); - //impl_pair_vectorspace_ops!(@assign, ($a, $b), SubAssign, sub_assign); - // impl_pair_vectorspace_ops!(@scalar, ($a, $b), $field, Mul, mul); - // impl_pair_vectorspace_ops!(@scalar, ($a, $b), $field, Div, div); - // Compiler overflow - // $( - // impl_pair_vectorspace_ops!(@scalar_lhs, ($a, $b), $field, $impl_scalarlhs_op, Mul, mul); - // )* - }; - (@scalar, ($a : ty, $b : ty), $field : ty, $trait : ident, $fn :ident) => { - impl_scalarop!(($a, $b), $field, $trait, $fn, ref); - impl_scalarop!(($a, $b), $field, $trait, $fn, noref); - }; - (@scalar_lhs, ($a : ty, $b : ty), $field : ty, $trait : ident, $fn : ident) => { - impl_scalarlhs_op!(($a, $b), $field, $trait, $fn, ref); - impl_scalarlhs_op!(($a, $b), $field, $trait, $fn, noref); - }; - (@scalar_assign, ($a : ty, $b : ty), $field : ty, $trait : ident, $fn : ident) => { - impl_scalar_assignop!(($a, $b), $field, $trait, $fn); - }; -} +impl_scalar_mut!(MulAssign, mul_assign, f32); +impl_scalar_mut!(MulAssign, mul_assign, f64); +impl_scalar_mut!(DivAssign, div_assign, f32); +impl_scalar_mut!(DivAssign, div_assign, f64); -// TODO: add what we can here. -#[macro_export] -macro_rules! impl_pair_vectorspace_ops_gen { - ($field:ty) => { - // impl_pair_vectorspace_ops_gen!(@binary, Add, add); - // impl_pair_vectorspace_ops_gen!(@binary, Sub, sub); - // impl_pair_vectorspace_ops_gen!(@assign, AddAssign, add_assign); - // impl_pair_vectorspace_ops_gen!(@assign, SubAssign, sub_assign); - impl_pair_vectorspace_ops_gen!(@scalar, $field, Mul, mul); - impl_pair_vectorspace_ops_gen!(@scalar, $field, Div, div); - // impl_pair_vectorspace_ops_gen!(@scalar_assign, $field, MulAssign, mul_assign); - // impl_pair_vectorspace_ops_gen!(@scalar_assign, $field, DivAssign, div_assign); - }; - (@scalar, $field : ty, $trait : ident, $fn :ident) => { - impl_scalarop_gen!($field, $trait, $fn, ref); - impl_scalarop_gen!($field, $trait, $fn, noref); - }; - // (@scalar_lhs, $field : ty, $trait : ident, $fn : ident) => { - // impl_scalarlhs_op_gen!(($a, $b), $field, $trait, $fn, ref); - // impl_scalarlhs_op_gen!(($a, $b), $field, $trait, $fn, noref); - // }; - // (@scalar_assign, $field : ty, $trait : ident, $fn : ident) => { - // impl_scalar_assignop_gen!(($a, $b), $field, $trait, $fn); - // }; -} - -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); - -/// We need to restrict `A` and `B` as [`Euclidean`] to have closed `Output` - +/// We only support 'closed' `Euclidean` `Pair`s, as more general ones cause +/// compiler overflows. impl Euclidean for Pair where A: Euclidean, diff -r 0fabd0b5914c -r cc0c6a8d0933 src/lib.rs --- a/src/lib.rs Thu May 01 01:55:57 2025 -0500 +++ b/src/lib.rs Thu May 01 02:09:50 2025 -0500 @@ -20,7 +20,6 @@ )] #[macro_use] -pub(crate) mod metaprogramming; pub mod collection; pub mod error; pub mod euclidean; diff -r 0fabd0b5914c -r cc0c6a8d0933 src/metaprogramming.rs --- a/src/metaprogramming.rs Thu May 01 01:55:57 2025 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,54 +0,0 @@ -/*! -Metaprogramming tools -*/ - -/// Reference `x` if so indicated by the first parameter. -/// Typically to be used from another macro. -/// -/// ```ignore -/// maybe_ref!(ref, V) // ➡ &V -/// maybe_ref!(noref, V) // ➡ V -/// ``` -macro_rules! maybe_ref { - (ref, $x:expr) => { - &$x - }; - (noref, $x:expr) => { - $x - }; - (ref, $x:ty) => { - &$x - }; - (noref, $x:ty) => { - $x - }; -} - -/// Choose `a` if first argument is the literal `ref`, otherwise `b`. -// macro_rules! ifref { -// (noref, $a:expr, $b:expr) => { -// $b -// }; -// (ref, $a:expr, $b:expr) => { -// $a -// }; -// } - -/// Annotate `x` with a lifetime if the first parameter -/// Typically to be used from another macro. -/// -/// ```ignore -/// maybe_ref!(ref, &'a V) // ➡ &'a V -/// maybe_ref!(noref, &'a V) // ➡ V -/// ``` -macro_rules! maybe_lifetime { - (ref, $x:ty) => { - $x - }; - (noref, &$lt:lifetime $x:ty) => { - $x - }; - (noref, &$x:ty) => { - $x - }; -}