src/instance.rs

branch
dev
changeset 150
c4e394a9c84c
parent 133
2b13f8a0c8ba
child 152
dab30b331f49
child 153
829c07ea584d
equal deleted inserted replaced
149:2f1798c65fd6 150:c4e394a9c84c
21 EitherDecomp::Borrowed(x) => x, 21 EitherDecomp::Borrowed(x) => x,
22 } 22 }
23 } 23 }
24 } 24 }
25 25
26 impl<'b, X> MyCow<'b, X> { 26 /// Trait for ownable-by-consumption objects
27 #[inline] 27 pub trait Ownable {
28 pub fn into_owned(self) -> X 28 type OwnedVariant: Clone;
29 where 29
30 X: Clone, 30 /// Returns an owned instance, possibly consuming the original,
31 { 31 /// avoiding cloning when possible.
32 match self { 32 fn into_owned(self) -> Self::OwnedVariant;
33 EitherDecomp::Owned(x) => x, 33
34 EitherDecomp::Borrowed(x) => x.clone(), 34 /// Returns an owned instance of a reference.
35 fn clone_owned(&self) -> Self::OwnedVariant;
36 }
37
38 impl<'a, X: Ownable> Ownable for &'a X {
39 type OwnedVariant = X::OwnedVariant;
40
41 #[inline]
42 /// Returns an owned instance.
43 fn into_owned(self) -> Self::OwnedVariant {
44 self.clone_owned()
45 }
46
47 #[inline]
48 /// Returns an owned instance.
49 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()
67 }
68 }
69
70 impl<'a, X: Ownable> Ownable for MyCow<'a, X> {
71 type OwnedVariant = X::OwnedVariant;
72
73 #[inline]
74 /// Returns an owned instance.
75 fn into_owned(self) -> Self::OwnedVariant {
76 match self {
77 EitherDecomp::Owned(x) => x.into_owned(),
78 EitherDecomp::Borrowed(x) => x.into_owned(),
79 }
80 }
81
82 #[inline]
83 /// Returns an owned instance.
84 fn clone_owned(&self) -> Self::OwnedVariant {
85 match self {
86 EitherDecomp::Owned(x) => x.into_owned(),
87 EitherDecomp::Borrowed(x) => x.into_owned(),
35 } 88 }
36 } 89 }
37 } 90 }
38 91
39 /// Trait for abitrary mathematical spaces. 92 /// Trait for abitrary mathematical spaces.
40 pub trait Space: Instance<Self, Self::Decomp> { 93 pub trait Space: Ownable<OwnedVariant = Self::OwnedSpace> + Sized {
94 type OwnedSpace: ClosedSpace;
95
41 /// Default decomposition for the space 96 /// Default decomposition for the space
42 type Decomp: Decomposition<Self>; 97 type Decomp: Decomposition<Self>;
43 } 98 }
44 99
100 mod private {
101 pub trait Sealed {}
102 }
103
104 /// Helper trait for working with own types.
105 pub trait Owned: Ownable<OwnedVariant = Self> + private::Sealed {}
106 impl<X: Ownable<OwnedVariant = X>> private::Sealed for X {}
107 impl<X: Ownable<OwnedVariant = X>> Owned for X {}
108
109 /// Helper trait for working with closed spaces, operations in which should
110 /// return members of the same space
111 pub trait ClosedSpace: Space<OwnedSpace = Self> + Owned + Instance<Self> {}
112 impl<X: Space<OwnedSpace = Self> + Owned + Instance<Self>> ClosedSpace for X {}
113
45 #[macro_export] 114 #[macro_export]
46 macro_rules! impl_basic_space { 115 macro_rules! impl_basic_space {
47 ($($type:ty)*) => { $( 116 ($($type:ty)*) => {
48 impl $crate::instance::Space for $type { 117 $( $crate::impl_basic_space!($type where ); )*
49 type Decomp = $crate::instance::BasicDecomposition; 118 };
50 }
51 )* };
52 ($type:ty where $($where:tt)*) => { 119 ($type:ty where $($where:tt)*) => {
53 impl<$($where)*> $crate::instance::Space for $type { 120 impl<$($where)*> $crate::instance::Space for $type {
121 type OwnedSpace = Self;
54 type Decomp = $crate::instance::BasicDecomposition; 122 type Decomp = $crate::instance::BasicDecomposition;
123 }
124
125 impl<$($where)*> $crate::instance::Ownable for $type {
126 type OwnedVariant = Self;
127
128 #[inline]
129 fn into_owned(self) -> Self::OwnedVariant {
130 self
131 }
132
133 #[inline]
134 fn clone_owned(&self) -> Self::OwnedVariant {
135 *self
136 }
55 } 137 }
56 }; 138 };
57 } 139 }
58 140
59 impl_basic_space!(u8 u16 u32 u64 u128 usize 141 impl_basic_space!(u8 u16 u32 u64 u128 usize
81 /// Most common [`Decomposition`] (into `Either<X, &'b X>`) that allows working with owned 163 /// Most common [`Decomposition`] (into `Either<X, &'b X>`) that allows working with owned
82 /// values and all sorts of references. 164 /// values and all sorts of references.
83 #[derive(Copy, Clone, Debug)] 165 #[derive(Copy, Clone, Debug)]
84 pub struct BasicDecomposition; 166 pub struct BasicDecomposition;
85 167
86 impl<X: Space + Clone> Decomposition<X> for BasicDecomposition { 168 impl<X: Space> Decomposition<X> for BasicDecomposition {
87 type Decomposition<'b> 169 type Decomposition<'b>
88 = MyCow<'b, X> 170 = MyCow<'b, X>
89 where 171 where
90 X: 'b; 172 X: 'b;
91 type Reference<'b> 173 type Reference<'b>
102 /// Helper trait for functions to work with either owned values or references to either the 184 /// Helper trait for functions to work with either owned values or references to either the
103 /// “principal type” `X` or types some present a subset of `X`. In the latter sense, this 185 /// “principal type” `X` or types some present a subset of `X`. In the latter sense, this
104 /// generalises [`std::borrow::ToOwned`], [`std::borrow::Borrow`], and [`std::borrow::Cow`]. 186 /// generalises [`std::borrow::ToOwned`], [`std::borrow::Borrow`], and [`std::borrow::Cow`].
105 /// 187 ///
106 /// This is used, for example, by [`crate::mapping::Mapping::apply`]. 188 /// This is used, for example, by [`crate::mapping::Mapping::apply`].
107 pub trait Instance<X: Space, D = <X as Space>::Decomp>: Sized 189 pub trait Instance<X, D = <X as Space>::Decomp>: Sized + Ownable
108 where 190 where
191 X: Space,
109 D: Decomposition<X>, 192 D: Decomposition<X>,
110 { 193 {
111 /// Decomposes self according to `decomposer`, and evaluate `f` on the result. 194 /// Decomposes self according to `decomposer`, and evaluate `f` on the result.
112 /// Consumes self. 195 /// Consumes self.
113 fn eval_decompose<'b, R>(self, f: impl FnOnce(D::Decomposition<'b>) -> R) -> R 196 fn eval_decompose<'b, R>(self, f: impl FnOnce(D::Decomposition<'b>) -> R) -> R
162 EitherDecomp::Borrowed(x) => g(x), 245 EitherDecomp::Borrowed(x) => g(x),
163 } 246 }
164 } 247 }
165 } 248 }
166 249
167 impl<X: Space + Clone> Instance<X, BasicDecomposition> for X { 250 impl<X: Space> Instance<X, BasicDecomposition> for X {
168 #[inline] 251 #[inline]
169 fn eval_decompose<'b, R>(self, f: impl FnOnce(MyCow<'b, X>) -> R) -> R 252 fn eval_decompose<'b, R>(self, f: impl FnOnce(MyCow<'b, X>) -> R) -> R
170 where 253 where
171 X: 'b, 254 X: 'b,
172 Self: 'b, 255 Self: 'b,
195 { 278 {
196 MyCow::Owned(self) 279 MyCow::Owned(self)
197 } 280 }
198 } 281 }
199 282
200 impl<'a, X: Space + Clone> Instance<X, BasicDecomposition> for &'a X { 283 impl<'a, X: Space> Instance<X, BasicDecomposition> for &'a X {
201 #[inline] 284 #[inline]
202 fn eval_decompose<'b, R>(self, f: impl FnOnce(MyCow<'b, X>) -> R) -> R 285 fn eval_decompose<'b, R>(self, f: impl FnOnce(MyCow<'b, X>) -> R) -> R
203 where 286 where
204 X: 'b, 287 X: 'b,
205 Self: 'b, 288 Self: 'b,
216 f(*self) 299 f(*self)
217 } 300 }
218 301
219 #[inline] 302 #[inline]
220 fn own(self) -> X { 303 fn own(self) -> X {
221 self.clone() 304 self.into_owned()
222 } 305 }
223 306
224 #[inline] 307 #[inline]
225 fn cow<'b>(self) -> MyCow<'b, X> 308 fn cow<'b>(self) -> MyCow<'b, X>
226 where 309 where
228 { 311 {
229 MyCow::Borrowed(self) 312 MyCow::Borrowed(self)
230 } 313 }
231 } 314 }
232 315
233 impl<'a, X: Space + Clone> Instance<X, BasicDecomposition> for &'a mut X { 316 impl<'a, X: Space> Instance<X, BasicDecomposition> for &'a mut X {
234 #[inline] 317 #[inline]
235 fn eval_decompose<'b, R>(self, f: impl FnOnce(MyCow<'b, X>) -> R) -> R 318 fn eval_decompose<'b, R>(self, f: impl FnOnce(MyCow<'b, X>) -> R) -> R
236 where 319 where
237 X: 'b, 320 X: 'b,
238 Self: 'b, 321 Self: 'b,
249 f(*self) 332 f(*self)
250 } 333 }
251 334
252 #[inline] 335 #[inline]
253 fn own(self) -> X { 336 fn own(self) -> X {
254 self.clone() 337 self.into_owned()
255 } 338 }
256 339
257 #[inline] 340 #[inline]
258 fn cow<'b>(self) -> MyCow<'b, X> 341 fn cow<'b>(self) -> MyCow<'b, X>
259 where 342 where
260 Self: 'b, 343 Self: 'b,
261 X: Clone,
262 { 344 {
263 EitherDecomp::Borrowed(self) 345 EitherDecomp::Borrowed(self)
264 } 346 }
265 } 347 }
266 348
267 impl<'a, X: Space + Clone> Instance<X, BasicDecomposition> for MyCow<'a, X> { 349 impl<'a, X: Space> Instance<X, BasicDecomposition> for MyCow<'a, X> {
268 #[inline] 350 #[inline]
269 fn eval_decompose<'b, R>(self, f: impl FnOnce(MyCow<'b, X>) -> R) -> R 351 fn eval_decompose<'b, R>(self, f: impl FnOnce(MyCow<'b, X>) -> R) -> R
270 where 352 where
271 X: 'b, 353 X: 'b,
272 Self: 'b, 354 Self: 'b,

mercurial