src/instance.rs

branch
dev
changeset 152
dab30b331f49
parent 150
c4e394a9c84c
--- 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<X, D = <X as Space>::Decomp>: Sized + Ownable
+pub trait Instance<X, D = <X as Space>::Decomp>:
+    Sized + Ownable<OwnedVariant = X::OwnedSpace>
 where
     X: Space,
     D: Decomposition<X>,
@@ -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<X, BasicDecomposition> 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<X, BasicDecomposition> 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<X, BasicDecomposition> 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`].

mercurial