src/instance.rs

branch
dev
changeset 133
2b13f8a0c8ba
parent 88
086a59b3a2b4
child 134
d65377920b00
child 136
22fd33834ab7
child 150
c4e394a9c84c
equal deleted inserted replaced
132:89371dc4d637 133:2b13f8a0c8ba
23 } 23 }
24 } 24 }
25 25
26 impl<'b, X> MyCow<'b, X> { 26 impl<'b, X> MyCow<'b, X> {
27 #[inline] 27 #[inline]
28 pub fn into_owned(self) -> X where X : Clone { 28 pub fn into_owned(self) -> X
29 where
30 X: Clone,
31 {
29 match self { 32 match self {
30 EitherDecomp::Owned(x) => x, 33 EitherDecomp::Owned(x) => x,
31 EitherDecomp::Borrowed(x) => x.clone(), 34 EitherDecomp::Borrowed(x) => x.clone(),
32 } 35 }
33 } 36 }
34 } 37 }
35 38
36 /// Trait for abitrary mathematical spaces. 39 /// Trait for abitrary mathematical spaces.
37 pub trait Space : Instance<Self, Self::Decomp> { 40 pub trait Space: Instance<Self, Self::Decomp> {
38 /// Default decomposition for the space 41 /// Default decomposition for the space
39 type Decomp : Decomposition<Self>; 42 type Decomp: Decomposition<Self>;
40 } 43 }
41 44
42 #[macro_export] 45 #[macro_export]
43 macro_rules! impl_basic_space { 46 macro_rules! impl_basic_space {
44 ($($type:ty)*) => { $( 47 ($($type:ty)*) => { $(
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 }

mercurial