calc_lib/
lending_iterator.rs

1/// Generalizes [`Iterator`] by allowing one to yield references.
2pub trait LendingIterator {
3    /// Read [`Iterator::Item`].
4    type Item<'a>
5    where
6        Self: 'a;
7    /// Read [`Iterator::next`].
8    fn lend_next(&mut self) -> Option<Self::Item<'_>>;
9    /// Read [`Iterator::size_hint`].
10    #[inline]
11    fn size_hint(&self) -> (usize, Option<usize>) {
12        (0, None)
13    }
14    /// Read [`Iterator::count`].
15    #[expect(
16        clippy::arithmetic_side_effects,
17        reason = "must, and overflow is no worry"
18    )]
19    #[inline]
20    fn count(self) -> usize
21    where
22        Self: Sized,
23    {
24        self.lend_fold(0, |count, _| count + 1)
25    }
26    /// Read [`Iterator::advance_by`].
27    ///
28    /// # Errors
29    ///
30    /// Read [`Iterator::advance_by`].
31    #[inline]
32    fn advance_by(&mut self, n: usize) -> Result<(), usize> {
33        for i in 0..n {
34            drop(self.lend_next().ok_or(i)?);
35        }
36        Ok(())
37    }
38    /// Read [`Iterator::by_ref`].
39    #[inline]
40    fn by_ref(&mut self) -> &mut Self
41    where
42        Self: Sized,
43    {
44        self
45    }
46    /// Read [`Iterator::try_fold`].
47    /// # Errors
48    ///
49    /// Read [`Iterator::try_fold`].
50    #[inline]
51    fn lend_try_fold<B, E, F>(&mut self, init: B, mut f: F) -> Result<B, E>
52    where
53        Self: Sized,
54        F: FnMut(B, Self::Item<'_>) -> Result<B, E>,
55    {
56        let mut accum = init;
57        while let Some(x) = self.lend_next() {
58            accum = f(accum, x)?;
59        }
60        Ok(accum)
61    }
62    /// Read [`Iterator::fold`].
63    #[inline]
64    fn lend_fold<B, F>(mut self, init: B, mut f: F) -> B
65    where
66        Self: Sized,
67        F: FnMut(B, Self::Item<'_>) -> B,
68    {
69        let mut accum = init;
70        while let Some(x) = self.lend_next() {
71            accum = f(accum, x);
72        }
73        accum
74    }
75}
76impl<T> LendingIterator for T
77where
78    T: Iterator,
79{
80    type Item<'a>
81        = T::Item
82    where
83        Self: 'a;
84    #[inline]
85    fn lend_next(&mut self) -> Option<Self::Item<'_>> {
86        self.next()
87    }
88    #[inline]
89    fn size_hint(&self) -> (usize, Option<usize>) {
90        self.size_hint()
91    }
92    #[inline]
93    fn count(self) -> usize
94    where
95        Self: Sized,
96    {
97        self.count()
98    }
99    #[inline]
100    fn advance_by(&mut self, n: usize) -> Result<(), usize> {
101        for i in 0..n {
102            drop(self.lend_next().ok_or(i)?);
103        }
104        Ok(())
105    }
106    #[inline]
107    fn by_ref(&mut self) -> &mut Self
108    where
109        Self: Sized,
110    {
111        self
112    }
113    // Due to a bug in GATs, fold and try_fold cannot be
114    // implemented.
115}