src/instance.rs

branch
dev
changeset 152
dab30b331f49
parent 150
c4e394a9c84c
equal deleted inserted replaced
151:402d717bb5c0 152:dab30b331f49
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 {
132 188
133 #[inline] 189 #[inline]
134 fn clone_owned(&self) -> Self::OwnedVariant { 190 fn clone_owned(&self) -> Self::OwnedVariant {
135 *self 191 *self
136 } 192 }
193
194 #[inline]
195 fn owned_cow<'b>(self) -> MyCow<'b, Self::OwnedVariant> where Self : 'b {
196 EitherDecomp::Owned(self)
197 }
198
199 #[inline]
200 fn ref_owned_cow<'b>(&'b self) -> MyCow<'b, Self::OwnedVariant> where Self : 'b{
201 EitherDecomp::Owned(*self)
202 }
137 } 203 }
138 }; 204 };
139 } 205 }
140 206
141 impl_basic_space!(u8 u16 u32 u64 u128 usize 207 impl_basic_space!(u8 u16 u32 u64 u128 usize
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
328 where 387 where
329 X: 'b, 388 X: 'b,
330 Self: 'b, 389 Self: 'b,
331 { 390 {
332 f(*self) 391 f(*self)
333 }
334
335 #[inline]
336 fn own(self) -> X {
337 self.into_owned()
338 }
339
340 #[inline]
341 fn cow<'b>(self) -> MyCow<'b, X>
342 where
343 Self: 'b,
344 {
345 EitherDecomp::Borrowed(self)
346 } 392 }
347 } 393 }
348 394
349 impl<'a, X: Space> Instance<X, BasicDecomposition> for MyCow<'a, X> { 395 impl<'a, X: Space> Instance<X, BasicDecomposition> for MyCow<'a, X> {
350 #[inline] 396 #[inline]
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`].

mercurial