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}