src/instance.rs

branch
dev
changeset 137
d5dfcb6abcf5
parent 136
22fd33834ab7
--- a/src/instance.rs	Mon May 12 21:56:42 2025 -0500
+++ b/src/instance.rs	Mon May 12 22:48:16 2025 -0500
@@ -80,6 +80,32 @@
         X: 'b;
 }
 
+pub trait Instantiated<X: Space, D = <X as Space>::Decomp>: Instance<X, D>
+where
+    D: Decomposition<X>,
+{
+    type RefInstance<'b>: Instance<X, D> + Copy
+    where
+        Self: 'b;
+
+    fn ref_inst(&self) -> Self::RefInstance<'_>;
+}
+
+impl<X: Space> Instantiated<X, BasicDecomposition> for X
+where
+    X: Instance<X, BasicDecomposition> + Clone,
+    for<'b> &'b X: Instance<X, BasicDecomposition>,
+{
+    type RefInstance<'b>
+        = &'b X
+    where
+        Self: 'b;
+
+    fn ref_inst(&self) -> Self::RefInstance<'_> {
+        self
+    }
+}
+
 /// Helper trait for functions to work with either owned values or references to either the
 /// “principal type” `X` or types some present a subset of `X`. In the latter sense, this
 /// generalises [`std::borrow::ToOwned`], [`std::borrow::Borrow`], and [`std::borrow::Cow`].
@@ -89,6 +115,8 @@
 where
     D: Decomposition<X>,
 {
+    type Instantiated: Space + Instantiated<X, D>;
+
     /// 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
@@ -106,8 +134,23 @@
     /// Returns an owned instance of `X`, cloning or converting non-true instances when necessary.
     fn own(self) -> X;
 
+    /// Instantiate to something that can be 'referenced'.
+    ///
+    /// This is distinct from [`own`], as it is not guaranteed that `&'b X` is an
+    /// [`Instance`] of `X`.
+    fn instantiate(self) -> Self::Instantiated;
+
     // ************** automatically implemented methods below from here **************
 
+    /// Evaluate `f` on the result of [`instantiate`]ing self, and then referencing.
+    fn eval_inst_ref<R>(
+        self,
+        f: impl for<'b> FnOnce(<Self::Instantiated as Instantiated<X, D>>::RefInstance<'b>) -> R,
+    ) -> R {
+        let inst = self.instantiate();
+        f(inst.ref_inst())
+    }
+
     /// Returns an owned instance or reference to `X`, converting non-true instances when necessary.
     ///
     /// Default implementation uses [`Self::own`]. Consumes the input.
@@ -146,6 +189,12 @@
 }
 
 impl<X: Space + Clone> Instance<X, BasicDecomposition> for X {
+    type Instantiated = X;
+
+    fn instantiate(self) -> Self::Instantiated {
+        self
+    }
+
     #[inline]
     fn eval_decompose<'b, R>(self, f: impl FnOnce(MyCow<'b, X>) -> R) -> R
     where
@@ -179,6 +228,12 @@
 }
 
 impl<'a, X: Space + Clone> Instance<X, BasicDecomposition> for &'a X {
+    type Instantiated = X;
+
+    fn instantiate(self) -> Self::Instantiated {
+        self.own()
+    }
+
     #[inline]
     fn eval_decompose<'b, R>(self, f: impl FnOnce(MyCow<'b, X>) -> R) -> R
     where
@@ -212,6 +267,12 @@
 }
 
 impl<'a, X: Space + Clone> Instance<X, BasicDecomposition> for &'a mut X {
+    type Instantiated = X;
+
+    fn instantiate(self) -> Self::Instantiated {
+        self.own()
+    }
+
     #[inline]
     fn eval_decompose<'b, R>(self, f: impl FnOnce(MyCow<'b, X>) -> R) -> R
     where
@@ -246,6 +307,12 @@
 }
 
 impl<'a, X: Space + Clone> Instance<X, BasicDecomposition> for MyCow<'a, X> {
+    type Instantiated = X;
+
+    fn instantiate(self) -> Self::Instantiated {
+        self.own()
+    }
+
     #[inline]
     fn eval_decompose<'b, R>(self, f: impl FnOnce(MyCow<'b, X>) -> R) -> R
     where

mercurial