orx_iterable/collection_mut.rs
1use crate::{
2 transformations::{
3 ChainedCol, FilteredCol, FlattenedCol, FusedCol, ReversedCol, SkippedCol, SkippedWhileCol,
4 SteppedByCol, TakenCol, TakenWhileCol,
5 },
6 Collection, Iterable,
7};
8
9/// A mutable collection providing the `iter_mut` method which returns an iterator over mutable references
10/// of elements of the collection.
11///
12/// Since it extends `Collection`, `iter` method is also available which returns an iterator over shared references
13/// of elements.
14///
15/// # Auto Implementations
16///
17/// Consider a collection type `X` storing elements of type `T`. Provided that the following implementations are provided:
18///
19/// * `X: IntoIterator<Item = T>`
20/// * `&X: IntoIterator<Item = &T>`
21/// * `&mut X: IntoIterator<Item = &mut T>`
22///
23/// Then, `X` implements `Collection<Item = T>` and `CollectionMut<Item = T>`.
24/// Further, `&X` implements `Iterable<Item = &T>`.
25///
26/// # Examples
27///
28/// ```
29/// use orx_iterable::*;
30/// use arrayvec::ArrayVec;
31/// use smallvec::{smallvec, SmallVec};
32/// use std::collections::{LinkedList, VecDeque};
33///
34/// /// first computes sum, and then adds it to each of the elements
35/// fn increment_by_sum(numbers: &mut impl CollectionMut<Item = i32>) {
36/// let sum: i32 = numbers.iter().sum();
37///
38/// for x in numbers.iter_mut() {
39/// *x += sum;
40/// }
41/// }
42///
43/// // example collections that automatically implement CollectionMut
44///
45/// let mut x = [1, 2, 3];
46/// increment_by_sum(&mut x);
47/// assert_eq!(x, [7, 8, 9]);
48///
49/// let mut x = vec![1, 2, 3];
50/// increment_by_sum(&mut x);
51///
52/// let mut x = LinkedList::from_iter([1, 2, 3]);
53/// increment_by_sum(&mut x);
54///
55/// let mut x = VecDeque::from_iter([1, 2, 3]);
56/// increment_by_sum(&mut x);
57///
58/// let mut x: SmallVec<[_; 128]> = smallvec![3, 5, 7];
59/// increment_by_sum(&mut x);
60///
61/// let mut x = ArrayVec::<_, 16>::new();
62/// x.extend([3, 5, 7]);
63/// increment_by_sum(&mut x);
64/// ```
65pub trait CollectionMut: Collection {
66 /// Type of the iterator yielding mutable references created by the [`iter_mut`] method.
67 ///
68 /// [`iter_mut`]: crate::CollectionMut::iter_mut
69 type IterMut<'i>: Iterator<Item = &'i mut Self::Item>
70 where
71 Self: 'i;
72
73 /// Creates a new iterator yielding mutable references to the elements of the collection; i.e.,
74 /// type of elements is `&mut Collection::Item`.
75 fn iter_mut(&mut self) -> Self::IterMut<'_>;
76
77 // provided
78
79 /// Combines mutable references of this collection and `other`; and creates an iterable collection which
80 /// is a chain of these two collections.
81 ///
82 /// Note that this method does not change the memory locations of the elements; i.e.,
83 /// the elements still live in two separate collections; however, now chained together.
84 ///
85 /// # Examples
86 ///
87 /// ```
88 /// use orx_iterable::*;
89 ///
90 /// let mut a = vec!['a', 'b'];
91 /// let mut b = ['c', 'd', 'e'];
92 ///
93 /// let mut it = a.chained_mut(&mut b);
94 ///
95 /// *it.iter_mut().last().unwrap() = 'x';
96 ///
97 /// assert_eq!(it.iter().count(), 5);
98 /// assert_eq!(it.iter().collect::<Vec<_>>(), vec![&'a', &'b', &'c', &'d', &'x']);
99 ///
100 /// // neither a nor b is consumed
101 /// assert_eq!(a, ['a', 'b']);
102 /// assert_eq!(b, ['c', 'd', 'x']);
103 /// ```
104 fn chained_mut<'a, I>(
105 &'a mut self,
106 other: &'a mut I,
107 ) -> ChainedCol<Self, I, &'a mut Self, &'a mut I>
108 where
109 Self: Sized,
110 I: CollectionMut<Item = Self::Item>,
111 {
112 ChainedCol {
113 it1: self,
114 it2: other,
115 phantom: Default::default(),
116 }
117 }
118
119 /// Creates an iterable collection view which is a filtered version of this collection from its mutable reference.
120 ///
121 /// # Examples
122 ///
123 /// ```
124 /// use orx_iterable::*;
125 ///
126 /// let mut a = [0i32, 1, 2];
127 ///
128 /// let mut it = a.filtered_mut(|x| x.is_positive());
129 ///
130 /// for x in it.iter_mut() {
131 /// *x *= 2;
132 /// }
133 ///
134 /// assert_eq!(it.iter().count(), 2);
135 /// assert_eq!(it.iter().collect::<Vec<_>>(), [&2, &4]);
136 ///
137 /// // a is not consumed
138 /// assert_eq!(a, [0, 2, 4]);
139 /// ```
140 fn filtered_mut<P>(&mut self, filter: P) -> FilteredCol<Self, &mut Self, P>
141 where
142 Self: Sized,
143 P: Fn(&Self::Item) -> bool + Copy,
144 {
145 FilteredCol {
146 it: self,
147 filter,
148 phantom: Default::default(),
149 }
150 }
151
152 /// Creates an iterable collection view which is a flattened version of this collection from its mutable reference.
153 ///
154 /// # Examples
155 ///
156 /// ```
157 /// use orx_iterable::*;
158 ///
159 /// let mut data = vec![vec![1, 2, 3, 4], vec![5, 6]];
160 ///
161 /// let mut it = data.flattened_mut();
162 ///
163 /// for x in it.iter_mut() {
164 /// *x *= 2;
165 /// }
166 ///
167 /// assert_eq!(it.iter().count(), 6);
168 /// assert_eq!(it.iter().sum::<u32>(), 2 * 21);
169 ///
170 /// // data is not consumed
171 /// assert_eq!(data, [vec![2, 4, 6, 8], vec![10, 12]]);
172 /// ```
173 fn flattened_mut(&mut self) -> FlattenedCol<Self, &mut Self>
174 where
175 Self: Sized,
176 Self::Item: IntoIterator,
177 for<'i> &'i Self::Item: IntoIterator<Item = &'i <Self::Item as IntoIterator>::Item>,
178 for<'i> &'i mut Self::Item: IntoIterator<Item = &'i mut <Self::Item as IntoIterator>::Item>,
179 {
180 FlattenedCol {
181 it: self,
182 phantom: Default::default(),
183 }
184 }
185
186 /// Creates an iterable collection view which is a fused version of this collection from its mutable reference.
187 ///
188 /// See [`core::iter::Fuse`] for details on fused iterators.
189 fn fused_mut(&mut self) -> FusedCol<Self, &mut Self>
190 where
191 Self: Sized,
192 {
193 FusedCol {
194 it: self,
195 phantom: Default::default(),
196 }
197 }
198
199 /// Creates an iterable collection view which is a reversed version of this collection from its mutable reference.
200 ///
201 /// # Examples
202 ///
203 /// ```
204 /// use orx_iterable::*;
205 ///
206 /// let mut data = vec![vec![1, 2, 3, 4], vec![5, 6]];
207 ///
208 /// let mut a = [1, 2, 3];
209 ///
210 /// let mut it = a.reversed_mut();
211 /// *it.iter_mut().next().unwrap() += 10;
212 /// assert_eq!(it.iter().collect::<Vec<_>>(), [&13, &2, &1]);
213 /// ```
214 fn reversed_mut(&mut self) -> ReversedCol<Self, &mut Self>
215 where
216 Self: Sized,
217 for<'b> <Self::Iterable<'b> as Iterable>::Iter: DoubleEndedIterator,
218 for<'b> Self::IterMut<'b>: DoubleEndedIterator,
219 {
220 ReversedCol {
221 it: self,
222 phantom: Default::default(),
223 }
224 }
225
226 /// Creates an iterable collection view which is skipped-by-`n` version of this collection from its mutable reference.
227 ///
228 /// # Examples
229 ///
230 /// ```
231 /// use orx_iterable::*;
232 ///
233 /// let mut a = [1, 2, 3, 4, 5];
234 ///
235 /// let mut it = a.skipped_mut(2);
236 ///
237 /// for x in it.iter_mut() {
238 /// *x += 10;
239 /// }
240 ///
241 /// assert_eq!(it.iter().collect::<Vec<_>>(), [&13, &14, &15]);
242 ///
243 /// assert_eq!(a, [1, 2, 13, 14, 15]);
244 /// ```
245 fn skipped_mut(&mut self, n: usize) -> SkippedCol<Self, &mut Self>
246 where
247 Self: Sized,
248 {
249 SkippedCol {
250 it: self,
251 n,
252 phantom: Default::default(),
253 }
254 }
255
256 /// Creates an iterable collection view which is skipped-while version of this collection from its mutable reference.
257 ///
258 /// # Examples
259 ///
260 /// ```
261 /// use orx_iterable::*;
262 ///
263 /// let mut a = [-1i32, 0, 1];
264 ///
265 /// let mut it = a.skipped_while_mut(|x| x.is_negative());
266 ///
267 /// for x in it.iter_mut() {
268 /// *x += 10;
269 /// }
270 ///
271 /// assert_eq!(it.iter().collect::<Vec<_>>(), [&10, &11]);
272 ///
273 /// assert_eq!(a, [-1, 10, 11]);
274 /// ```
275 fn skipped_while_mut<P>(&mut self, skip_while: P) -> SkippedWhileCol<Self, &mut Self, P>
276 where
277 Self: Sized,
278 P: Fn(&Self::Item) -> bool + Copy,
279 {
280 SkippedWhileCol {
281 it: self,
282 skip_while,
283 phantom: Default::default(),
284 }
285 }
286
287 /// Creates an iterable collection view which is stepped-by-`step` version of this collection from its mutable reference.
288 ///
289 /// # Examples
290 ///
291 /// ```
292 /// use orx_iterable::*;
293 ///
294 /// let mut a = [0, 1, 2, 3, 4, 5];
295 ///
296 /// let mut it = a.stepped_by_mut(2);
297 ///
298 /// for x in it.iter_mut() {
299 /// *x *= 10;
300 /// }
301 ///
302 /// assert_eq!(it.iter().collect::<Vec<_>>(), [&0, &20, &40]);
303 ///
304 /// assert_eq!(a, [0, 1, 20, 3, 40, 5]);
305 /// ```
306 fn stepped_by_mut(&mut self, step: usize) -> SteppedByCol<Self, &mut Self>
307 where
308 Self: Sized,
309 {
310 SteppedByCol {
311 it: self,
312 step,
313 phantom: Default::default(),
314 }
315 }
316
317 /// Creates an iterable collection view which is taken-`n` version of this collection from its mutable reference.
318 ///
319 /// # Examples
320 ///
321 /// ```
322 /// use orx_iterable::*;
323 ///
324 /// let mut a = [1, 2, 3, 4, 5];
325 ///
326 /// let mut it = a.taken_mut(3);
327 ///
328 /// for x in it.iter_mut() {
329 /// *x += 10;
330 /// }
331 ///
332 /// assert_eq!(it.iter().collect::<Vec<_>>(), [&11, &12, &13]);
333 ///
334 /// assert_eq!(a, [11, 12, 13, 4, 5]);
335 /// ```
336 fn taken_mut(&mut self, n: usize) -> TakenCol<Self, &mut Self>
337 where
338 Self: Sized,
339 {
340 TakenCol {
341 it: self,
342 n,
343 phantom: Default::default(),
344 }
345 }
346
347 /// Creates an iterable collection view which is taken-while version of this collection from its mutable reference.
348 ///
349 /// # Examples
350 ///
351 /// ```
352 /// use orx_iterable::*;
353 ///
354 /// let mut a = [-1i32, 0, 1];
355 ///
356 /// let mut it = a.taken_while_mut(|x| x.is_negative());
357 ///
358 /// for x in it.iter_mut() {
359 /// *x *= 10;
360 /// }
361 ///
362 /// assert_eq!(it.iter().collect::<Vec<_>>(), [&-10]);
363 ///
364 /// assert_eq!(a, [-10, 0, 1]);
365 /// ```
366 fn taken_while_mut<P>(&mut self, take_while: P) -> TakenWhileCol<Self, &mut Self, P>
367 where
368 Self: Sized,
369 P: Fn(&Self::Item) -> bool + Copy,
370 {
371 TakenWhileCol {
372 it: self,
373 take_while,
374 phantom: Default::default(),
375 }
376 }
377}
378
379impl<X> CollectionMut for X
380where
381 X: IntoIterator,
382 for<'a> &'a X: IntoIterator<Item = &'a <X as IntoIterator>::Item>,
383 for<'a> &'a mut X: IntoIterator<Item = &'a mut <X as IntoIterator>::Item>,
384{
385 type IterMut<'i>
386 = <&'i mut X as IntoIterator>::IntoIter
387 where
388 Self: 'i;
389
390 fn iter_mut(&mut self) -> Self::IterMut<'_> {
391 <&mut X as IntoIterator>::into_iter(self)
392 }
393}