1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
/// Generalizes [`Iterator`] by allowing one to yield references.
pub trait LendingIterator {
    /// Read [`Iterator::Item`].
    type Item<'a>
    where
        Self: 'a;
    /// Read [`Iterator::next`].
    fn lend_next(&mut self) -> Option<Self::Item<'_>>;
    /// Read [`Iterator::size_hint`].
    #[inline]
    fn size_hint(&self) -> (usize, Option<usize>) {
        (0, None)
    }
    /// Read [`Iterator::count`].
    #[allow(clippy::arithmetic_side_effects)]
    #[inline]
    fn count(self) -> usize
    where
        Self: Sized,
    {
        self.lend_fold(0, |count, _| count + 1)
    }
    /// Read [`Iterator::advance_by`].

    /// # Errors
    ///
    /// Read [`Iterator::advance_by`].
    #[inline]
    fn advance_by(&mut self, n: usize) -> Result<(), usize> {
        for i in 0..n {
            self.lend_next().ok_or(i)?;
        }
        Ok(())
    }
    /// Read [`Iterator::by_ref`].
    #[inline]
    fn by_ref(&mut self) -> &mut Self
    where
        Self: Sized,
    {
        self
    }
    /// Read [`Iterator::try_fold`].
    /// # Errors
    ///
    /// Read [`Iterator::try_fold`].
    #[inline]
    fn lend_try_fold<B, E, F>(&mut self, init: B, mut f: F) -> Result<B, E>
    where
        Self: Sized,
        F: FnMut(B, Self::Item<'_>) -> Result<B, E>,
    {
        let mut accum = init;
        while let Some(x) = self.lend_next() {
            accum = f(accum, x)?;
        }
        Ok(accum)
    }
    /// Read [`Iterator::fold`].
    #[inline]
    fn lend_fold<B, F>(mut self, init: B, mut f: F) -> B
    where
        Self: Sized,
        F: FnMut(B, Self::Item<'_>) -> B,
    {
        let mut accum = init;
        while let Some(x) = self.lend_next() {
            accum = f(accum, x);
        }
        accum
    }
}
impl<T> LendingIterator for T
where
    T: Iterator,
{
    type Item<'a> = T::Item where Self: 'a;
    #[inline]
    fn lend_next(&mut self) -> Option<Self::Item<'_>> {
        self.next()
    }
    #[inline]
    fn size_hint(&self) -> (usize, Option<usize>) {
        self.size_hint()
    }
    #[inline]
    fn count(self) -> usize
    where
        Self: Sized,
    {
        self.count()
    }
    #[inline]
    fn advance_by(&mut self, n: usize) -> Result<(), usize> {
        for i in 0..n {
            self.lend_next().ok_or(i)?;
        }
        Ok(())
    }
    #[inline]
    fn by_ref(&mut self) -> &mut Self
    where
        Self: Sized,
    {
        self
    }
    // Due to a bug in GATs, fold and try_fold cannot be
    // implemented.
}