src/sets/cube.rs

branch
dev
changeset 124
6aa955ad8122
parent 55
7b2ee3e84c5f
equal deleted inserted replaced
122:495448cca603 124:6aa955ad8122
14 # use alg_tools::types::float; 14 # use alg_tools::types::float;
15 let cube : Cube<float, 2> = [[0.0, 1.0], [-1.0, 1.0]].into(); 15 let cube : Cube<float, 2> = [[0.0, 1.0], [-1.0, 1.0]].into();
16 ``` 16 ```
17 */ 17 */
18 18
19 use serde::ser::{Serialize, Serializer, SerializeTupleStruct}; 19 use crate::loc::Loc;
20 use crate::maputil::{map1, map1_indexed, map2, FixedLength, FixedLengthMut};
21 use crate::sets::SetOrd;
20 use crate::types::*; 22 use crate::types::*;
21 use crate::loc::Loc; 23 use serde::ser::{Serialize, SerializeTupleStruct, Serializer};
22 use crate::sets::SetOrd;
23 use crate::maputil::{
24 FixedLength,
25 FixedLengthMut,
26 map1,
27 map1_indexed,
28 map2,
29 };
30 24
31 /// A multi-dimensional cube $∏_{i=1}^N [a_i, b_i)$ with the starting and ending points 25 /// A multi-dimensional cube $∏_{i=1}^N [a_i, b_i)$ with the starting and ending points
32 /// along $a_i$ and $b_i$ along each dimension of type `U`. 26 /// along $a_i$ and $b_i$ along each dimension of type `U`.
33 #[derive(Copy, Clone, Debug, Eq, PartialEq)] 27 #[derive(Copy, Clone, Debug, Eq, PartialEq)]
34 pub struct Cube<U : Num, const N : usize>(pub(super) [[U; 2]; N]); 28 pub struct Cube<const N: usize, U: Num = f64>(pub(super) [[U; 2]; N]);
35 29
36 // Need to manually implement as [F; N] serialisation is provided only for some N. 30 // Need to manually implement as [F; N] serialisation is provided only for some N.
37 impl<F : Num + Serialize, const N : usize> Serialize for Cube<F, N> 31 impl<F: Num + Serialize, const N: usize> Serialize for Cube<N, F>
38 where 32 where
39 F: Serialize, 33 F: Serialize,
40 { 34 {
41 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> 35 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
42 where 36 where
48 } 42 }
49 ts.end() 43 ts.end()
50 } 44 }
51 } 45 }
52 46
53 impl<A : Num, const N : usize> FixedLength<N> for Cube<A,N> { 47 impl<A: Num, const N: usize> FixedLength<N> for Cube<N, A> {
54 type Iter = std::array::IntoIter<[A; 2], N>; 48 type Iter = std::array::IntoIter<[A; 2], N>;
55 type Elem = [A; 2]; 49 type Elem = [A; 2];
56 #[inline] 50 #[inline]
57 fn fl_iter(self) -> Self::Iter { 51 fn fl_iter(self) -> Self::Iter {
58 self.0.into_iter() 52 self.0.into_iter()
59 } 53 }
60 } 54 }
61 55
62 impl<A : Num, const N : usize> FixedLengthMut<N> for Cube<A,N> { 56 impl<A: Num, const N: usize> FixedLengthMut<N> for Cube<N, A> {
63 type IterMut<'a> = std::slice::IterMut<'a, [A; 2]>; 57 type IterMut<'a> = std::slice::IterMut<'a, [A; 2]>;
64 #[inline] 58 #[inline]
65 fn fl_iter_mut(&mut self) -> Self::IterMut<'_> { 59 fn fl_iter_mut(&mut self) -> Self::IterMut<'_> {
66 self.0.iter_mut() 60 self.0.iter_mut()
67 } 61 }
68 } 62 }
69 63
70 impl<'a, A : Num, const N : usize> FixedLength<N> for &'a Cube<A,N> { 64 impl<'a, A: Num, const N: usize> FixedLength<N> for &'a Cube<N, A> {
71 type Iter = std::slice::Iter<'a, [A; 2]>; 65 type Iter = std::slice::Iter<'a, [A; 2]>;
72 type Elem = &'a [A; 2]; 66 type Elem = &'a [A; 2];
73 #[inline] 67 #[inline]
74 fn fl_iter(self) -> Self::Iter { 68 fn fl_iter(self) -> Self::Iter {
75 self.0.iter() 69 self.0.iter()
76 } 70 }
77 } 71 }
78 72
79
80 /// Iterator for [`Cube`] corners. 73 /// Iterator for [`Cube`] corners.
81 pub struct CubeCornersIter<'a, U : Num, const N : usize> { 74 pub struct CubeCornersIter<'a, U: Num, const N: usize> {
82 index : usize, 75 index: usize,
83 cube : &'a Cube<U, N>, 76 cube: &'a Cube<N, U>,
84 } 77 }
85 78
86 impl<'a, U : Num, const N : usize> Iterator for CubeCornersIter<'a, U, N> { 79 impl<'a, U: Num, const N: usize> Iterator for CubeCornersIter<'a, U, N> {
87 type Item = Loc<U, N>; 80 type Item = Loc<N, U>;
88 #[inline] 81 #[inline]
89 fn next(&mut self) -> Option<Self::Item> { 82 fn next(&mut self) -> Option<Self::Item> {
90 if self.index >= N { 83 if self.index >= N {
91 None 84 None
92 } else { 85 } else {
93 let i = self.index; 86 let i = self.index;
94 self.index += 1; 87 self.index += 1;
95 let arr = self.cube.map_indexed(|k, a, b| if (i>>k)&1 == 0 { a } else { b }); 88 let arr = self
89 .cube
90 .map_indexed(|k, a, b| if (i >> k) & 1 == 0 { a } else { b });
96 Some(arr.into()) 91 Some(arr.into())
97 } 92 }
98 } 93 }
99 } 94 }
100 95
101 impl<U : Num, const N : usize> Cube<U, N> { 96 impl<U: Num, const N: usize> Cube<N, U> {
102 /// Maps `f` over the triples $\\{(i, a\_i, b\_i)\\}\_{i=1}^N$ 97 /// Maps `f` over the triples $\\{(i, a\_i, b\_i)\\}\_{i=1}^N$
103 /// of the cube $∏_{i=1}^N [a_i, b_i)$. 98 /// of the cube $∏_{i=1}^N [a_i, b_i)$.
104 #[inline] 99 #[inline]
105 pub fn map_indexed<T>(&self, f : impl Fn(usize, U, U) -> T) -> [T; N] { 100 pub fn map_indexed<T>(&self, f: impl Fn(usize, U, U) -> T) -> [T; N] {
106 map1_indexed(self, |i, &[a, b]| f(i, a, b)) 101 map1_indexed(self, |i, &[a, b]| f(i, a, b))
107 } 102 }
108 103
109 /// Maps `f` over the tuples $\\{(a\_i, b\_i)\\}\_{i=1}^N$ 104 /// Maps `f` over the tuples $\\{(a\_i, b\_i)\\}\_{i=1}^N$
110 /// of the cube $∏_{i=1}^N [a_i, b_i)$. 105 /// of the cube $∏_{i=1}^N [a_i, b_i)$.
111 #[inline] 106 #[inline]
112 pub fn map<T>(&self, f : impl Fn(U, U) -> T) -> [T; N] { 107 pub fn map<T>(&self, f: impl Fn(U, U) -> T) -> [T; N] {
113 map1(self, |&[a, b]| f(a, b)) 108 map1(self, |&[a, b]| f(a, b))
114 } 109 }
115 110
116 /// Iterates over the start and end coordinates $\{(a_i, b_i)\}_{i=1}^N$ of the cube along 111 /// Iterates over the start and end coordinates $\{(a_i, b_i)\}_{i=1}^N$ of the cube along
117 /// each dimension. 112 /// each dimension.
118 #[inline] 113 #[inline]
119 pub fn iter_coords(&self) -> std::slice::Iter<'_, [U; 2]> { 114 pub fn iter_coords(&self) -> std::slice::Iter<'_, [U; 2]> {
120 self.0.iter() 115 self.0.iter()
121 } 116 }
122 117
123 /// Returns the “start” coordinate $a_i$ of the cube $∏_{i=1}^N [a_i, b_i)$. 118 /// Returns the “start” coordinate $a_i$ of the cube $∏_{i=1}^N [a_i, b_i)$.
124 #[inline] 119 #[inline]
125 pub fn start(&self, i : usize) -> U { 120 pub fn start(&self, i: usize) -> U {
126 self.0[i][0] 121 self.0[i][0]
127 } 122 }
128 123
129 /// Returns the end coordinate $a_i$ of the cube $∏_{i=1}^N [a_i, b_i)$. 124 /// Returns the end coordinate $a_i$ of the cube $∏_{i=1}^N [a_i, b_i)$.
130 #[inline] 125 #[inline]
131 pub fn end(&self, i : usize) -> U { 126 pub fn end(&self, i: usize) -> U {
132 self.0[i][1] 127 self.0[i][1]
133 } 128 }
134 129
135 /// Returns the “start” $(a_1, … ,a_N)$ of the cube $∏_{i=1}^N [a_i, b_i)$ 130 /// Returns the “start” $(a_1, … ,a_N)$ of the cube $∏_{i=1}^N [a_i, b_i)$
136 /// spanned between $(a_1, … ,a_N)$ and $(b_1, … ,b_N)$. 131 /// spanned between $(a_1, … ,a_N)$ and $(b_1, … ,b_N)$.
137 #[inline] 132 #[inline]
138 pub fn span_start(&self) -> Loc<U, N> { 133 pub fn span_start(&self) -> Loc<N, U> {
139 Loc::new(self.map(|a, _b| a)) 134 Loc::new(self.map(|a, _b| a))
140 } 135 }
141 136
142 /// Returns the end $(b_1, … ,b_N)$ of the cube $∏_{i=1}^N [a_i, b_i)$ 137 /// Returns the end $(b_1, … ,b_N)$ of the cube $∏_{i=1}^N [a_i, b_i)$
143 /// spanned between $(a_1, … ,a_N)$ and $(b_1, … ,b_N)$. 138 /// spanned between $(a_1, … ,a_N)$ and $(b_1, … ,b_N)$.
144 #[inline] 139 #[inline]
145 pub fn span_end(&self) -> Loc<U, N> { 140 pub fn span_end(&self) -> Loc<N, U> {
146 Loc::new(self.map(|_a, b| b)) 141 Loc::new(self.map(|_a, b| b))
147 } 142 }
148 143
149 /// Iterates over the corners $\{(c_1, … ,c_N) | c_i ∈ \{a_i, b_i\}\}$ of the cube 144 /// Iterates over the corners $\{(c_1, … ,c_N) | c_i ∈ \{a_i, b_i\}\}$ of the cube
150 /// $∏_{i=1}^N [a_i, b_i)$. 145 /// $∏_{i=1}^N [a_i, b_i)$.
151 #[inline] 146 #[inline]
152 pub fn iter_corners(&self) -> CubeCornersIter<'_, U, N> { 147 pub fn iter_corners(&self) -> CubeCornersIter<'_, U, N> {
153 CubeCornersIter{ index : 0, cube : self } 148 CubeCornersIter {
149 index: 0,
150 cube: self,
151 }
154 } 152 }
155 153
156 /// Returns the width-`N`-tuple $(b_1-a_1, … ,b_N-a_N)$ of the cube $∏_{i=1}^N [a_i, b_i)$. 154 /// Returns the width-`N`-tuple $(b_1-a_1, … ,b_N-a_N)$ of the cube $∏_{i=1}^N [a_i, b_i)$.
157 #[inline] 155 #[inline]
158 pub fn width(&self) -> Loc<U, N> { 156 pub fn width(&self) -> Loc<N, U> {
159 Loc::new(self.map(|a, b| b-a)) 157 Loc::new(self.map(|a, b| b - a))
160 } 158 }
161 159
162 /// Translates the cube $∏_{i=1}^N [a_i, b_i)$ by the `shift` $(s_1, … , s_N)$ to 160 /// Translates the cube $∏_{i=1}^N [a_i, b_i)$ by the `shift` $(s_1, … , s_N)$ to
163 /// $∏_{i=1}^N [a_i+s_i, b_i+s_i)$. 161 /// $∏_{i=1}^N [a_i+s_i, b_i+s_i)$.
164 #[inline] 162 #[inline]
165 pub fn shift(&self, shift : &Loc<U, N>) -> Self { 163 pub fn shift(&self, shift: &Loc<N, U>) -> Self {
166 let mut cube = self.clone(); 164 let mut cube = self.clone();
167 for i in 0..N { 165 for i in 0..N {
168 cube.0[i][0] += shift[i]; 166 cube.0[i][0] += shift[i];
169 cube.0[i][1] += shift[i]; 167 cube.0[i][1] += shift[i];
170 } 168 }
171 cube 169 cube
172 } 170 }
173 171
174 /// Creates a new cube from an array. 172 /// Creates a new cube from an array.
175 #[inline] 173 #[inline]
176 pub fn new(data : [[U; 2]; N]) -> Self { 174 pub fn new(data: [[U; 2]; N]) -> Self {
177 Cube(data) 175 Cube(data)
178 } 176 }
179 } 177 }
180 178
181 impl<F : Float, const N : usize> Cube<F, N> { 179 impl<F: Float, const N: usize> Cube<N, F> {
182 /// Returns the centre of the cube 180 /// Returns the centre of the cube
183 pub fn center(&self) -> Loc<F, N> { 181 pub fn center(&self) -> Loc<N, F> {
184 map1(self, |&[a, b]| (a + b) / F::TWO).into() 182 map1(self, |&[a, b]| (a + b) / F::TWO).into()
185 } 183 }
186 } 184 }
187 185
188 impl<U : Num> Cube<U, 1> { 186 impl<U: Num> Cube<1, U> {
189 /// Get the corners of the cube. 187 /// Get the corners of the cube.
190 /// 188 ///
191 /// TODO: generic implementation once const-generics can be involved in 189 /// TODO: generic implementation once const-generics can be involved in
192 /// calculations. 190 /// calculations.
193 #[inline] 191 #[inline]
194 pub fn corners(&self) -> [Loc<U, 1>; 2] { 192 pub fn corners(&self) -> [Loc<1, U>; 2] {
195 let [[a, b]] = self.0; 193 let [[a, b]] = self.0;
196 [a.into(), b.into()] 194 [a.into(), b.into()]
197 } 195 }
198 } 196 }
199 197
200 impl<U : Num> Cube<U, 2> { 198 impl<U: Num> Cube<2, U> {
201 /// Get the corners of the cube in counter-clockwise order. 199 /// Get the corners of the cube in counter-clockwise order.
202 /// 200 ///
203 /// TODO: generic implementation once const-generics can be involved in 201 /// TODO: generic implementation once const-generics can be involved in
204 /// calculations. 202 /// calculations.
205 #[inline] 203 #[inline]
206 pub fn corners(&self) -> [Loc<U, 2>; 4] { 204 pub fn corners(&self) -> [Loc<2, U>; 4] {
207 let [[a1, b1], [a2, b2]]=self.0; 205 let [[a1, b1], [a2, b2]] = self.0;
208 [[a1, a2].into(), 206 [
209 [b1, a2].into(), 207 [a1, a2].into(),
210 [b1, b2].into(), 208 [b1, a2].into(),
211 [a1, b2].into()] 209 [b1, b2].into(),
212 } 210 [a1, b2].into(),
213 } 211 ]
214 212 }
215 impl<U : Num> Cube<U, 3> { 213 }
214
215 impl<U: Num> Cube<3, U> {
216 /// Get the corners of the cube. 216 /// Get the corners of the cube.
217 /// 217 ///
218 /// TODO: generic implementation once const-generics can be involved in 218 /// TODO: generic implementation once const-generics can be involved in
219 /// calculations. 219 /// calculations.
220 #[inline] 220 #[inline]
221 pub fn corners(&self) -> [Loc<U, 3>; 8] { 221 pub fn corners(&self) -> [Loc<3, U>; 8] {
222 let [[a1, b1], [a2, b2], [a3, b3]]=self.0; 222 let [[a1, b1], [a2, b2], [a3, b3]] = self.0;
223 [[a1, a2, a3].into(), 223 [
224 [b1, a2, a3].into(), 224 [a1, a2, a3].into(),
225 [b1, b2, a3].into(), 225 [b1, a2, a3].into(),
226 [a1, b2, a3].into(), 226 [b1, b2, a3].into(),
227 [a1, b2, b3].into(), 227 [a1, b2, a3].into(),
228 [b1, b2, b3].into(), 228 [a1, b2, b3].into(),
229 [b1, a2, b3].into(), 229 [b1, b2, b3].into(),
230 [a1, a2, b3].into()] 230 [b1, a2, b3].into(),
231 [a1, a2, b3].into(),
232 ]
231 } 233 }
232 } 234 }
233 235
234 // TODO: Implement Add and Sub of Loc to Cube, and Mul and Div by U : Num. 236 // TODO: Implement Add and Sub of Loc to Cube, and Mul and Div by U : Num.
235 237
236 impl<U : Num, const N : usize> From<[[U; 2]; N]> for Cube<U, N> { 238 impl<U: Num, const N: usize> From<[[U; 2]; N]> for Cube<N, U> {
237 #[inline] 239 #[inline]
238 fn from(data : [[U; 2]; N]) -> Self { 240 fn from(data: [[U; 2]; N]) -> Self {
239 Cube(data) 241 Cube(data)
240 } 242 }
241 } 243 }
242 244
243 impl<U : Num, const N : usize> From<Cube<U, N>> for [[U; 2]; N] { 245 impl<U: Num, const N: usize> From<Cube<N, U>> for [[U; 2]; N] {
244 #[inline] 246 #[inline]
245 fn from(Cube(data) : Cube<U, N>) -> Self { 247 fn from(Cube(data): Cube<N, U>) -> Self {
246 data 248 data
247 } 249 }
248 } 250 }
249 251
250 252 impl<U, const N: usize> Cube<N, U>
251 impl<U, const N : usize> Cube<U, N> where U : Num + PartialOrd { 253 where
254 U: Num + PartialOrd,
255 {
252 /// Checks whether the cube is non-degenerate, i.e., the start coordinate 256 /// Checks whether the cube is non-degenerate, i.e., the start coordinate
253 /// of each axis is strictly less than the end coordinate. 257 /// of each axis is strictly less than the end coordinate.
254 #[inline] 258 #[inline]
255 pub fn nondegenerate(&self) -> bool { 259 pub fn nondegenerate(&self) -> bool {
256 self.0.iter().all(|range| range[0] < range[1]) 260 self.0.iter().all(|range| range[0] < range[1])
257 } 261 }
258 262
259 /// Checks whether the cube intersects some `other` cube. 263 /// Checks whether the cube intersects some `other` cube.
260 /// Matching boundary points are not counted, so `U` is ideally a [`Float`]. 264 /// Matching boundary points are not counted, so `U` is ideally a [`Float`].
261 #[inline] 265 #[inline]
262 pub fn intersects(&self, other : &Cube<U, N>) -> bool { 266 pub fn intersects(&self, other: &Cube<N, U>) -> bool {
263 self.iter_coords().zip(other.iter_coords()).all(|([a1, b1], [a2, b2])| { 267 self.iter_coords()
264 a1 < b2 && a2 < b1 268 .zip(other.iter_coords())
265 }) 269 .all(|([a1, b1], [a2, b2])| a1 < b2 && a2 < b1)
266 } 270 }
267 271
268 /// Checks whether the cube contains some `other` cube. 272 /// Checks whether the cube contains some `other` cube.
269 pub fn contains_set(&self, other : &Cube<U, N>) -> bool { 273 pub fn contains_set(&self, other: &Cube<N, U>) -> bool {
270 self.iter_coords().zip(other.iter_coords()).all(|([a1, b1], [a2, b2])| { 274 self.iter_coords()
271 a1 <= a2 && b1 >= b2 275 .zip(other.iter_coords())
272 }) 276 .all(|([a1, b1], [a2, b2])| a1 <= a2 && b1 >= b2)
273 } 277 }
274 278
275 /// Produces the point of minimum $ℓ^p$-norm within the cube `self` for any $p$-norm. 279 /// Produces the point of minimum $ℓ^p$-norm within the cube `self` for any $p$-norm.
276 /// This is the point where each coordinate is closest to zero. 280 /// This is the point where each coordinate is closest to zero.
277 #[inline] 281 #[inline]
278 pub fn minnorm_point(&self) -> Loc<U, N> { 282 pub fn minnorm_point(&self) -> Loc<N, U> {
279 let z = U::ZERO; 283 let z = U::ZERO;
280 // As always, we assume that a ≤ b. 284 // As always, we assume that a ≤ b.
281 self.map(|a, b| { 285 self.map(|a, b| {
282 debug_assert!(a <= b); 286 debug_assert!(a <= b);
283 match (a < z, z < b) { 287 match (a < z, z < b) {
284 (false, _) => a, 288 (false, _) => a,
285 (_, false) => b, 289 (_, false) => b,
286 (true, true) => z 290 (true, true) => z,
287 } 291 }
288 }).into() 292 })
293 .into()
289 } 294 }
290 295
291 /// Produces the point of maximum $ℓ^p$-norm within the cube `self` for any $p$-norm. 296 /// Produces the point of maximum $ℓ^p$-norm within the cube `self` for any $p$-norm.
292 /// This is the point where each coordinate is furthest from zero. 297 /// This is the point where each coordinate is furthest from zero.
293 #[inline] 298 #[inline]
294 pub fn maxnorm_point(&self) -> Loc<U, N> { 299 pub fn maxnorm_point(&self) -> Loc<N, U> {
295 let z = U::ZERO; 300 let z = U::ZERO;
296 // As always, we assume that a ≤ b. 301 // As always, we assume that a ≤ b.
297 self.map(|a, b| { 302 self.map(|a, b| {
298 debug_assert!(a <= b); 303 debug_assert!(a <= b);
299 match (a < z, z < b) { 304 match (a < z, z < b) {
300 (false, _) => b, 305 (false, _) => b,
301 (_, false) => a, 306 (_, false) => a,
302 // A this stage we must have a < 0 (so U must be signed), and want to check 307 // A this stage we must have a < 0 (so U must be signed), and want to check
303 // whether |a| > |b|. We can do this without assuming U to actually implement 308 // whether |a| > |b|. We can do this without assuming U to actually implement
304 // `Neg` by comparing whether 0 > a + b. 309 // `Neg` by comparing whether 0 > a + b.
305 (true, true) => if z > a + b { a } else { b } 310 (true, true) => {
311 if z > a + b {
312 a
313 } else {
314 b
315 }
316 }
306 } 317 }
307 }).into() 318 })
319 .into()
308 } 320 }
309 } 321 }
310 322
311 macro_rules! impl_common { 323 macro_rules! impl_common {
312 ($($t:ty)*, $min:ident, $max:ident) => { $( 324 ($($t:ty)*, $min:ident, $max:ident) => { $(
313 impl<const N : usize> SetOrd for Cube<$t, N> { 325 impl<const N : usize> SetOrd for Cube<N, $t> {
314 #[inline] 326 #[inline]
315 fn common(&self, other : &Self) -> Self { 327 fn common(&self, other : &Self) -> Self {
316 map2(self, other, |&[a1, b1], &[a2, b2]| { 328 map2(self, other, |&[a1, b1], &[a2, b2]| {
317 debug_assert!(a1 <= b1 && a2 <= b2); 329 debug_assert!(a1 <= b1 && a2 <= b2);
318 [a1.$min(a2), b1.$max(b2)] 330 [a1.$min(a2), b1.$max(b2)]
336 348
337 // Any NaN yields NaN 349 // Any NaN yields NaN
338 #[cfg(feature = "nightly")] 350 #[cfg(feature = "nightly")]
339 impl_common!(f32 f64, minimum, maximum); 351 impl_common!(f32 f64, minimum, maximum);
340 352
341 impl<U : Num, const N : usize> std::ops::Index<usize> for Cube<U, N> { 353 impl<U: Num, const N: usize> std::ops::Index<usize> for Cube<N, U> {
342 type Output = [U; 2]; 354 type Output = [U; 2];
343 #[inline] 355 #[inline]
344 fn index(&self, index: usize) -> &Self::Output { 356 fn index(&self, index: usize) -> &Self::Output {
345 &self.0[index] 357 &self.0[index]
346 } 358 }
347 } 359 }
348 360
349 impl<U : Num, const N : usize> std::ops::IndexMut<usize> for Cube<U, N> { 361 impl<U: Num, const N: usize> std::ops::IndexMut<usize> for Cube<N, U> {
350 #[inline] 362 #[inline]
351 fn index_mut(&mut self, index: usize) -> &mut Self::Output { 363 fn index_mut(&mut self, index: usize) -> &mut Self::Output {
352 &mut self.0[index] 364 &mut self.0[index]
353 } 365 }
354 } 366 }

mercurial