gat_lending_iterator/traits/
lending_iterator.rs

1use core::cmp::Ordering;
2use std::{num::NonZeroUsize, ops::Deref};
3
4use crate::{
5    Chain, Cloned, Enumerate, Filter, FilterMap, Map, OptionTrait, SingleArgFnMut, SingleArgFnOnce, Skip, SkipWhile, StepBy, Take, TakeWhile, Zip
6};
7
8/// Like [`Iterator`], but items may borrow from `&mut self`.
9///
10/// This means that the compiler will check that you finish using an item
11/// before requesting the next item, as it's not allowed for two `&mut self` to exist
12/// at the same time.
13pub trait LendingIterator {
14    /// The type of the elements being iterated over.
15    type Item<'a>
16    where
17        Self: 'a;
18
19    /// Advances the lending iterator and returns the next value.
20    ///
21    /// See [`Iterator::next`].
22    fn next(&mut self) -> Option<Self::Item<'_>>;
23
24    /// Returns the bounds on the remaining length of the iterator.
25    ///
26    /// See [`Iterator::size_hint`].
27    #[inline]
28    fn size_hint(&self) -> (usize, Option<usize>) {
29        (0, None)
30    }
31
32    /// Returns the number of items in the lending iterator.
33    ///
34    /// See [`Iterator::count`].
35    #[inline]
36    fn count(self) -> usize
37    where
38        Self: Sized,
39    {
40        self.fold(0, |count, _| count + 1)
41    }
42
43    /// Advances the lending iterator by `n` elements.
44    ///
45    /// See [`Iterator::advance_by`].
46    #[inline]
47    #[allow(clippy::missing_errors_doc)]
48    fn advance_by(&mut self, n: usize) -> Result<(), NonZeroUsize> {
49        for i in 0..n {
50            if self.next().is_none() {
51                // SAFETY: `i` is always less than `n`.
52                return Err(unsafe { NonZeroUsize::new_unchecked(n - i) });
53            }
54        }
55        Ok(())
56    }
57
58    /// Returns the `n`th element of the lending iterator.
59    ///
60    /// See [`Iterator::nth`].
61    #[inline]
62    fn nth(&mut self, n: usize) -> Option<Self::Item<'_>> {
63        self.advance_by(n).ok()?;
64        self.next()
65    }
66
67    /// Creates a lending iterator starting at the same point, but stepping by
68    /// the given amount at each iteration.
69    ///
70    /// See [`Iterator::step_by`].
71    #[inline]
72    fn step_by(self, step: usize) -> StepBy<Self>
73    where
74        Self: Sized,
75    {
76        StepBy::new(self, step)
77    }
78
79    /// Creates a lending iterator that lends the first `n` elements, or fewer
80    /// if the underlying iterator ends sooner.
81    ///
82    /// See [`Iterator::take`].
83    #[inline]
84    fn take(self, n: usize) -> Take<Self>
85    where
86        Self: Sized,
87    {
88        Take::new(self, n)
89    }
90
91    /// Creates a lending iterator that lends items matching a predicate.
92    ///
93    /// The predicate is called once for every item.
94    /// Once it returns false once, `None` is returned for all subsequent calls to [`next`].
95    ///
96    /// [`next`]: Self::next
97    #[inline]
98    fn take_while<P>(self, predicate: P) -> TakeWhile<Self, P>
99    where
100        Self: Sized,
101        P: for<'a> FnMut(&Self::Item<'a>) -> bool,
102    {
103        TakeWhile::new(self, predicate)
104    }
105
106    /// Takes two lending iterators and creates a new lending iterator over both in sequence.
107    ///
108    /// See [`Iterator::chain`].
109    #[inline]
110    fn chain<I>(self, other: I) -> Chain<Self, I>
111    where
112        Self: Sized,
113        for<'a> I: LendingIterator<Item<'a> = Self::Item<'a>> + 'a,
114    {
115        Chain::new(self, other)
116    }
117
118    /// 'Zips up' two lending iterators into a single lending iterator of pairs.
119    #[inline]
120    fn zip<I>(self, other: I) -> Zip<Self, I>
121    where
122        Self: Sized,
123        I: LendingIterator,
124    {
125        Zip::new(self, other)
126    }
127
128    /// Takes a closure and creates a lending iterator which calls that closure on each
129    /// element.
130    ///
131    /// As of writing, in stable rust it's not possible to create a closure
132    /// where the lifetime of its output is tied to its input.
133    /// If you're on nightly, you can use the unstable
134    /// `closure_lifetime_binder` feature. If you're on stable, try using
135    /// a function.
136    ///
137    /// In the case that the closure's return type doesn't borrow from its input,
138    /// the resulting `LendingIterator` will implement [`IntoIterator`].
139    ///
140    /// See [`Iterator::map`].
141    #[inline]
142    fn map<F>(self, f: F) -> Map<Self, F>
143    where
144        Self: Sized,
145        F: for<'a> SingleArgFnMut<Self::Item<'a>>,
146    {
147        Map::new(self, f)
148    }
149
150    /// Calls a closure on each element of the lending iterator.
151    ///
152    /// See [`Iterator::for_each`].
153    #[inline]
154    fn for_each<F>(mut self, mut f: F)
155    where
156        Self: Sized,
157        F: FnMut(Self::Item<'_>),
158    {
159        while let Some(item) = self.next() {
160            f(item);
161        }
162    }
163
164    /// Creates a lending iterator which uses a closure to determine if an element
165    /// should be yielded.
166    ///
167    /// See [`Iterator::filter`].
168    #[inline]
169    fn filter<P>(self, predicate: P) -> Filter<Self, P>
170    where
171        Self: Sized,
172        P: for<'a> FnMut(&Self::Item<'a>) -> bool,
173    {
174        Filter::new(self, predicate)
175    }
176
177    /// Creates a lending iterator that both filters and maps.
178    ///
179    /// See [`Iterator::filter_map`].
180    #[inline]
181    fn filter_map<F>(self, f: F) -> FilterMap<Self, F>
182    where
183        Self: Sized,
184        F: for<'a> SingleArgFnMut<Self::Item<'a>>,
185        for<'a> <F as SingleArgFnOnce<Self::Item<'a>>>::Output: OptionTrait,
186    {
187        FilterMap::new(self, f)
188    }
189
190    /// Folds every element into an accumulator by applying an operation,
191    /// returning the final result.
192    ///
193    /// See [`Iterator::fold`].
194    #[inline]
195    fn fold<B, F>(mut self, init: B, mut f: F) -> B
196    where
197        Self: Sized,
198        F: FnMut(B, Self::Item<'_>) -> B,
199    {
200        let mut accum = init;
201        while let Some(x) = self.next() {
202            accum = f(accum, x);
203        }
204        accum
205    }
206
207    /// Creates a lending iterator which [`clone`]s all of its elements.
208    ///
209    /// The resulting lending iterator implements [`IntoIterator`].
210    ///
211    /// See [`Iterator::cloned`].
212    ///
213    /// [`clone`]: Clone::clone
214    fn cloned<T>(self) -> Cloned<Self>
215    where
216        Self: Sized,
217        for<'a> Self::Item<'a>: Deref<Target = T>,
218        T: Clone,
219    {
220        Cloned::new(self)
221    }
222
223    /// Creates a lending iterator which gives the current iteration count as well as the next value.
224    #[inline]
225    fn enumerate(self) -> Enumerate<Self>
226    where
227        Self: Sized,
228    {
229        Enumerate::new(self)
230    }
231
232    /// Creates a lending iterator that skips over the first `n` elements of self.
233    #[inline]
234    fn skip(self, n: usize) -> Skip<Self>
235    where
236        Self: Sized,
237    {
238        Skip::new(self, n)
239    }
240
241    /// Creates a lending iterator that rejects elements while `predicate` returns `true`.
242    #[inline]
243    fn skip_while<P>(self, predicate: P) -> SkipWhile<Self, P>
244    where
245        Self: Sized,
246        P: for<'a> FnMut(&Self::Item<'a>) -> bool,
247    {
248        SkipWhile::new(self, predicate)
249    }
250
251    /// Borrows the lending iterator.
252    /// 
253    /// This is useful to allow applying iterator adapters while still
254    /// retaining ownership of the original iterator.
255    /// 
256    /// Unfortunately adapters that take in a closure are currently
257    /// incompatible with this, due to limitations in the borrow checker.
258    #[inline]
259    fn by_ref(&mut self) -> &mut Self
260    where
261        Self: Sized,
262    {
263        self
264    }
265
266    /// Tests if every element of the iterator matches a predicate.
267    #[inline]
268    fn all<P>(&mut self, mut predicate: P) -> bool
269    where
270        P: FnMut(Self::Item<'_>) -> bool,
271    {
272        while let Some(item) = self.next() {
273            if !predicate(item) {
274                return false;
275            }
276        }
277        true
278    }
279
280    /// Tests if any element of the iterator matches a predicate.
281    #[inline]
282    fn any<P>(&mut self, mut predicate: P) -> bool
283    where
284        P: FnMut(Self::Item<'_>) -> bool,
285    {
286        while let Some(item) = self.next() {
287            if predicate(item) {
288                return true;
289            }
290        }
291        false
292    }
293
294    /// Checks if the elements of this iterator are partitioned according to the given predicate,
295    /// such that all those that return `true` precede all those that return `false`.
296    #[inline]
297    #[allow(clippy::wrong_self_convention)]
298    fn is_partitioned<P>(mut self, mut predicate: P) -> bool
299    where
300        Self: Sized,
301        P: FnMut(Self::Item<'_>) -> bool,
302    {
303        while let Some(item) = self.next() {
304            if !predicate(item) {
305                break
306            }
307        }
308        while let Some(item) = self.next() {
309            if predicate(item) {
310                return false
311            }
312        }
313        true
314    }
315
316    /// Searches for an element of an iterator that satisfies a predicate.
317    #[inline]
318    fn find<P>(&mut self, mut predicate: P) -> Option<Self::Item<'_>>
319    where
320        P: FnMut(&Self::Item<'_>) -> bool,
321    {
322        loop {
323            // SAFETY: see https://docs.rs/polonius-the-crab/0.3.1/polonius_the_crab/#the-arcanemagic
324            let self_ = unsafe { &mut *(self as *mut Self) };
325            if let Some(item) = self_.next() {
326                if (predicate)(&item) {
327                    return Some(item);
328                }
329            } else {
330                return None;
331            }
332        }
333    }
334
335    /// Applies function to the elements of iterator and returns
336    /// the first non-none result.
337    #[inline]
338    fn find_map<B, F>(&mut self, mut f: F) -> Option<B>
339    where
340        F: FnMut(Self::Item<'_>) -> Option<B>,
341    {
342        loop {
343            // SAFETY: see https://docs.rs/polonius-the-crab/0.3.1/polonius_the_crab/#the-arcanemagic
344            let self_ = unsafe { &mut *(self as *mut Self) };
345            if let Some(item) = self_.next() {
346                if let Some(result) = f(item) {
347                    return Some(result);
348                }
349            } else {
350                return None;
351            }
352        }
353    }
354
355    /// Searches for an element in an iterator, returning its index.
356    #[inline]
357    fn position<P>(&mut self, mut predicate: P) -> Option<usize>
358    where
359        P: FnMut(Self::Item<'_>) -> bool,
360    {
361        let mut i = 0;
362        while let Some(item) = self.next() {
363            if predicate(item) {
364                return Some(i);
365            }
366            i += 1;
367        }
368        None
369    }
370
371    /// [Lexicographically](Ord#lexicographical-comparison) compares the elements of this [`Iterator`] with those
372    /// of another.
373    fn cmp<I>(mut self, mut other: I) -> Ordering
374    where
375        I: for<'a> LendingIterator<Item<'a> = Self::Item<'a>>,
376        for<'a> Self::Item<'a>: Ord,
377        Self: Sized,
378    {
379        // TODO: this could be implemented as `self.cmp_by(other, |x, y| x.cmp(y))`
380        // except that doesn't type check due to lifetime issues.
381        loop {
382            match (self.next(), other.next()) {
383                (Some(x), Some(y)) => match x.cmp(&y) {
384                    Ordering::Equal => continue,
385                    non_eq => return non_eq,
386                },
387                (None, None) => return Ordering::Equal,
388                (None, _) => return Ordering::Less,
389                (_, None) => return Ordering::Greater,
390            }
391        }
392    }
393
394    /// [Lexicographically](Ord#lexicographical-comparison) compares the elements of this [`Iterator`] with those
395    /// of another with respect to the specified comparison function.
396    fn cmp_by<I, F>(mut self, mut other: I, mut cmp: F) -> Ordering
397    where
398        Self: Sized,
399        I: LendingIterator,
400        F: FnMut(Self::Item<'_>, I::Item<'_>) -> Ordering,
401    {
402        loop {
403            match (self.next(), other.next()) {
404                (Some(x), Some(y)) => match cmp(x, y) {
405                    Ordering::Equal => continue,
406                    non_eq => return non_eq,
407                },
408                (None, None) => return Ordering::Equal,
409                (None, _) => return Ordering::Less,
410                (_, None) => return Ordering::Greater,
411            }
412        }
413    }
414
415    /// [Lexicographically](Ord#lexicographical-comparison) compares the [`PartialOrd`] elements of
416    /// this [`Iterator`] with those of another. The comparison works like short-circuit
417    /// evaluation, returning a result without comparing the remaining elements.
418    /// As soon as an order can be determined, the evaluation stops and a result is returned.
419    fn partial_cmp<I>(mut self, mut other: I) -> Option<Ordering>
420    where
421        I: LendingIterator,
422        for<'a> Self::Item<'a>: PartialOrd<I::Item<'a>>,
423        Self: Sized,
424    {
425        loop {
426            match (self.next(), other.next()) {
427                (Some(x), Some(y)) => match x.partial_cmp(&y) {
428                    Some(Ordering::Equal) => continue,
429                    non_eq => return non_eq,
430                },
431                (None, None) => return Some(Ordering::Equal),
432                (None, _) => return Some(Ordering::Less),
433                (_, None) => return Some(Ordering::Greater),
434            }
435        }
436    }
437
438    /// [Lexicographically](Ord#lexicographical-comparison) compares the elements of this [`Iterator`] with those
439    /// of another with respect to the specified comparison function.
440    fn partial_cmp_by<I, F>(mut self, mut other: I, mut partial_cmp: F) -> Option<Ordering>
441    where
442        Self: Sized,
443        I: LendingIterator,
444        F: FnMut(Self::Item<'_>, I::Item<'_>) -> Option<Ordering>,
445    {
446        loop {
447            match (self.next(), other.next()) {
448                (Some(x), Some(y)) => match partial_cmp(x, y) {
449                    Some(Ordering::Equal) => continue,
450                    non_eq => return non_eq,
451                },
452                (None, None) => return Some(Ordering::Equal),
453                (None, _) => return Some(Ordering::Less),
454                (_, None) => return Some(Ordering::Greater),
455            }
456        }
457    }
458
459    /// Determines if the elements of this [`Iterator`] are equal to those of
460    /// another.
461    fn eq<I>(mut self, mut other: I) -> bool
462    where
463        I: LendingIterator,
464        for<'a> Self::Item<'a>: PartialEq<I::Item<'a>>,
465        Self: Sized,
466    {
467        loop {
468            match (self.next(), other.next()) {
469                (Some(x), Some(y)) => if x != y {
470                    return false;
471                },
472                (None, None) => return true,
473                _ => return false,
474            }
475        }
476    }
477
478    /// Determines if the elements of this [`Iterator`] are equal to those of
479    /// another with respect to the specified equality function.
480    fn eq_by<I, F>(mut self, mut other: I, mut eq: F) -> bool
481    where
482        Self: Sized,
483        I: LendingIterator,
484        F: FnMut(Self::Item<'_>, I::Item<'_>) -> bool,
485    {
486        loop {
487            match (self.next(), other.next()) {
488                (Some(x), Some(y)) => if !eq(x, y) {
489                    return false;
490                },
491                (None, None) => return true,
492                _ => return false,
493            }
494        }
495    }
496
497    /// Determines if the elements of this [`Iterator`] are not equal to those of
498    /// another.
499    fn ne<I>(self, other: I) -> bool
500    where
501        I: LendingIterator,
502        for<'a> Self::Item<'a>: PartialEq<I::Item<'a>>,
503        Self: Sized,
504    {
505        !self.eq(other)
506    }
507
508    /// Determines if the elements of this [`Iterator`] are [lexicographically](Ord#lexicographical-comparison)
509    /// less than those of another.
510    fn lt<I>(self, other: I) -> bool
511    where
512        I: LendingIterator,
513        for<'a> Self::Item<'a>: PartialOrd<I::Item<'a>>,
514        Self: Sized,
515    {
516        self.partial_cmp(other) == Some(Ordering::Less)
517    }
518
519    /// Determines if the elements of this [`Iterator`] are [lexicographically](Ord#lexicographical-comparison)
520    /// less or equal to those of another.
521    fn le<I>(self, other: I) -> bool
522    where
523        I: LendingIterator,
524        for<'a> Self::Item<'a>: PartialOrd<I::Item<'a>>,
525        Self: Sized,
526    {
527        matches!(self.partial_cmp(other), Some(Ordering::Less | Ordering::Equal))
528    }
529
530    /// Determines if the elements of this [`Iterator`] are [lexicographically](Ord#lexicographical-comparison)
531    /// greater than those of another.
532    fn gt<I>(self, other: I) -> bool
533    where
534        I: LendingIterator,
535        for<'a> Self::Item<'a>: PartialOrd<I::Item<'a>>,
536        Self: Sized,
537    {
538        self.partial_cmp(other) == Some(Ordering::Greater)
539    }
540
541    /// Determines if the elements of this [`Iterator`] are [lexicographically](Ord#lexicographical-comparison)
542    /// greater or equal to those of another.
543    fn ge<I>(self, other: I) -> bool
544    where
545        I: LendingIterator,
546        for<'a> Self::Item<'a>: PartialOrd<I::Item<'a>>,
547        Self: Sized,
548    {
549        matches!(self.partial_cmp(other), Some(Ordering::Greater | Ordering::Equal))
550    }
551}
552
553impl<T: LendingIterator> LendingIterator for &mut T {
554    type Item<'a> = T::Item<'a> where Self: 'a;
555
556    #[inline]
557    fn next(&mut self) -> Option<Self::Item<'_>> {
558        (**self).next()
559    }
560
561    #[inline]
562    fn size_hint(&self) -> (usize, Option<usize>) {
563        (**self).size_hint()
564    }
565}