diff -r 89371dc4d637 -r 2b13f8a0c8ba src/instance.rs --- a/src/instance.rs Mon May 12 19:30:41 2025 -0500 +++ b/src/instance.rs Mon May 12 20:40:14 2025 -0500 @@ -25,7 +25,10 @@ impl<'b, X> MyCow<'b, X> { #[inline] - pub fn into_owned(self) -> X where X : Clone { + pub fn into_owned(self) -> X + where + X: Clone, + { match self { EitherDecomp::Owned(x) => x, EitherDecomp::Borrowed(x) => x.clone(), @@ -34,9 +37,9 @@ } /// Trait for abitrary mathematical spaces. -pub trait Space : Instance { +pub trait Space: Instance { /// Default decomposition for the space - type Decomp : Decomposition; + type Decomp: Decomposition; } #[macro_export] @@ -58,17 +61,21 @@ f32 f64); /// Marker type for decompositions to be used with [`Instance`]. -pub trait Decomposition : Sized { +pub trait Decomposition: Sized { /// Possibly owned form of the decomposition - type Decomposition<'b> : Instance where X : 'b; + type Decomposition<'b>: Instance + where + X: 'b; /// Unlikely owned form of the decomposition. /// Type for a lightweight intermediate conversion that does not own the original variable. /// Usually this is just a reference, but may also be a lightweight structure that /// contains references; see the implementation for [`crate::direct_product::Pair`]. - type Reference<'b> : Instance + Copy where X : 'b; + type Reference<'b>: Instance + Copy + where + X: 'b; /// Left the lightweight reference type into a full decomposition type. - fn lift<'b>(r : Self::Reference<'b>) -> Self::Decomposition<'b>; + fn lift<'b>(r: Self::Reference<'b>) -> Self::Decomposition<'b>; } /// Most common [`Decomposition`] (into `Either`) that allows working with owned @@ -76,12 +83,18 @@ #[derive(Copy, Clone, Debug)] pub struct BasicDecomposition; -impl Decomposition for BasicDecomposition { - type Decomposition<'b> = MyCow<'b, X> where X : 'b; - type Reference<'b> = &'b X where X : 'b; +impl Decomposition for BasicDecomposition { + type Decomposition<'b> + = MyCow<'b, X> + where + X: 'b; + type Reference<'b> + = &'b X + where + X: 'b; #[inline] - fn lift<'b>(r : Self::Reference<'b>) -> Self::Decomposition<'b> { + fn lift<'b>(r: Self::Reference<'b>) -> Self::Decomposition<'b> { MyCow::Borrowed(r) } } @@ -91,13 +104,23 @@ /// generalises [`std::borrow::ToOwned`], [`std::borrow::Borrow`], and [`std::borrow::Cow`]. /// /// This is used, for example, by [`crate::mapping::Mapping::apply`]. -pub trait Instance::Decomp> : Sized where D : Decomposition { - /// Decomposes self according to `decomposer`. - fn decompose<'b>(self) -> D::Decomposition<'b> - where Self : 'b, X : 'b; - - /// Returns a lightweight instance of `self`. - fn ref_instance(&self) -> D::Reference<'_>; +pub trait Instance::Decomp>: Sized +where + D: Decomposition, +{ + /// Decomposes self according to `decomposer`, and evaluate `f` on the result. + /// Consumes self. + fn eval_decompose<'b, R>(self, f: impl FnOnce(D::Decomposition<'b>) -> R) -> R + where + X: 'b, + Self: 'b; + + /// Does a light decomposition of self `decomposer`, and evaluates `f` on the result. + /// Does not consume self. + fn eval_ref_decompose<'b, R>(&'b self, f: impl FnOnce(D::Reference<'b>) -> R) -> R + where + X: 'b, + Self: 'b; /// Returns an owned instance of `X`, cloning or converting non-true instances when necessary. fn own(self) -> X; @@ -107,16 +130,21 @@ /// Returns an owned instance or reference to `X`, converting non-true instances when necessary. /// /// Default implementation uses [`Self::own`]. Consumes the input. - fn cow<'b>(self) -> MyCow<'b, X> where Self : 'b { + fn cow<'b>(self) -> MyCow<'b, X> + where + Self: 'b, + { MyCow::Owned(self.own()) } - + #[inline] /// Evaluates `f` on a reference to self. /// /// Default implementation uses [`Self::cow`]. Consumes the input. - fn eval<'b, R>(self, f : impl FnOnce(&X) -> R) -> R - where X : 'b, Self : 'b + fn eval<'b, R>(self, f: impl FnOnce(&X) -> R) -> R + where + X: 'b, + Self: 'b, { f(&*self.cow()) } @@ -125,12 +153,9 @@ /// Evaluates `f` or `g` depending on whether a reference or owned value is available. /// /// Default implementation uses [`Self::cow`]. Consumes the input. - fn either<'b, R>( - self, - f : impl FnOnce(X) -> R, - g : impl FnOnce(&X) -> R - ) -> R - where Self : 'b + fn either<'b, R>(self, f: impl FnOnce(X) -> R, g: impl FnOnce(&X) -> R) -> R + where + Self: 'b, { match self.cow() { EitherDecomp::Owned(x) => f(x), @@ -139,13 +164,23 @@ } } - -impl Instance for X { +impl Instance for X { #[inline] - fn decompose<'b>(self) -> >::Decomposition<'b> - where Self : 'b, X : 'b + fn eval_decompose<'b, R>(self, f: impl FnOnce(MyCow<'b, X>) -> R) -> R + where + X: 'b, + Self: 'b, { - MyCow::Owned(self) + f(MyCow::Owned(self)) + } + + #[inline] + fn eval_ref_decompose<'b, R>(&'b self, f: impl FnOnce(&'b X) -> R) -> R + where + X: 'b, + Self: 'b, + { + f(self) } #[inline] @@ -154,22 +189,31 @@ } #[inline] - fn cow<'b>(self) -> MyCow<'b, X> where Self : 'b { + fn cow<'b>(self) -> MyCow<'b, X> + where + Self: 'b, + { MyCow::Owned(self) } +} + +impl<'a, X: Space + Clone> Instance for &'a X { + #[inline] + fn eval_decompose<'b, R>(self, f: impl FnOnce(MyCow<'b, X>) -> R) -> R + where + X: 'b, + Self: 'b, + { + f(MyCow::Borrowed(self)) + } #[inline] - fn ref_instance(&self) -> >::Reference<'_> { - self - } -} - -impl<'a, X : Space + Clone> Instance for &'a X { - #[inline] - fn decompose<'b>(self) -> >::Decomposition<'b> - where Self : 'b, X : 'b + fn eval_ref_decompose<'b, R>(&'b self, f: impl FnOnce(&'b X) -> R) -> R + where + X: 'b, + Self: 'b, { - MyCow::Borrowed(self) + f(*self) } #[inline] @@ -178,22 +222,31 @@ } #[inline] - fn cow<'b>(self) -> MyCow<'b, X> where Self : 'b { + fn cow<'b>(self) -> MyCow<'b, X> + where + Self: 'b, + { MyCow::Borrowed(self) } +} + +impl<'a, X: Space + Clone> Instance for &'a mut X { + #[inline] + fn eval_decompose<'b, R>(self, f: impl FnOnce(MyCow<'b, X>) -> R) -> R + where + X: 'b, + Self: 'b, + { + f(EitherDecomp::Borrowed(self)) + } #[inline] - fn ref_instance(&self) -> >::Reference<'_> { - *self - } -} - -impl<'a, X : Space + Clone> Instance for &'a mut X { - #[inline] - fn decompose<'b>(self) -> >::Decomposition<'b> - where Self : 'b, X : 'b + fn eval_ref_decompose<'b, R>(&'b self, f: impl FnOnce(&'b X) -> R) -> R + where + X: 'b, + Self: 'b, { - EitherDecomp::Borrowed(self) + f(*self) } #[inline] @@ -202,81 +255,95 @@ } #[inline] - fn cow<'b>(self) -> MyCow<'b, X> where Self : 'b, X : Clone { + fn cow<'b>(self) -> MyCow<'b, X> + where + Self: 'b, + X: Clone, + { EitherDecomp::Borrowed(self) } +} + +impl<'a, X: Space + Clone> Instance for MyCow<'a, X> { + #[inline] + fn eval_decompose<'b, R>(self, f: impl FnOnce(MyCow<'b, X>) -> R) -> R + where + X: 'b, + Self: 'b, + { + f(self) + } #[inline] - fn ref_instance(&self) -> >::Reference<'_> { - *self - } -} - -impl<'a, X : Space + Clone> Instance for MyCow<'a, X> { - - #[inline] - fn decompose<'b>(self) -> >::Decomposition<'b> - where Self : 'b, X : 'b + fn eval_ref_decompose<'b, R>(&'b self, f: impl FnOnce(&'b X) -> R) -> R + where + X: 'b, + Self: 'b, { - self + match self { + MyCow::Borrowed(a) => f(a), + MyCow::Owned(b) => f(&b), + } } #[inline] fn own(self) -> X { match self { MyCow::Borrowed(a) => a.own(), - MyCow::Owned(b) => b.own() + MyCow::Owned(b) => b.own(), } } #[inline] - fn cow<'b>(self) -> MyCow<'b, X> where Self : 'b { + fn cow<'b>(self) -> MyCow<'b, X> + where + Self: 'b, + { match self { MyCow::Borrowed(a) => a.cow(), - MyCow::Owned(b) => b.cow() - } - } - - #[inline] - fn ref_instance(&self) -> >::Reference<'_> { - match self { - MyCow::Borrowed(a) => a, - MyCow::Owned(b) => &b, + MyCow::Owned(b) => b.cow(), } } } /// Marker type for mutable decompositions to be used with [`InstanceMut`]. -pub trait DecompositionMut : Sized { - type ReferenceMut<'b> : InstanceMut where X : 'b; +pub trait DecompositionMut: Sized { + type ReferenceMut<'b>: InstanceMut + where + X: 'b; } - /// Helper trait for functions to work with mutable references. -pub trait InstanceMut::Decomp> : Sized where D : DecompositionMut { +pub trait InstanceMut::Decomp>: Sized +where + D: DecompositionMut, +{ /// Returns a mutable decomposition of self. fn ref_instance_mut(&mut self) -> D::ReferenceMut<'_>; } -impl DecompositionMut for BasicDecomposition { - type ReferenceMut<'b> = &'b mut X where X : 'b; +impl DecompositionMut for BasicDecomposition { + type ReferenceMut<'b> + = &'b mut X + where + X: 'b; } /// This impl may seem pointless, but allows throwaway mutable scratch variables -impl<'a, X : Space> InstanceMut for X { +impl<'a, X: Space> InstanceMut for X { #[inline] - fn ref_instance_mut(&mut self) - -> >::ReferenceMut<'_> - { + fn ref_instance_mut( + &mut self, + ) -> >::ReferenceMut<'_> { self } } -impl<'a, X : Space> InstanceMut for &'a mut X { +impl<'a, X: Space> InstanceMut for &'a mut X { #[inline] - fn ref_instance_mut(&mut self) - -> >::ReferenceMut<'_> - { + fn ref_instance_mut( + &mut self, + ) -> >::ReferenceMut<'_> { self } }