gat_std/
iter.rs

1//! GAT equivalent of `std` iterator traits, often referred to as a lending iterator
2
3mod adapters;
4
5pub use adapters::*;
6
7/// # Safety:
8/// This is only safe to use if the item provided is sound to have a lifetime of `'b`.
9///
10/// This is true in cases such as the polonius borrow case and when the user is sure the value can
11/// actually live for the desired time.
12unsafe fn change_lifetime<'a, 'b, I: ?Sized + Iterator>(i: I::Item<'a>) -> I::Item<'b> {
13    // SAFETY: This functions preconditions assure this is sound
14    unsafe { core::mem::transmute::<I::Item<'a>, I::Item<'b>>(i) }
15}
16
17/// A lending iterator, whose items may have their lifetimes tied to the individual borrow of the
18/// iterator. This allows for things like yielding mutable references that overlap, with the
19/// trade-off that there's no generic `collect` interface - the items of this iterator cannot
20/// co-exist.
21pub trait Iterator {
22    /// The value yielded by each call to `next` on this iterator
23    type Item<'a>
24    where
25        Self: 'a;
26
27    /// Get the next value of this iterator, or return `None`
28    fn next(&mut self) -> Option<Self::Item<'_>>;
29
30    /// Get a hint as to the size of this iterator - the first value is a lower bound, second
31    /// is an optional upper bound.
32    fn size_hint(&self) -> (usize, Option<usize>) {
33        (0, None)
34    }
35
36    /// Advance the iterator by `n` elements
37    fn advance_by(&mut self, n: usize) -> Result<(), usize> {
38        let mut idx = 0;
39        while idx < n {
40            if self.next().is_none() {
41                return Err(idx);
42            }
43            idx += 1;
44        }
45        Ok(())
46    }
47
48    /// Return the `n`th element of the iterator
49    ///
50    /// This does not rewind the iterator after completion, so repeatedly calling `nth(0)` is
51    /// equivalent to calling `next`
52    fn nth(&mut self, mut n: usize) -> Option<Self::Item<'_>> {
53        while n > 0 {
54            self.next()?;
55            n -= 1;
56        }
57        self.next()
58    }
59
60    // Lazy Adaptors
61
62    /// Take a closure which will take each value from the iterator, and yield a new value computed
63    /// from it.
64    ///
65    /// The result cannot reference the provided data, as such, this returns an iterator which also
66    /// implements the non-lending core iterator
67    fn map<O, F>(self, f: F) -> Map<Self, F>
68    where
69        Self: Sized,
70        F: FnMut(Self::Item<'_>) -> O,
71    {
72        Map::new(self, f)
73    }
74
75    /// Gain mutable access to each value in this iterator, then yield it to the next step.
76    /// This allows altering each item without consuming it, preserving the lending nature
77    /// or the iterator
78    fn touch<F>(self, f: F) -> Touch<Self, F>
79    where
80        Self: Sized,
81        F: FnMut(&mut Self::Item<'_>),
82    {
83        Touch::new(self, f)
84    }
85
86    /// Execute a closure on each item in the iterator, returning true if it should be included, or
87    /// false to skip it
88    fn filter<F>(self, f: F) -> Filter<Self, F>
89    where
90        Self: Sized,
91        F: FnMut(&Self::Item<'_>) -> bool,
92    {
93        Filter::new(self, f)
94    }
95
96    /// Creates an iterator starting at the same point, but stepping by the given amount at each
97    /// iteration
98    fn step_by(self, step: usize) -> StepBy<Self>
99    where
100        Self: Sized,
101    {
102        assert_ne!(step, 0);
103        StepBy::new(self, step)
104    }
105
106    /// Takes two iterators and creates a new iterator over both in sequence
107    fn chain<U>(self, other: U) -> Chain<Self, U::IntoIter>
108    where
109        Self: Sized,
110        U: IntoIterator,
111        U::IntoIter: for<'a> Iterator<Item<'a> = Self::Item<'a>>,
112    {
113        Chain::new(self, other.into_iter())
114    }
115
116    /// ‘Zips up’ two iterators into a single iterator of pairs
117    fn zip<U>(self, other: U) -> Zip<Self, U::IntoIter>
118    where
119        Self: Sized,
120        U: IntoIterator,
121    {
122        Zip::new(self, other.into_iter())
123    }
124
125    /// Creates an iterator which gives the current iteration count as well as the next value
126    fn enumerate(self) -> Enumerate<Self>
127    where
128        Self: Sized,
129    {
130        Enumerate::new(self)
131    }
132
133    /// Creates an iterator that skips elements based on a predicate
134    fn skip_while<F>(self, f: F) -> SkipWhile<Self, F>
135    where
136        Self: Sized,
137        F: FnMut(&Self::Item<'_>) -> bool,
138    {
139        SkipWhile::new(self, f)
140    }
141
142    /// Creates an iterator that yields elements based on a predicate
143    fn take_while<F>(self, f: F) -> TakeWhile<Self, F>
144    where
145        Self: Sized,
146        F: FnMut(&Self::Item<'_>) -> bool,
147    {
148        TakeWhile::new(self, f)
149    }
150
151    /// Creates an iterator that skips the first n elements
152    fn skip(self, n: usize) -> Skip<Self>
153    where
154        Self: Sized,
155    {
156        Skip::new(self, n)
157    }
158
159    /// Creates an iterator that yields the first n elements, or fewer if the underlying iterator
160    /// ends sooner
161    fn take(self, n: usize) -> Take<Self>
162    where
163        Self: Sized,
164    {
165        Take::new(self, n)
166    }
167
168    // Consumers
169
170    /// Tests if every element of the iterator matches a predicate
171    fn all<F>(&mut self, mut f: F) -> bool
172    where
173        F: FnMut(Self::Item<'_>) -> bool,
174    {
175        while let Some(val) = self.next() {
176            if !f(val) {
177                return false;
178            }
179        }
180        true
181    }
182
183    /// Tests if any element of the iterator matches a predicate
184    fn any<F>(&mut self, mut f: F) -> bool
185    where
186        F: FnMut(Self::Item<'_>) -> bool,
187    {
188        while let Some(val) = self.next() {
189            if f(val) {
190                return true;
191            }
192        }
193        false
194    }
195
196    /// Searches for an element of an iterator that satisfies a predicate
197    fn find<F>(&mut self, mut f: F) -> Option<Self::Item<'_>>
198    where
199        F: FnMut(&Self::Item<'_>) -> bool,
200    {
201        while let Some(val) = self.next() {
202            if f(&val) {
203                // SAFETY: Polonius case
204                return Some(unsafe { change_lifetime::<Self>(val) });
205            }
206        }
207        None
208    }
209
210    /// Consume the iterator, counting the number of items and returning it
211    fn count(self) -> usize
212    where
213        Self: Sized,
214    {
215        self.fold(0, |acc, _| acc + 1)
216    }
217
218    /// Execute a closure on each value of this iterator
219    fn for_each<F>(mut self, mut f: F)
220    where
221        Self: Sized,
222        F: FnMut(Self::Item<'_>),
223    {
224        while let Some(next) = self.next() {
225            f(next)
226        }
227    }
228
229    /// Execute a closure on each value of this iterator, with an additional 'accumulator' value
230    /// passed to each call. The closure is expected to return the new value of the accumulator.
231    fn fold<T, F>(mut self, acc: T, mut f: F) -> T
232    where
233        Self: Sized,
234        F: FnMut(T, Self::Item<'_>) -> T,
235    {
236        let mut acc = acc;
237        while let Some(x) = self.next() {
238            acc = f(acc, x);
239        }
240        acc
241    }
242
243    /// Execute a closure on each value of this iterator, with an additional state value passed
244    /// via mutable reference to each call. The closure is expected to return the new value
245    /// for each step of the iterator, if the returned value is `None` the iterator stops early.
246    ///
247    /// The result cannot reference the provided data, as such, this returns an iterator which also
248    /// implements the non-lending core iterator
249    fn scan<T, B, F>(self, acc: T, f: F) -> Scan<Self, T, F>
250    where
251        Self: Sized,
252        F: FnMut(&mut T, Self::Item<'_>) -> Option<B>,
253    {
254        Scan::new(self, acc, f)
255    }
256}
257
258/// Trait for values which can be converted into an [`Iterator`]
259pub trait IntoIterator {
260    /// The type of the returned iterator
261    type IntoIter: Iterator;
262
263    /// Convert this value into an [`Iterator`]
264    fn into_iter(self) -> Self::IntoIter;
265}
266
267impl<T> IntoIterator for T
268where
269    T: Iterator,
270{
271    type IntoIter = T;
272
273    fn into_iter(self) -> Self::IntoIter {
274        self
275    }
276}
277
278/// Trait for converting a normal, non-lending iterator into a lending iterator.
279///
280/// This is useful for methods such as [`Iterator::zip`], where you may want to combine a standard
281/// iterator onto a lending one.
282pub trait IntoLending: Sized {
283    /// Convert this iterator into a lending one
284    fn into_lending(self) -> FromCore<Self>;
285}
286
287impl<I> IntoLending for I
288where
289    I: core::iter::Iterator,
290{
291    fn into_lending(self) -> FromCore<Self> {
292        FromCore(self)
293    }
294}
295
296#[cfg(test)]
297mod test;