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
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
//! GAT equivalent of `std` iterator traits, often referred to as a lending iterator

mod adapters;

pub use adapters::*;

/// # Safety:
/// This is only safe to use if the item provided is sound to have a lifetime of `'b`.
///
/// This is true in cases such as the polonius borrow case and when the user is sure the value can
/// actually live for the desired time.
unsafe fn change_lifetime<'a, 'b, I: ?Sized + Iterator>(i: I::Item<'a>) -> I::Item<'b> {
    // SAFETY: This functions preconditions assure this is sound
    unsafe { core::mem::transmute::<I::Item<'a>, I::Item<'b>>(i) }
}

/// A lending iterator, whose items may have their lifetimes tied to the individual borrow of the
/// iterator. This allows for things like yielding mutable references that overlap, with the
/// trade-off that there's no generic `collect` interface - the items of this iterator cannot
/// co-exist.
pub trait Iterator {
    /// The value yielded by each call to `next` on this iterator
    type Item<'a>
    where
        Self: 'a;

    /// Get the next value of this iterator, or return `None`
    fn next(&mut self) -> Option<Self::Item<'_>>;

    /// Get a hint as to the size of this iterator - the first value is a lower bound, second
    /// is an optional upper bound.
    fn size_hint(&self) -> (usize, Option<usize>) {
        (0, None)
    }

    /// Advance the iterator by `n` elements
    fn advance_by(&mut self, n: usize) -> Result<(), usize> {
        let mut idx = 0;
        while idx < n {
            if self.next().is_none() {
                return Err(idx);
            }
            idx += 1;
        }
        Ok(())
    }

    /// Return the `n`th element of the iterator
    ///
    /// This does not rewind the iterator after completion, so repeatedly calling `nth(0)` is
    /// equivalent to calling `next`
    fn nth(&mut self, mut n: usize) -> Option<Self::Item<'_>> {
        while n > 0 {
            self.next()?;
            n -= 1;
        }
        self.next()
    }

    // Lazy Adaptors

    /// Take a closure which will take each value from the iterator, and yield a new value computed
    /// from it.
    ///
    /// The result cannot reference the provided data, as such, this returns an iterator which also
    /// implements the non-lending core iterator
    fn map<O, F>(self, f: F) -> Map<Self, F>
    where
        Self: Sized,
        F: FnMut(Self::Item<'_>) -> O,
    {
        Map::new(self, f)
    }

    /// Gain mutable access to each value in this iterator, then yield it to the next step.
    /// This allows altering each item without consuming it, preserving the lending nature
    /// or the iterator
    fn touch<F>(self, f: F) -> Touch<Self, F>
    where
        Self: Sized,
        F: FnMut(&mut Self::Item<'_>),
    {
        Touch::new(self, f)
    }

    /// Execute a closure on each item in the iterator, returning true if it should be included, or
    /// false to skip it
    fn filter<F>(self, f: F) -> Filter<Self, F>
    where
        Self: Sized,
        F: FnMut(&Self::Item<'_>) -> bool,
    {
        Filter::new(self, f)
    }

    /// Creates an iterator starting at the same point, but stepping by the given amount at each
    /// iteration
    fn step_by(self, step: usize) -> StepBy<Self>
    where
        Self: Sized,
    {
        assert_ne!(step, 0);
        StepBy::new(self, step)
    }

    /// Takes two iterators and creates a new iterator over both in sequence
    fn chain<U>(self, other: U) -> Chain<Self, U::IntoIter>
    where
        Self: Sized,
        U: IntoIterator,
        U::IntoIter: for<'a> Iterator<Item<'a> = Self::Item<'a>>,
    {
        Chain::new(self, other.into_iter())
    }

    /// ‘Zips up’ two iterators into a single iterator of pairs
    fn zip<U>(self, other: U) -> Zip<Self, U::IntoIter>
    where
        Self: Sized,
        U: IntoIterator,
    {
        Zip::new(self, other.into_iter())
    }

    /// Creates an iterator which gives the current iteration count as well as the next value
    fn enumerate(self) -> Enumerate<Self>
    where
        Self: Sized,
    {
        Enumerate::new(self)
    }

    /// Creates an iterator that skips elements based on a predicate
    fn skip_while<F>(self, f: F) -> SkipWhile<Self, F>
    where
        Self: Sized,
        F: FnMut(&Self::Item<'_>) -> bool,
    {
        SkipWhile::new(self, f)
    }

    /// Creates an iterator that yields elements based on a predicate
    fn take_while<F>(self, f: F) -> TakeWhile<Self, F>
    where
        Self: Sized,
        F: FnMut(&Self::Item<'_>) -> bool,
    {
        TakeWhile::new(self, f)
    }

    /// Creates an iterator that skips the first n elements
    fn skip(self, n: usize) -> Skip<Self>
    where
        Self: Sized,
    {
        Skip::new(self, n)
    }

    /// Creates an iterator that yields the first n elements, or fewer if the underlying iterator
    /// ends sooner
    fn take(self, n: usize) -> Take<Self>
    where
        Self: Sized,
    {
        Take::new(self, n)
    }

    // Consumers

    /// Tests if every element of the iterator matches a predicate
    fn all<F>(&mut self, mut f: F) -> bool
    where
        F: FnMut(Self::Item<'_>) -> bool,
    {
        while let Some(val) = self.next() {
            if !f(val) {
                return false;
            }
        }
        true
    }

    /// Tests if any element of the iterator matches a predicate
    fn any<F>(&mut self, mut f: F) -> bool
    where
        F: FnMut(Self::Item<'_>) -> bool,
    {
        while let Some(val) = self.next() {
            if f(val) {
                return true;
            }
        }
        false
    }

    /// Searches for an element of an iterator that satisfies a predicate
    fn find<F>(&mut self, mut f: F) -> Option<Self::Item<'_>>
    where
        F: FnMut(&Self::Item<'_>) -> bool,
    {
        while let Some(val) = self.next() {
            if f(&val) {
                // SAFETY: Polonius case
                return Some(unsafe { change_lifetime::<Self>(val) });
            }
        }
        None
    }

    /// Consume the iterator, counting the number of items and returning it
    fn count(self) -> usize
    where
        Self: Sized,
    {
        self.fold(0, |acc, _| acc + 1)
    }

    /// Execute a closure on each value of this iterator
    fn for_each<F>(mut self, mut f: F)
    where
        Self: Sized,
        F: FnMut(Self::Item<'_>),
    {
        while let Some(next) = self.next() {
            f(next)
        }
    }

    /// Execute a closure on each value of this iterator, with an additional 'accumulator' value
    /// passed to each call. The closure is expected to return the new value of the accumulator.
    fn fold<T, F>(mut self, acc: T, mut f: F) -> T
    where
        Self: Sized,
        F: FnMut(T, Self::Item<'_>) -> T,
    {
        let mut acc = acc;
        while let Some(x) = self.next() {
            acc = f(acc, x);
        }
        acc
    }

    /// Execute a closure on each value of this iterator, with an additional state value passed
    /// via mutable reference to each call. The closure is expected to return the new value
    /// for each step of the iterator, if the returned value is `None` the iterator stops early.
    ///
    /// The result cannot reference the provided data, as such, this returns an iterator which also
    /// implements the non-lending core iterator
    fn scan<T, B, F>(self, acc: T, f: F) -> Scan<Self, T, F>
    where
        Self: Sized,
        F: FnMut(&mut T, Self::Item<'_>) -> Option<B>,
    {
        Scan::new(self, acc, f)
    }
}

/// Trait for values which can be converted into an [`Iterator`]
pub trait IntoIterator {
    /// The type of the returned iterator
    type IntoIter: Iterator;

    /// Convert this value into an [`Iterator`]
    fn into_iter(self) -> Self::IntoIter;
}

impl<T> IntoIterator for T
where
    T: Iterator,
{
    type IntoIter = T;

    fn into_iter(self) -> Self::IntoIter {
        self
    }
}

/// Trait for converting a normal, non-lending iterator into a lending iterator.
///
/// This is useful for methods such as [`Iterator::zip`], where you may want to combine a standard
/// iterator onto a lending one.
pub trait IntoLending: Sized {
    /// Convert this iterator into a lending one
    fn into_lending(self) -> FromCore<Self>;
}

impl<I> IntoLending for I
where
    I: core::iter::Iterator,
{
    fn into_lending(self) -> FromCore<Self> {
        FromCore(self)
    }
}

#[cfg(test)]
mod test;