diff -r 402d717bb5c0 -r dab30b331f49 src/instance.rs --- a/src/instance.rs Mon Sep 01 20:55:34 2025 -0500 +++ b/src/instance.rs Mon Sep 01 23:03:27 2025 -0500 @@ -24,7 +24,7 @@ } /// Trait for ownable-by-consumption objects -pub trait Ownable { +pub trait Ownable: Sized { type OwnedVariant: Clone; /// Returns an owned instance, possibly consuming the original, @@ -33,22 +33,45 @@ /// Returns an owned instance of a reference. fn clone_owned(&self) -> Self::OwnedVariant; + + /// Returns either an owned instance or a reference to one + fn owned_cow<'b>(self) -> MyCow<'b, Self::OwnedVariant> + where + Self: 'b; + + /// Returns either an owned instance or a reference to one, preferring a reference. + fn ref_owned_cow<'b>(&'b self) -> MyCow<'b, Self::OwnedVariant> + where + Self: 'b; } impl<'a, X: Ownable> Ownable for &'a X { type OwnedVariant = X::OwnedVariant; #[inline] - /// Returns an owned instance. fn into_owned(self) -> Self::OwnedVariant { self.clone_owned() } #[inline] - /// Returns an owned instance. fn clone_owned(&self) -> Self::OwnedVariant { (*self).into_owned() } + + fn owned_cow<'b>(self) -> MyCow<'b, Self::OwnedVariant> + where + Self: 'b, + { + (*self).ref_owned_cow() + } + + #[inline] + fn ref_owned_cow<'b>(&'b self) -> MyCow<'b, Self::OwnedVariant> + where + Self: 'b, + { + (*self).ref_owned_cow() + } } impl<'a, X: Ownable> Ownable for &'a mut X { @@ -65,6 +88,21 @@ fn clone_owned(&self) -> Self::OwnedVariant { (&**self).into_owned() } + + fn owned_cow<'b>(self) -> MyCow<'b, Self::OwnedVariant> + where + Self: 'b, + { + (&*self).ref_owned_cow() + } + + #[inline] + fn ref_owned_cow<'b>(&'b self) -> MyCow<'b, Self::OwnedVariant> + where + Self: 'b, + { + (&**self).ref_owned_cow() + } } impl<'a, X: Ownable> Ownable for MyCow<'a, X> { @@ -87,6 +125,24 @@ EitherDecomp::Borrowed(x) => x.into_owned(), } } + + fn owned_cow<'b>(self) -> MyCow<'b, Self::OwnedVariant> + where + Self: 'b, + { + match self { + EitherDecomp::Owned(x) => x.owned_cow(), + EitherDecomp::Borrowed(x) => x.ref_owned_cow(), + } + } + + #[inline] + fn ref_owned_cow<'b>(&'b self) -> MyCow<'b, Self::OwnedVariant> + where + Self: 'b, + { + (&**self).ref_owned_cow() + } } /// Trait for abitrary mathematical spaces. @@ -134,6 +190,16 @@ fn clone_owned(&self) -> Self::OwnedVariant { *self } + + #[inline] + fn owned_cow<'b>(self) -> MyCow<'b, Self::OwnedVariant> where Self : 'b { + EitherDecomp::Owned(self) + } + + #[inline] + fn ref_owned_cow<'b>(&'b self) -> MyCow<'b, Self::OwnedVariant> where Self : 'b{ + EitherDecomp::Owned(*self) + } } }; } @@ -186,7 +252,8 @@ /// 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 + Ownable +pub trait Instance::Decomp>: + Sized + Ownable where X: Space, D: Decomposition, @@ -205,26 +272,40 @@ X: 'b, Self: 'b; + // fn eval_<'b, R>( + // &'b self, + // _f: impl FnOnce(D::Decomposition<'b>) -> R, + // g: impl FnOnce(D::Reference<'b>) -> R, + // ) -> R + // where + // X: 'b, + // Self: 'b, + // { + // self.eval_ref_decompose(g) + // } + /// Returns an owned instance of `X`, cloning or converting non-true instances when necessary. - fn own(self) -> X; + fn own(self) -> X::OwnedSpace { + self.into_owned() + } // ************** automatically implemented methods below from here ************** /// 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> + fn cow<'b>(self) -> MyCow<'b, X::OwnedSpace> where Self: 'b, { - MyCow::Owned(self.own()) + self.owned_cow() } #[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 + fn eval<'b, R>(self, f: impl FnOnce(&X::OwnedSpace) -> R) -> R where X: 'b, Self: 'b, @@ -236,7 +317,11 @@ /// 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 + fn either<'b, R>( + self, + f: impl FnOnce(X::OwnedSpace) -> R, + g: impl FnOnce(&X::OwnedSpace) -> R, + ) -> R where Self: 'b, { @@ -265,19 +350,6 @@ { f(self) } - - #[inline] - fn own(self) -> X { - self - } - - #[inline] - fn cow<'b>(self) -> MyCow<'b, X> - where - Self: 'b, - { - MyCow::Owned(self) - } } impl<'a, X: Space> Instance for &'a X { @@ -298,19 +370,6 @@ { f(*self) } - - #[inline] - fn own(self) -> X { - self.into_owned() - } - - #[inline] - fn cow<'b>(self) -> MyCow<'b, X> - where - Self: 'b, - { - MyCow::Borrowed(self) - } } impl<'a, X: Space> Instance for &'a mut X { @@ -331,19 +390,6 @@ { f(*self) } - - #[inline] - fn own(self) -> X { - self.into_owned() - } - - #[inline] - fn cow<'b>(self) -> MyCow<'b, X> - where - Self: 'b, - { - EitherDecomp::Borrowed(self) - } } impl<'a, X: Space> Instance for MyCow<'a, X> { @@ -367,25 +413,6 @@ MyCow::Owned(b) => f(&b), } } - - #[inline] - fn own(self) -> X { - match self { - MyCow::Borrowed(a) => a.own(), - MyCow::Owned(b) => b.own(), - } - } - - #[inline] - fn cow<'b>(self) -> MyCow<'b, X> - where - Self: 'b, - { - match self { - MyCow::Borrowed(a) => a.cow(), - MyCow::Owned(b) => b.cow(), - } - } } /// Marker type for mutable decompositions to be used with [`InstanceMut`].