| 56 impl_basic_space!(u8 u16 u32 u64 u128 usize |
59 impl_basic_space!(u8 u16 u32 u64 u128 usize |
| 57 i8 i16 i32 i64 i128 isize |
60 i8 i16 i32 i64 i128 isize |
| 58 f32 f64); |
61 f32 f64); |
| 59 |
62 |
| 60 /// Marker type for decompositions to be used with [`Instance`]. |
63 /// Marker type for decompositions to be used with [`Instance`]. |
| 61 pub trait Decomposition<X : Space> : Sized { |
64 pub trait Decomposition<X: Space>: Sized { |
| 62 /// Possibly owned form of the decomposition |
65 /// Possibly owned form of the decomposition |
| 63 type Decomposition<'b> : Instance<X, Self> where X : 'b; |
66 type Decomposition<'b>: Instance<X, Self> |
| |
67 where |
| |
68 X: 'b; |
| 64 /// Unlikely owned form of the decomposition. |
69 /// Unlikely owned form of the decomposition. |
| 65 /// Type for a lightweight intermediate conversion that does not own the original variable. |
70 /// Type for a lightweight intermediate conversion that does not own the original variable. |
| 66 /// Usually this is just a reference, but may also be a lightweight structure that |
71 /// Usually this is just a reference, but may also be a lightweight structure that |
| 67 /// contains references; see the implementation for [`crate::direct_product::Pair`]. |
72 /// contains references; see the implementation for [`crate::direct_product::Pair`]. |
| 68 type Reference<'b> : Instance<X, Self> + Copy where X : 'b; |
73 type Reference<'b>: Instance<X, Self> + Copy |
| |
74 where |
| |
75 X: 'b; |
| 69 |
76 |
| 70 /// Left the lightweight reference type into a full decomposition type. |
77 /// Left the lightweight reference type into a full decomposition type. |
| 71 fn lift<'b>(r : Self::Reference<'b>) -> Self::Decomposition<'b>; |
78 fn lift<'b>(r: Self::Reference<'b>) -> Self::Decomposition<'b>; |
| 72 } |
79 } |
| 73 |
80 |
| 74 /// Most common [`Decomposition`] (into `Either<X, &'b X>`) that allows working with owned |
81 /// Most common [`Decomposition`] (into `Either<X, &'b X>`) that allows working with owned |
| 75 /// values and all sorts of references. |
82 /// values and all sorts of references. |
| 76 #[derive(Copy, Clone, Debug)] |
83 #[derive(Copy, Clone, Debug)] |
| 77 pub struct BasicDecomposition; |
84 pub struct BasicDecomposition; |
| 78 |
85 |
| 79 impl<X : Space + Clone> Decomposition<X> for BasicDecomposition { |
86 impl<X: Space + Clone> Decomposition<X> for BasicDecomposition { |
| 80 type Decomposition<'b> = MyCow<'b, X> where X : 'b; |
87 type Decomposition<'b> |
| 81 type Reference<'b> = &'b X where X : 'b; |
88 = MyCow<'b, X> |
| 82 |
89 where |
| 83 #[inline] |
90 X: 'b; |
| 84 fn lift<'b>(r : Self::Reference<'b>) -> Self::Decomposition<'b> { |
91 type Reference<'b> |
| |
92 = &'b X |
| |
93 where |
| |
94 X: 'b; |
| |
95 |
| |
96 #[inline] |
| |
97 fn lift<'b>(r: Self::Reference<'b>) -> Self::Decomposition<'b> { |
| 85 MyCow::Borrowed(r) |
98 MyCow::Borrowed(r) |
| 86 } |
99 } |
| 87 } |
100 } |
| 88 |
101 |
| 89 /// Helper trait for functions to work with either owned values or references to either the |
102 /// Helper trait for functions to work with either owned values or references to either the |
| 90 /// “principal type” `X` or types some present a subset of `X`. In the latter sense, this |
103 /// “principal type” `X` or types some present a subset of `X`. In the latter sense, this |
| 91 /// generalises [`std::borrow::ToOwned`], [`std::borrow::Borrow`], and [`std::borrow::Cow`]. |
104 /// generalises [`std::borrow::ToOwned`], [`std::borrow::Borrow`], and [`std::borrow::Cow`]. |
| 92 /// |
105 /// |
| 93 /// This is used, for example, by [`crate::mapping::Mapping::apply`]. |
106 /// This is used, for example, by [`crate::mapping::Mapping::apply`]. |
| 94 pub trait Instance<X : Space, D = <X as Space>::Decomp> : Sized where D : Decomposition<X> { |
107 pub trait Instance<X: Space, D = <X as Space>::Decomp>: Sized |
| 95 /// Decomposes self according to `decomposer`. |
108 where |
| 96 fn decompose<'b>(self) -> D::Decomposition<'b> |
109 D: Decomposition<X>, |
| 97 where Self : 'b, X : 'b; |
110 { |
| 98 |
111 /// Decomposes self according to `decomposer`, and evaluate `f` on the result. |
| 99 /// Returns a lightweight instance of `self`. |
112 /// Consumes self. |
| 100 fn ref_instance(&self) -> D::Reference<'_>; |
113 fn eval_decompose<'b, R>(self, f: impl FnOnce(D::Decomposition<'b>) -> R) -> R |
| |
114 where |
| |
115 X: 'b, |
| |
116 Self: 'b; |
| |
117 |
| |
118 /// Does a light decomposition of self `decomposer`, and evaluates `f` on the result. |
| |
119 /// Does not consume self. |
| |
120 fn eval_ref_decompose<'b, R>(&'b self, f: impl FnOnce(D::Reference<'b>) -> R) -> R |
| |
121 where |
| |
122 X: 'b, |
| |
123 Self: 'b; |
| 101 |
124 |
| 102 /// Returns an owned instance of `X`, cloning or converting non-true instances when necessary. |
125 /// Returns an owned instance of `X`, cloning or converting non-true instances when necessary. |
| 103 fn own(self) -> X; |
126 fn own(self) -> X; |
| 104 |
127 |
| 105 // ************** automatically implemented methods below from here ************** |
128 // ************** automatically implemented methods below from here ************** |
| 106 |
129 |
| 107 /// Returns an owned instance or reference to `X`, converting non-true instances when necessary. |
130 /// Returns an owned instance or reference to `X`, converting non-true instances when necessary. |
| 108 /// |
131 /// |
| 109 /// Default implementation uses [`Self::own`]. Consumes the input. |
132 /// Default implementation uses [`Self::own`]. Consumes the input. |
| 110 fn cow<'b>(self) -> MyCow<'b, X> where Self : 'b { |
133 fn cow<'b>(self) -> MyCow<'b, X> |
| |
134 where |
| |
135 Self: 'b, |
| |
136 { |
| 111 MyCow::Owned(self.own()) |
137 MyCow::Owned(self.own()) |
| 112 } |
138 } |
| 113 |
139 |
| 114 #[inline] |
140 #[inline] |
| 115 /// Evaluates `f` on a reference to self. |
141 /// Evaluates `f` on a reference to self. |
| 116 /// |
142 /// |
| 117 /// Default implementation uses [`Self::cow`]. Consumes the input. |
143 /// Default implementation uses [`Self::cow`]. Consumes the input. |
| 118 fn eval<'b, R>(self, f : impl FnOnce(&X) -> R) -> R |
144 fn eval<'b, R>(self, f: impl FnOnce(&X) -> R) -> R |
| 119 where X : 'b, Self : 'b |
145 where |
| |
146 X: 'b, |
| |
147 Self: 'b, |
| 120 { |
148 { |
| 121 f(&*self.cow()) |
149 f(&*self.cow()) |
| 122 } |
150 } |
| 123 |
151 |
| 124 #[inline] |
152 #[inline] |
| 125 /// Evaluates `f` or `g` depending on whether a reference or owned value is available. |
153 /// Evaluates `f` or `g` depending on whether a reference or owned value is available. |
| 126 /// |
154 /// |
| 127 /// Default implementation uses [`Self::cow`]. Consumes the input. |
155 /// Default implementation uses [`Self::cow`]. Consumes the input. |
| 128 fn either<'b, R>( |
156 fn either<'b, R>(self, f: impl FnOnce(X) -> R, g: impl FnOnce(&X) -> R) -> R |
| 129 self, |
157 where |
| 130 f : impl FnOnce(X) -> R, |
158 Self: 'b, |
| 131 g : impl FnOnce(&X) -> R |
|
| 132 ) -> R |
|
| 133 where Self : 'b |
|
| 134 { |
159 { |
| 135 match self.cow() { |
160 match self.cow() { |
| 136 EitherDecomp::Owned(x) => f(x), |
161 EitherDecomp::Owned(x) => f(x), |
| 137 EitherDecomp::Borrowed(x) => g(x), |
162 EitherDecomp::Borrowed(x) => g(x), |
| 138 } |
163 } |
| 139 } |
164 } |
| 140 } |
165 } |
| 141 |
166 |
| 142 |
167 impl<X: Space + Clone> Instance<X, BasicDecomposition> for X { |
| 143 impl<X : Space + Clone> Instance<X, BasicDecomposition> for X { |
168 #[inline] |
| 144 #[inline] |
169 fn eval_decompose<'b, R>(self, f: impl FnOnce(MyCow<'b, X>) -> R) -> R |
| 145 fn decompose<'b>(self) -> <BasicDecomposition as Decomposition<X>>::Decomposition<'b> |
170 where |
| 146 where Self : 'b, X : 'b |
171 X: 'b, |
| 147 { |
172 Self: 'b, |
| 148 MyCow::Owned(self) |
173 { |
| |
174 f(MyCow::Owned(self)) |
| |
175 } |
| |
176 |
| |
177 #[inline] |
| |
178 fn eval_ref_decompose<'b, R>(&'b self, f: impl FnOnce(&'b X) -> R) -> R |
| |
179 where |
| |
180 X: 'b, |
| |
181 Self: 'b, |
| |
182 { |
| |
183 f(self) |
| 149 } |
184 } |
| 150 |
185 |
| 151 #[inline] |
186 #[inline] |
| 152 fn own(self) -> X { |
187 fn own(self) -> X { |
| 153 self |
188 self |
| 154 } |
189 } |
| 155 |
190 |
| 156 #[inline] |
191 #[inline] |
| 157 fn cow<'b>(self) -> MyCow<'b, X> where Self : 'b { |
192 fn cow<'b>(self) -> MyCow<'b, X> |
| |
193 where |
| |
194 Self: 'b, |
| |
195 { |
| 158 MyCow::Owned(self) |
196 MyCow::Owned(self) |
| 159 } |
197 } |
| 160 |
198 } |
| 161 #[inline] |
199 |
| 162 fn ref_instance(&self) -> <BasicDecomposition as Decomposition<X>>::Reference<'_> { |
200 impl<'a, X: Space + Clone> Instance<X, BasicDecomposition> for &'a X { |
| 163 self |
201 #[inline] |
| 164 } |
202 fn eval_decompose<'b, R>(self, f: impl FnOnce(MyCow<'b, X>) -> R) -> R |
| 165 } |
203 where |
| 166 |
204 X: 'b, |
| 167 impl<'a, X : Space + Clone> Instance<X, BasicDecomposition> for &'a X { |
205 Self: 'b, |
| 168 #[inline] |
206 { |
| 169 fn decompose<'b>(self) -> <BasicDecomposition as Decomposition<X>>::Decomposition<'b> |
207 f(MyCow::Borrowed(self)) |
| 170 where Self : 'b, X : 'b |
208 } |
| 171 { |
209 |
| 172 MyCow::Borrowed(self) |
210 #[inline] |
| |
211 fn eval_ref_decompose<'b, R>(&'b self, f: impl FnOnce(&'b X) -> R) -> R |
| |
212 where |
| |
213 X: 'b, |
| |
214 Self: 'b, |
| |
215 { |
| |
216 f(*self) |
| 173 } |
217 } |
| 174 |
218 |
| 175 #[inline] |
219 #[inline] |
| 176 fn own(self) -> X { |
220 fn own(self) -> X { |
| 177 self.clone() |
221 self.clone() |
| 178 } |
222 } |
| 179 |
223 |
| 180 #[inline] |
224 #[inline] |
| 181 fn cow<'b>(self) -> MyCow<'b, X> where Self : 'b { |
225 fn cow<'b>(self) -> MyCow<'b, X> |
| |
226 where |
| |
227 Self: 'b, |
| |
228 { |
| 182 MyCow::Borrowed(self) |
229 MyCow::Borrowed(self) |
| 183 } |
230 } |
| 184 |
231 } |
| 185 #[inline] |
232 |
| 186 fn ref_instance(&self) -> <BasicDecomposition as Decomposition<X>>::Reference<'_> { |
233 impl<'a, X: Space + Clone> Instance<X, BasicDecomposition> for &'a mut X { |
| 187 *self |
234 #[inline] |
| 188 } |
235 fn eval_decompose<'b, R>(self, f: impl FnOnce(MyCow<'b, X>) -> R) -> R |
| 189 } |
236 where |
| 190 |
237 X: 'b, |
| 191 impl<'a, X : Space + Clone> Instance<X, BasicDecomposition> for &'a mut X { |
238 Self: 'b, |
| 192 #[inline] |
239 { |
| 193 fn decompose<'b>(self) -> <BasicDecomposition as Decomposition<X>>::Decomposition<'b> |
240 f(EitherDecomp::Borrowed(self)) |
| 194 where Self : 'b, X : 'b |
241 } |
| 195 { |
242 |
| 196 EitherDecomp::Borrowed(self) |
243 #[inline] |
| |
244 fn eval_ref_decompose<'b, R>(&'b self, f: impl FnOnce(&'b X) -> R) -> R |
| |
245 where |
| |
246 X: 'b, |
| |
247 Self: 'b, |
| |
248 { |
| |
249 f(*self) |
| 197 } |
250 } |
| 198 |
251 |
| 199 #[inline] |
252 #[inline] |
| 200 fn own(self) -> X { |
253 fn own(self) -> X { |
| 201 self.clone() |
254 self.clone() |
| 202 } |
255 } |
| 203 |
256 |
| 204 #[inline] |
257 #[inline] |
| 205 fn cow<'b>(self) -> MyCow<'b, X> where Self : 'b, X : Clone { |
258 fn cow<'b>(self) -> MyCow<'b, X> |
| |
259 where |
| |
260 Self: 'b, |
| |
261 X: Clone, |
| |
262 { |
| 206 EitherDecomp::Borrowed(self) |
263 EitherDecomp::Borrowed(self) |
| 207 } |
264 } |
| 208 |
265 } |
| 209 #[inline] |
266 |
| 210 fn ref_instance(&self) -> <BasicDecomposition as Decomposition<X>>::Reference<'_> { |
267 impl<'a, X: Space + Clone> Instance<X, BasicDecomposition> for MyCow<'a, X> { |
| 211 *self |
268 #[inline] |
| 212 } |
269 fn eval_decompose<'b, R>(self, f: impl FnOnce(MyCow<'b, X>) -> R) -> R |
| 213 } |
270 where |
| 214 |
271 X: 'b, |
| 215 impl<'a, X : Space + Clone> Instance<X, BasicDecomposition> for MyCow<'a, X> { |
272 Self: 'b, |
| 216 |
273 { |
| 217 #[inline] |
274 f(self) |
| 218 fn decompose<'b>(self) -> <BasicDecomposition as Decomposition<X>>::Decomposition<'b> |
275 } |
| 219 where Self : 'b, X : 'b |
276 |
| 220 { |
277 #[inline] |
| 221 self |
278 fn eval_ref_decompose<'b, R>(&'b self, f: impl FnOnce(&'b X) -> R) -> R |
| |
279 where |
| |
280 X: 'b, |
| |
281 Self: 'b, |
| |
282 { |
| |
283 match self { |
| |
284 MyCow::Borrowed(a) => f(a), |
| |
285 MyCow::Owned(b) => f(&b), |
| |
286 } |
| 222 } |
287 } |
| 223 |
288 |
| 224 #[inline] |
289 #[inline] |
| 225 fn own(self) -> X { |
290 fn own(self) -> X { |
| 226 match self { |
291 match self { |
| 227 MyCow::Borrowed(a) => a.own(), |
292 MyCow::Borrowed(a) => a.own(), |
| 228 MyCow::Owned(b) => b.own() |
293 MyCow::Owned(b) => b.own(), |
| 229 } |
294 } |
| 230 } |
295 } |
| 231 |
296 |
| 232 #[inline] |
297 #[inline] |
| 233 fn cow<'b>(self) -> MyCow<'b, X> where Self : 'b { |
298 fn cow<'b>(self) -> MyCow<'b, X> |
| |
299 where |
| |
300 Self: 'b, |
| |
301 { |
| 234 match self { |
302 match self { |
| 235 MyCow::Borrowed(a) => a.cow(), |
303 MyCow::Borrowed(a) => a.cow(), |
| 236 MyCow::Owned(b) => b.cow() |
304 MyCow::Owned(b) => b.cow(), |
| 237 } |
|
| 238 } |
|
| 239 |
|
| 240 #[inline] |
|
| 241 fn ref_instance(&self) -> <BasicDecomposition as Decomposition<X>>::Reference<'_> { |
|
| 242 match self { |
|
| 243 MyCow::Borrowed(a) => a, |
|
| 244 MyCow::Owned(b) => &b, |
|
| 245 } |
305 } |
| 246 } |
306 } |
| 247 } |
307 } |
| 248 |
308 |
| 249 /// Marker type for mutable decompositions to be used with [`InstanceMut`]. |
309 /// Marker type for mutable decompositions to be used with [`InstanceMut`]. |
| 250 pub trait DecompositionMut<X : Space> : Sized { |
310 pub trait DecompositionMut<X: Space>: Sized { |
| 251 type ReferenceMut<'b> : InstanceMut<X, Self> where X : 'b; |
311 type ReferenceMut<'b>: InstanceMut<X, Self> |
| 252 } |
312 where |
| 253 |
313 X: 'b; |
| |
314 } |
| 254 |
315 |
| 255 /// Helper trait for functions to work with mutable references. |
316 /// Helper trait for functions to work with mutable references. |
| 256 pub trait InstanceMut<X : Space , D = <X as Space>::Decomp> : Sized where D : DecompositionMut<X> { |
317 pub trait InstanceMut<X: Space, D = <X as Space>::Decomp>: Sized |
| |
318 where |
| |
319 D: DecompositionMut<X>, |
| |
320 { |
| 257 /// Returns a mutable decomposition of self. |
321 /// Returns a mutable decomposition of self. |
| 258 fn ref_instance_mut(&mut self) -> D::ReferenceMut<'_>; |
322 fn ref_instance_mut(&mut self) -> D::ReferenceMut<'_>; |
| 259 } |
323 } |
| 260 |
324 |
| 261 impl<X : Space> DecompositionMut<X> for BasicDecomposition { |
325 impl<X: Space> DecompositionMut<X> for BasicDecomposition { |
| 262 type ReferenceMut<'b> = &'b mut X where X : 'b; |
326 type ReferenceMut<'b> |
| |
327 = &'b mut X |
| |
328 where |
| |
329 X: 'b; |
| 263 } |
330 } |
| 264 |
331 |
| 265 /// This impl may seem pointless, but allows throwaway mutable scratch variables |
332 /// This impl may seem pointless, but allows throwaway mutable scratch variables |
| 266 impl<'a, X : Space> InstanceMut<X, BasicDecomposition> for X { |
333 impl<'a, X: Space> InstanceMut<X, BasicDecomposition> for X { |
| 267 #[inline] |
334 #[inline] |
| 268 fn ref_instance_mut(&mut self) |
335 fn ref_instance_mut( |
| 269 -> <BasicDecomposition as DecompositionMut<X>>::ReferenceMut<'_> |
336 &mut self, |
| 270 { |
337 ) -> <BasicDecomposition as DecompositionMut<X>>::ReferenceMut<'_> { |
| 271 self |
338 self |
| 272 } |
339 } |
| 273 } |
340 } |
| 274 |
341 |
| 275 impl<'a, X : Space> InstanceMut<X, BasicDecomposition> for &'a mut X { |
342 impl<'a, X: Space> InstanceMut<X, BasicDecomposition> for &'a mut X { |
| 276 #[inline] |
343 #[inline] |
| 277 fn ref_instance_mut(&mut self) |
344 fn ref_instance_mut( |
| 278 -> <BasicDecomposition as DecompositionMut<X>>::ReferenceMut<'_> |
345 &mut self, |
| 279 { |
346 ) -> <BasicDecomposition as DecompositionMut<X>>::ReferenceMut<'_> { |
| 280 self |
347 self |
| 281 } |
348 } |
| 282 } |
349 } |