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;