| 22 } |
22 } |
| 23 } |
23 } |
| 24 } |
24 } |
| 25 |
25 |
| 26 /// Trait for ownable-by-consumption objects |
26 /// Trait for ownable-by-consumption objects |
| 27 pub trait Ownable { |
27 pub trait Ownable: Sized { |
| 28 type OwnedVariant: Clone; |
28 type OwnedVariant: Clone; |
| 29 |
29 |
| 30 /// Returns an owned instance, possibly consuming the original, |
30 /// Returns an owned instance, possibly consuming the original, |
| 31 /// avoiding cloning when possible. |
31 /// avoiding cloning when possible. |
| 32 fn into_owned(self) -> Self::OwnedVariant; |
32 fn into_owned(self) -> Self::OwnedVariant; |
| 33 |
33 |
| 34 /// Returns an owned instance of a reference. |
34 /// Returns an owned instance of a reference. |
| 35 fn clone_owned(&self) -> Self::OwnedVariant; |
35 fn clone_owned(&self) -> Self::OwnedVariant; |
| |
36 |
| |
37 /// Returns either an owned instance or a reference to one |
| |
38 fn owned_cow<'b>(self) -> MyCow<'b, Self::OwnedVariant> |
| |
39 where |
| |
40 Self: 'b; |
| |
41 |
| |
42 /// Returns either an owned instance or a reference to one, preferring a reference. |
| |
43 fn ref_owned_cow<'b>(&'b self) -> MyCow<'b, Self::OwnedVariant> |
| |
44 where |
| |
45 Self: 'b; |
| 36 } |
46 } |
| 37 |
47 |
| 38 impl<'a, X: Ownable> Ownable for &'a X { |
48 impl<'a, X: Ownable> Ownable for &'a X { |
| |
49 type OwnedVariant = X::OwnedVariant; |
| |
50 |
| |
51 #[inline] |
| |
52 fn into_owned(self) -> Self::OwnedVariant { |
| |
53 self.clone_owned() |
| |
54 } |
| |
55 |
| |
56 #[inline] |
| |
57 fn clone_owned(&self) -> Self::OwnedVariant { |
| |
58 (*self).into_owned() |
| |
59 } |
| |
60 |
| |
61 fn owned_cow<'b>(self) -> MyCow<'b, Self::OwnedVariant> |
| |
62 where |
| |
63 Self: 'b, |
| |
64 { |
| |
65 (*self).ref_owned_cow() |
| |
66 } |
| |
67 |
| |
68 #[inline] |
| |
69 fn ref_owned_cow<'b>(&'b self) -> MyCow<'b, Self::OwnedVariant> |
| |
70 where |
| |
71 Self: 'b, |
| |
72 { |
| |
73 (*self).ref_owned_cow() |
| |
74 } |
| |
75 } |
| |
76 |
| |
77 impl<'a, X: Ownable> Ownable for &'a mut X { |
| 39 type OwnedVariant = X::OwnedVariant; |
78 type OwnedVariant = X::OwnedVariant; |
| 40 |
79 |
| 41 #[inline] |
80 #[inline] |
| 42 /// Returns an owned instance. |
81 /// Returns an owned instance. |
| 43 fn into_owned(self) -> Self::OwnedVariant { |
82 fn into_owned(self) -> Self::OwnedVariant { |
| 45 } |
84 } |
| 46 |
85 |
| 47 #[inline] |
86 #[inline] |
| 48 /// Returns an owned instance. |
87 /// Returns an owned instance. |
| 49 fn clone_owned(&self) -> Self::OwnedVariant { |
88 fn clone_owned(&self) -> Self::OwnedVariant { |
| 50 (*self).into_owned() |
|
| 51 } |
|
| 52 } |
|
| 53 |
|
| 54 impl<'a, X: Ownable> Ownable for &'a mut X { |
|
| 55 type OwnedVariant = X::OwnedVariant; |
|
| 56 |
|
| 57 #[inline] |
|
| 58 /// Returns an owned instance. |
|
| 59 fn into_owned(self) -> Self::OwnedVariant { |
|
| 60 self.clone_owned() |
|
| 61 } |
|
| 62 |
|
| 63 #[inline] |
|
| 64 /// Returns an owned instance. |
|
| 65 fn clone_owned(&self) -> Self::OwnedVariant { |
|
| 66 (&**self).into_owned() |
89 (&**self).into_owned() |
| |
90 } |
| |
91 |
| |
92 fn owned_cow<'b>(self) -> MyCow<'b, Self::OwnedVariant> |
| |
93 where |
| |
94 Self: 'b, |
| |
95 { |
| |
96 (&*self).ref_owned_cow() |
| |
97 } |
| |
98 |
| |
99 #[inline] |
| |
100 fn ref_owned_cow<'b>(&'b self) -> MyCow<'b, Self::OwnedVariant> |
| |
101 where |
| |
102 Self: 'b, |
| |
103 { |
| |
104 (&**self).ref_owned_cow() |
| 67 } |
105 } |
| 68 } |
106 } |
| 69 |
107 |
| 70 impl<'a, X: Ownable> Ownable for MyCow<'a, X> { |
108 impl<'a, X: Ownable> Ownable for MyCow<'a, X> { |
| 71 type OwnedVariant = X::OwnedVariant; |
109 type OwnedVariant = X::OwnedVariant; |
| 84 fn clone_owned(&self) -> Self::OwnedVariant { |
122 fn clone_owned(&self) -> Self::OwnedVariant { |
| 85 match self { |
123 match self { |
| 86 EitherDecomp::Owned(x) => x.into_owned(), |
124 EitherDecomp::Owned(x) => x.into_owned(), |
| 87 EitherDecomp::Borrowed(x) => x.into_owned(), |
125 EitherDecomp::Borrowed(x) => x.into_owned(), |
| 88 } |
126 } |
| |
127 } |
| |
128 |
| |
129 fn owned_cow<'b>(self) -> MyCow<'b, Self::OwnedVariant> |
| |
130 where |
| |
131 Self: 'b, |
| |
132 { |
| |
133 match self { |
| |
134 EitherDecomp::Owned(x) => x.owned_cow(), |
| |
135 EitherDecomp::Borrowed(x) => x.ref_owned_cow(), |
| |
136 } |
| |
137 } |
| |
138 |
| |
139 #[inline] |
| |
140 fn ref_owned_cow<'b>(&'b self) -> MyCow<'b, Self::OwnedVariant> |
| |
141 where |
| |
142 Self: 'b, |
| |
143 { |
| |
144 (&**self).ref_owned_cow() |
| 89 } |
145 } |
| 90 } |
146 } |
| 91 |
147 |
| 92 /// Trait for abitrary mathematical spaces. |
148 /// Trait for abitrary mathematical spaces. |
| 93 pub trait Space: Ownable<OwnedVariant = Self::OwnedSpace> + Sized { |
149 pub trait Space: Ownable<OwnedVariant = Self::OwnedSpace> + Sized { |
| 184 /// Helper trait for functions to work with either owned values or references to either the |
250 /// Helper trait for functions to work with either owned values or references to either the |
| 185 /// “principal type” `X` or types some present a subset of `X`. In the latter sense, this |
251 /// “principal type” `X` or types some present a subset of `X`. In the latter sense, this |
| 186 /// generalises [`std::borrow::ToOwned`], [`std::borrow::Borrow`], and [`std::borrow::Cow`]. |
252 /// generalises [`std::borrow::ToOwned`], [`std::borrow::Borrow`], and [`std::borrow::Cow`]. |
| 187 /// |
253 /// |
| 188 /// This is used, for example, by [`crate::mapping::Mapping::apply`]. |
254 /// This is used, for example, by [`crate::mapping::Mapping::apply`]. |
| 189 pub trait Instance<X, D = <X as Space>::Decomp>: Sized + Ownable |
255 pub trait Instance<X, D = <X as Space>::Decomp>: |
| |
256 Sized + Ownable<OwnedVariant = X::OwnedSpace> |
| 190 where |
257 where |
| 191 X: Space, |
258 X: Space, |
| 192 D: Decomposition<X>, |
259 D: Decomposition<X>, |
| 193 { |
260 { |
| 194 /// Decomposes self according to `decomposer`, and evaluate `f` on the result. |
261 /// Decomposes self according to `decomposer`, and evaluate `f` on the result. |
| 203 fn eval_ref_decompose<'b, R>(&'b self, f: impl FnOnce(D::Reference<'b>) -> R) -> R |
270 fn eval_ref_decompose<'b, R>(&'b self, f: impl FnOnce(D::Reference<'b>) -> R) -> R |
| 204 where |
271 where |
| 205 X: 'b, |
272 X: 'b, |
| 206 Self: 'b; |
273 Self: 'b; |
| 207 |
274 |
| |
275 // fn eval_<'b, R>( |
| |
276 // &'b self, |
| |
277 // _f: impl FnOnce(D::Decomposition<'b>) -> R, |
| |
278 // g: impl FnOnce(D::Reference<'b>) -> R, |
| |
279 // ) -> R |
| |
280 // where |
| |
281 // X: 'b, |
| |
282 // Self: 'b, |
| |
283 // { |
| |
284 // self.eval_ref_decompose(g) |
| |
285 // } |
| |
286 |
| 208 /// Returns an owned instance of `X`, cloning or converting non-true instances when necessary. |
287 /// Returns an owned instance of `X`, cloning or converting non-true instances when necessary. |
| 209 fn own(self) -> X; |
288 fn own(self) -> X::OwnedSpace { |
| |
289 self.into_owned() |
| |
290 } |
| 210 |
291 |
| 211 // ************** automatically implemented methods below from here ************** |
292 // ************** automatically implemented methods below from here ************** |
| 212 |
293 |
| 213 /// Returns an owned instance or reference to `X`, converting non-true instances when necessary. |
294 /// Returns an owned instance or reference to `X`, converting non-true instances when necessary. |
| 214 /// |
295 /// |
| 215 /// Default implementation uses [`Self::own`]. Consumes the input. |
296 /// Default implementation uses [`Self::own`]. Consumes the input. |
| 216 fn cow<'b>(self) -> MyCow<'b, X> |
297 fn cow<'b>(self) -> MyCow<'b, X::OwnedSpace> |
| 217 where |
298 where |
| 218 Self: 'b, |
299 Self: 'b, |
| 219 { |
300 { |
| 220 MyCow::Owned(self.own()) |
301 self.owned_cow() |
| 221 } |
302 } |
| 222 |
303 |
| 223 #[inline] |
304 #[inline] |
| 224 /// Evaluates `f` on a reference to self. |
305 /// Evaluates `f` on a reference to self. |
| 225 /// |
306 /// |
| 226 /// Default implementation uses [`Self::cow`]. Consumes the input. |
307 /// Default implementation uses [`Self::cow`]. Consumes the input. |
| 227 fn eval<'b, R>(self, f: impl FnOnce(&X) -> R) -> R |
308 fn eval<'b, R>(self, f: impl FnOnce(&X::OwnedSpace) -> R) -> R |
| 228 where |
309 where |
| 229 X: 'b, |
310 X: 'b, |
| 230 Self: 'b, |
311 Self: 'b, |
| 231 { |
312 { |
| 232 f(&*self.cow()) |
313 f(&*self.cow()) |
| 234 |
315 |
| 235 #[inline] |
316 #[inline] |
| 236 /// Evaluates `f` or `g` depending on whether a reference or owned value is available. |
317 /// Evaluates `f` or `g` depending on whether a reference or owned value is available. |
| 237 /// |
318 /// |
| 238 /// Default implementation uses [`Self::cow`]. Consumes the input. |
319 /// Default implementation uses [`Self::cow`]. Consumes the input. |
| 239 fn either<'b, R>(self, f: impl FnOnce(X) -> R, g: impl FnOnce(&X) -> R) -> R |
320 fn either<'b, R>( |
| |
321 self, |
| |
322 f: impl FnOnce(X::OwnedSpace) -> R, |
| |
323 g: impl FnOnce(&X::OwnedSpace) -> R, |
| |
324 ) -> R |
| 240 where |
325 where |
| 241 Self: 'b, |
326 Self: 'b, |
| 242 { |
327 { |
| 243 match self.cow() { |
328 match self.cow() { |
| 244 EitherDecomp::Owned(x) => f(x), |
329 EitherDecomp::Owned(x) => f(x), |
| 263 X: 'b, |
348 X: 'b, |
| 264 Self: 'b, |
349 Self: 'b, |
| 265 { |
350 { |
| 266 f(self) |
351 f(self) |
| 267 } |
352 } |
| 268 |
|
| 269 #[inline] |
|
| 270 fn own(self) -> X { |
|
| 271 self |
|
| 272 } |
|
| 273 |
|
| 274 #[inline] |
|
| 275 fn cow<'b>(self) -> MyCow<'b, X> |
|
| 276 where |
|
| 277 Self: 'b, |
|
| 278 { |
|
| 279 MyCow::Owned(self) |
|
| 280 } |
|
| 281 } |
353 } |
| 282 |
354 |
| 283 impl<'a, X: Space> Instance<X, BasicDecomposition> for &'a X { |
355 impl<'a, X: Space> Instance<X, BasicDecomposition> for &'a X { |
| 284 #[inline] |
356 #[inline] |
| 285 fn eval_decompose<'b, R>(self, f: impl FnOnce(MyCow<'b, X>) -> R) -> R |
357 fn eval_decompose<'b, R>(self, f: impl FnOnce(MyCow<'b, X>) -> R) -> R |
| 296 X: 'b, |
368 X: 'b, |
| 297 Self: 'b, |
369 Self: 'b, |
| 298 { |
370 { |
| 299 f(*self) |
371 f(*self) |
| 300 } |
372 } |
| 301 |
|
| 302 #[inline] |
|
| 303 fn own(self) -> X { |
|
| 304 self.into_owned() |
|
| 305 } |
|
| 306 |
|
| 307 #[inline] |
|
| 308 fn cow<'b>(self) -> MyCow<'b, X> |
|
| 309 where |
|
| 310 Self: 'b, |
|
| 311 { |
|
| 312 MyCow::Borrowed(self) |
|
| 313 } |
|
| 314 } |
373 } |
| 315 |
374 |
| 316 impl<'a, X: Space> Instance<X, BasicDecomposition> for &'a mut X { |
375 impl<'a, X: Space> Instance<X, BasicDecomposition> for &'a mut X { |
| 317 #[inline] |
376 #[inline] |
| 318 fn eval_decompose<'b, R>(self, f: impl FnOnce(MyCow<'b, X>) -> R) -> R |
377 fn eval_decompose<'b, R>(self, f: impl FnOnce(MyCow<'b, X>) -> R) -> R |
| 363 Self: 'b, |
409 Self: 'b, |
| 364 { |
410 { |
| 365 match self { |
411 match self { |
| 366 MyCow::Borrowed(a) => f(a), |
412 MyCow::Borrowed(a) => f(a), |
| 367 MyCow::Owned(b) => f(&b), |
413 MyCow::Owned(b) => f(&b), |
| 368 } |
|
| 369 } |
|
| 370 |
|
| 371 #[inline] |
|
| 372 fn own(self) -> X { |
|
| 373 match self { |
|
| 374 MyCow::Borrowed(a) => a.own(), |
|
| 375 MyCow::Owned(b) => b.own(), |
|
| 376 } |
|
| 377 } |
|
| 378 |
|
| 379 #[inline] |
|
| 380 fn cow<'b>(self) -> MyCow<'b, X> |
|
| 381 where |
|
| 382 Self: 'b, |
|
| 383 { |
|
| 384 match self { |
|
| 385 MyCow::Borrowed(a) => a.cow(), |
|
| 386 MyCow::Owned(b) => b.cow(), |
|
| 387 } |
414 } |
| 388 } |
415 } |
| 389 } |
416 } |
| 390 |
417 |
| 391 /// Marker type for mutable decompositions to be used with [`InstanceMut`]. |
418 /// Marker type for mutable decompositions to be used with [`InstanceMut`]. |