| 111 todo!(); |
111 todo!(); |
| 112 } |
112 } |
| 113 } |
113 } |
| 114 |
114 |
| 115 /// Trait for abitrary mathematical spaces. |
115 /// Trait for abitrary mathematical spaces. |
| 116 pub trait Space: Ownable<OwnedVariant = Self::OwnedSpace> + Sized { |
116 pub trait Space: Ownable<OwnedVariant = Self::Principal> + Sized { |
| 117 type OwnedSpace: ClosedSpace; |
117 /// Principal, typically owned realisation of the space. |
| |
118 type Principal: ClosedSpace; |
| 118 |
119 |
| 119 /// Default decomposition for the space |
120 /// Default decomposition for the space |
| 120 type Decomp: Decomposition<Self>; |
121 type Decomp: Decomposition<Self>; |
| 121 } |
122 } |
| 122 |
123 |
| 129 impl<X: Ownable<OwnedVariant = X>> private::Sealed for X {} |
130 impl<X: Ownable<OwnedVariant = X>> private::Sealed for X {} |
| 130 impl<X: Ownable<OwnedVariant = X>> Owned for X {} |
131 impl<X: Ownable<OwnedVariant = X>> Owned for X {} |
| 131 |
132 |
| 132 /// Helper trait for working with closed spaces, operations in which should |
133 /// Helper trait for working with closed spaces, operations in which should |
| 133 /// return members of the same space |
134 /// return members of the same space |
| 134 pub trait ClosedSpace: Space<OwnedSpace = Self> + Owned + Instance<Self> {} |
135 pub trait ClosedSpace: Space<Principal = Self> + Owned + Instance<Self> {} |
| 135 impl<X: Space<OwnedSpace = Self> + Owned + Instance<Self>> ClosedSpace for X {} |
136 impl<X: Space<Principal = Self> + Owned + Instance<Self>> ClosedSpace for X {} |
| 136 |
137 |
| 137 #[macro_export] |
138 #[macro_export] |
| 138 macro_rules! impl_basic_space { |
139 macro_rules! impl_basic_space { |
| 139 ($($type:ty)*) => { |
140 ($($type:ty)*) => { |
| 140 $( $crate::impl_basic_space!($type where ); )* |
141 $( $crate::impl_basic_space!($type where ); )* |
| 141 }; |
142 }; |
| 142 ($type:ty where $($where:tt)*) => { |
143 ($type:ty where $($where:tt)*) => { |
| 143 impl<$($where)*> $crate::instance::Space for $type { |
144 impl<$($where)*> $crate::instance::Space for $type { |
| 144 type OwnedSpace = Self; |
145 type Principal = Self; |
| 145 type Decomp = $crate::instance::BasicDecomposition; |
146 type Decomp = $crate::instance::BasicDecomposition; |
| 146 } |
147 } |
| 147 |
148 |
| 148 impl<$($where)*> $crate::instance::Ownable for $type { |
149 impl<$($where)*> $crate::instance::Ownable for $type { |
| 149 type OwnedVariant = Self; |
150 type OwnedVariant = Self; |
| 213 /// “principal type” `X` or types some present a subset of `X`. In the latter sense, this |
214 /// “principal type” `X` or types some present a subset of `X`. In the latter sense, this |
| 214 /// generalises [`std::borrow::ToOwned`], [`std::borrow::Borrow`], and [`std::borrow::Cow`]. |
215 /// generalises [`std::borrow::ToOwned`], [`std::borrow::Borrow`], and [`std::borrow::Cow`]. |
| 215 /// |
216 /// |
| 216 /// This is used, for example, by [`crate::mapping::Mapping::apply`]. |
217 /// This is used, for example, by [`crate::mapping::Mapping::apply`]. |
| 217 pub trait Instance<X, D = <X as Space>::Decomp>: |
218 pub trait Instance<X, D = <X as Space>::Decomp>: |
| 218 Sized + Ownable<OwnedVariant = X::OwnedSpace> |
219 Sized + Ownable<OwnedVariant = X::Principal> |
| 219 where |
220 where |
| 220 X: Space, |
221 X: Space, |
| 221 D: Decomposition<X>, |
222 D: Decomposition<X>, |
| 222 { |
223 { |
| 223 /// Decomposes self according to `decomposer`, and evaluate `f` on the result. |
224 /// Decomposes self according to `decomposer`, and evaluate `f` on the result. |
| 233 where |
234 where |
| 234 X: 'b, |
235 X: 'b, |
| 235 Self: 'b; |
236 Self: 'b; |
| 236 |
237 |
| 237 /// Returns an owned instance of `X`, cloning or converting non-true instances when necessary. |
238 /// Returns an owned instance of `X`, cloning or converting non-true instances when necessary. |
| 238 fn own(self) -> X::OwnedSpace { |
239 fn own(self) -> X::Principal { |
| 239 self.into_owned() |
240 self.into_owned() |
| 240 } |
241 } |
| 241 |
242 |
| 242 // ************** automatically implemented methods below from here ************** |
243 // ************** automatically implemented methods below from here ************** |
| 243 |
244 |
| 244 /// Returns an owned instance or reference to `X`, converting non-true instances when necessary. |
245 /// Returns an owned instance or reference to `X`, converting non-true instances when necessary. |
| 245 /// |
246 /// |
| 246 /// Default implementation uses [`Self::own`]. Consumes the input. |
247 /// Default implementation uses [`Self::own`]. Consumes the input. |
| 247 fn cow<'b>(self) -> MyCow<'b, X::OwnedSpace> |
248 fn cow<'b>(self) -> MyCow<'b, X::Principal> |
| 248 where |
249 where |
| 249 Self: 'b, |
250 Self: 'b, |
| 250 { |
251 { |
| 251 self.cow_owned() |
252 self.cow_owned() |
| 252 } |
253 } |
| 253 |
254 |
| 254 #[inline] |
255 #[inline] |
| 255 /// Evaluates `f` on a reference to self. |
256 /// Evaluates `f` on a reference to self. |
| 256 /// |
257 /// |
| 257 /// Default implementation uses [`Self::cow`]. Consumes the input. |
258 /// Default implementation uses [`Self::cow`]. Consumes the input. |
| 258 fn eval<'b, R>(self, f: impl FnOnce(&X::OwnedSpace) -> R) -> R |
259 fn eval<'b, R>(self, f: impl FnOnce(&X::Principal) -> R) -> R |
| 259 where |
260 where |
| 260 X: 'b, |
261 X: 'b, |
| 261 Self: 'b, |
262 Self: 'b, |
| 262 { |
263 { |
| 263 f(&*self.cow()) |
264 f(&*self.cow()) |
| 267 /// Evaluates `f` or `g` depending on whether a reference or owned value is available. |
268 /// Evaluates `f` or `g` depending on whether a reference or owned value is available. |
| 268 /// |
269 /// |
| 269 /// Default implementation uses [`Self::cow`]. Consumes the input. |
270 /// Default implementation uses [`Self::cow`]. Consumes the input. |
| 270 fn either<'b, R>( |
271 fn either<'b, R>( |
| 271 self, |
272 self, |
| 272 f: impl FnOnce(X::OwnedSpace) -> R, |
273 f: impl FnOnce(X::Principal) -> R, |
| 273 g: impl FnOnce(&X::OwnedSpace) -> R, |
274 g: impl FnOnce(&X::Principal) -> R, |
| 274 ) -> R |
275 ) -> R |
| 275 where |
276 where |
| 276 Self: 'b, |
277 Self: 'b, |
| 277 { |
278 { |
| 278 match self.cow() { |
279 match self.cow() { |