| 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 |
| 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 |