1 | use crate::iter::adapters::SourceIter; |
2 | use crate::iter::{FusedIterator, TrustedLen}; |
3 | use crate::ops::{ControlFlow, Try}; |
4 | |
5 | /// An iterator with a `peek()` that returns an optional reference to the next |
6 | /// element. |
7 | /// |
8 | /// This `struct` is created by the [`peekable`] method on [`Iterator`]. See its |
9 | /// documentation for more. |
10 | /// |
11 | /// [`peekable`]: Iterator::peekable |
12 | /// [`Iterator`]: trait.Iterator.html |
13 | #[derive (Clone, Debug)] |
14 | #[must_use = "iterators are lazy and do nothing unless consumed" ] |
15 | #[stable (feature = "rust1" , since = "1.0.0" )] |
16 | #[rustc_diagnostic_item = "IterPeekable" ] |
17 | pub struct Peekable<I: Iterator> { |
18 | iter: I, |
19 | /// Remember a peeked value, even if it was None. |
20 | peeked: Option<Option<I::Item>>, |
21 | } |
22 | |
23 | impl<I: Iterator> Peekable<I> { |
24 | pub(in crate::iter) fn new(iter: I) -> Peekable<I> { |
25 | Peekable { iter, peeked: None } |
26 | } |
27 | } |
28 | |
29 | // Peekable must remember if a None has been seen in the `.peek()` method. |
30 | // It ensures that `.peek(); .peek();` or `.peek(); .next();` only advances the |
31 | // underlying iterator at most once. This does not by itself make the iterator |
32 | // fused. |
33 | #[stable (feature = "rust1" , since = "1.0.0" )] |
34 | impl<I: Iterator> Iterator for Peekable<I> { |
35 | type Item = I::Item; |
36 | |
37 | #[inline ] |
38 | fn next(&mut self) -> Option<I::Item> { |
39 | match self.peeked.take() { |
40 | Some(v) => v, |
41 | None => self.iter.next(), |
42 | } |
43 | } |
44 | |
45 | #[inline ] |
46 | #[rustc_inherit_overflow_checks ] |
47 | fn count(mut self) -> usize { |
48 | match self.peeked.take() { |
49 | Some(None) => 0, |
50 | Some(Some(_)) => 1 + self.iter.count(), |
51 | None => self.iter.count(), |
52 | } |
53 | } |
54 | |
55 | #[inline ] |
56 | fn nth(&mut self, n: usize) -> Option<I::Item> { |
57 | match self.peeked.take() { |
58 | Some(None) => None, |
59 | Some(v @ Some(_)) if n == 0 => v, |
60 | Some(Some(_)) => self.iter.nth(n - 1), |
61 | None => self.iter.nth(n), |
62 | } |
63 | } |
64 | |
65 | #[inline ] |
66 | fn last(mut self) -> Option<I::Item> { |
67 | let peek_opt = match self.peeked.take() { |
68 | Some(None) => return None, |
69 | Some(v) => v, |
70 | None => None, |
71 | }; |
72 | self.iter.last().or(peek_opt) |
73 | } |
74 | |
75 | #[inline ] |
76 | fn size_hint(&self) -> (usize, Option<usize>) { |
77 | let peek_len = match self.peeked { |
78 | Some(None) => return (0, Some(0)), |
79 | Some(Some(_)) => 1, |
80 | None => 0, |
81 | }; |
82 | let (lo, hi) = self.iter.size_hint(); |
83 | let lo = lo.saturating_add(peek_len); |
84 | let hi = match hi { |
85 | Some(x) => x.checked_add(peek_len), |
86 | None => None, |
87 | }; |
88 | (lo, hi) |
89 | } |
90 | |
91 | #[inline ] |
92 | fn try_fold<B, F, R>(&mut self, init: B, mut f: F) -> R |
93 | where |
94 | Self: Sized, |
95 | F: FnMut(B, Self::Item) -> R, |
96 | R: Try<Output = B>, |
97 | { |
98 | let acc = match self.peeked.take() { |
99 | Some(None) => return try { init }, |
100 | Some(Some(v)) => f(init, v)?, |
101 | None => init, |
102 | }; |
103 | self.iter.try_fold(acc, f) |
104 | } |
105 | |
106 | #[inline ] |
107 | fn fold<Acc, Fold>(self, init: Acc, mut fold: Fold) -> Acc |
108 | where |
109 | Fold: FnMut(Acc, Self::Item) -> Acc, |
110 | { |
111 | let acc = match self.peeked { |
112 | Some(None) => return init, |
113 | Some(Some(v)) => fold(init, v), |
114 | None => init, |
115 | }; |
116 | self.iter.fold(acc, fold) |
117 | } |
118 | } |
119 | |
120 | #[stable (feature = "double_ended_peek_iterator" , since = "1.38.0" )] |
121 | impl<I> DoubleEndedIterator for Peekable<I> |
122 | where |
123 | I: DoubleEndedIterator, |
124 | { |
125 | #[inline ] |
126 | fn next_back(&mut self) -> Option<Self::Item> { |
127 | match self.peeked.as_mut() { |
128 | Some(v @ Some(_)) => self.iter.next_back().or_else(|| v.take()), |
129 | Some(None) => None, |
130 | None => self.iter.next_back(), |
131 | } |
132 | } |
133 | |
134 | #[inline ] |
135 | fn try_rfold<B, F, R>(&mut self, init: B, mut f: F) -> R |
136 | where |
137 | Self: Sized, |
138 | F: FnMut(B, Self::Item) -> R, |
139 | R: Try<Output = B>, |
140 | { |
141 | match self.peeked.take() { |
142 | Some(None) => try { init }, |
143 | Some(Some(v)) => match self.iter.try_rfold(init, &mut f).branch() { |
144 | ControlFlow::Continue(acc) => f(acc, v), |
145 | ControlFlow::Break(r) => { |
146 | self.peeked = Some(Some(v)); |
147 | R::from_residual(r) |
148 | } |
149 | }, |
150 | None => self.iter.try_rfold(init, f), |
151 | } |
152 | } |
153 | |
154 | #[inline ] |
155 | fn rfold<Acc, Fold>(self, init: Acc, mut fold: Fold) -> Acc |
156 | where |
157 | Fold: FnMut(Acc, Self::Item) -> Acc, |
158 | { |
159 | match self.peeked { |
160 | Some(None) => init, |
161 | Some(Some(v)) => { |
162 | let acc = self.iter.rfold(init, &mut fold); |
163 | fold(acc, v) |
164 | } |
165 | None => self.iter.rfold(init, fold), |
166 | } |
167 | } |
168 | } |
169 | |
170 | #[stable (feature = "rust1" , since = "1.0.0" )] |
171 | impl<I: ExactSizeIterator> ExactSizeIterator for Peekable<I> {} |
172 | |
173 | #[stable (feature = "fused" , since = "1.26.0" )] |
174 | impl<I: FusedIterator> FusedIterator for Peekable<I> {} |
175 | |
176 | impl<I: Iterator> Peekable<I> { |
177 | /// Returns a reference to the next() value without advancing the iterator. |
178 | /// |
179 | /// Like [`next`], if there is a value, it is wrapped in a `Some(T)`. |
180 | /// But if the iteration is over, `None` is returned. |
181 | /// |
182 | /// [`next`]: Iterator::next |
183 | /// |
184 | /// Because `peek()` returns a reference, and many iterators iterate over |
185 | /// references, there can be a possibly confusing situation where the |
186 | /// return value is a double reference. You can see this effect in the |
187 | /// examples below. |
188 | /// |
189 | /// # Examples |
190 | /// |
191 | /// Basic usage: |
192 | /// |
193 | /// ``` |
194 | /// let xs = [1, 2, 3]; |
195 | /// |
196 | /// let mut iter = xs.iter().peekable(); |
197 | /// |
198 | /// // peek() lets us see into the future |
199 | /// assert_eq!(iter.peek(), Some(&&1)); |
200 | /// assert_eq!(iter.next(), Some(&1)); |
201 | /// |
202 | /// assert_eq!(iter.next(), Some(&2)); |
203 | /// |
204 | /// // The iterator does not advance even if we `peek` multiple times |
205 | /// assert_eq!(iter.peek(), Some(&&3)); |
206 | /// assert_eq!(iter.peek(), Some(&&3)); |
207 | /// |
208 | /// assert_eq!(iter.next(), Some(&3)); |
209 | /// |
210 | /// // After the iterator is finished, so is `peek()` |
211 | /// assert_eq!(iter.peek(), None); |
212 | /// assert_eq!(iter.next(), None); |
213 | /// ``` |
214 | #[inline ] |
215 | #[stable (feature = "rust1" , since = "1.0.0" )] |
216 | pub fn peek(&mut self) -> Option<&I::Item> { |
217 | let iter = &mut self.iter; |
218 | self.peeked.get_or_insert_with(|| iter.next()).as_ref() |
219 | } |
220 | |
221 | /// Returns a mutable reference to the next() value without advancing the iterator. |
222 | /// |
223 | /// Like [`next`], if there is a value, it is wrapped in a `Some(T)`. |
224 | /// But if the iteration is over, `None` is returned. |
225 | /// |
226 | /// Because `peek_mut()` returns a reference, and many iterators iterate over |
227 | /// references, there can be a possibly confusing situation where the |
228 | /// return value is a double reference. You can see this effect in the examples |
229 | /// below. |
230 | /// |
231 | /// [`next`]: Iterator::next |
232 | /// |
233 | /// # Examples |
234 | /// |
235 | /// Basic usage: |
236 | /// |
237 | /// ``` |
238 | /// let mut iter = [1, 2, 3].iter().peekable(); |
239 | /// |
240 | /// // Like with `peek()`, we can see into the future without advancing the iterator. |
241 | /// assert_eq!(iter.peek_mut(), Some(&mut &1)); |
242 | /// assert_eq!(iter.peek_mut(), Some(&mut &1)); |
243 | /// assert_eq!(iter.next(), Some(&1)); |
244 | /// |
245 | /// // Peek into the iterator and set the value behind the mutable reference. |
246 | /// if let Some(p) = iter.peek_mut() { |
247 | /// assert_eq!(*p, &2); |
248 | /// *p = &5; |
249 | /// } |
250 | /// |
251 | /// // The value we put in reappears as the iterator continues. |
252 | /// assert_eq!(iter.collect::<Vec<_>>(), vec![&5, &3]); |
253 | /// ``` |
254 | #[inline ] |
255 | #[stable (feature = "peekable_peek_mut" , since = "1.53.0" )] |
256 | pub fn peek_mut(&mut self) -> Option<&mut I::Item> { |
257 | let iter = &mut self.iter; |
258 | self.peeked.get_or_insert_with(|| iter.next()).as_mut() |
259 | } |
260 | |
261 | /// Consume and return the next value of this iterator if a condition is true. |
262 | /// |
263 | /// If `func` returns `true` for the next value of this iterator, consume and return it. |
264 | /// Otherwise, return `None`. |
265 | /// |
266 | /// # Examples |
267 | /// Consume a number if it's equal to 0. |
268 | /// ``` |
269 | /// let mut iter = (0..5).peekable(); |
270 | /// // The first item of the iterator is 0; consume it. |
271 | /// assert_eq!(iter.next_if(|&x| x == 0), Some(0)); |
272 | /// // The next item returned is now 1, so `next_if` will return `None`. |
273 | /// assert_eq!(iter.next_if(|&x| x == 0), None); |
274 | /// // `next_if` saves the value of the next item if it was not equal to `expected`. |
275 | /// assert_eq!(iter.next(), Some(1)); |
276 | /// ``` |
277 | /// |
278 | /// Consume any number less than 10. |
279 | /// ``` |
280 | /// let mut iter = (1..20).peekable(); |
281 | /// // Consume all numbers less than 10 |
282 | /// while iter.next_if(|&x| x < 10).is_some() {} |
283 | /// // The next value returned will be 10 |
284 | /// assert_eq!(iter.next(), Some(10)); |
285 | /// ``` |
286 | #[stable (feature = "peekable_next_if" , since = "1.51.0" )] |
287 | pub fn next_if(&mut self, func: impl FnOnce(&I::Item) -> bool) -> Option<I::Item> { |
288 | match self.next() { |
289 | Some(matched) if func(&matched) => Some(matched), |
290 | other => { |
291 | // Since we called `self.next()`, we consumed `self.peeked`. |
292 | assert!(self.peeked.is_none()); |
293 | self.peeked = Some(other); |
294 | None |
295 | } |
296 | } |
297 | } |
298 | |
299 | /// Consume and return the next item if it is equal to `expected`. |
300 | /// |
301 | /// # Example |
302 | /// Consume a number if it's equal to 0. |
303 | /// ``` |
304 | /// let mut iter = (0..5).peekable(); |
305 | /// // The first item of the iterator is 0; consume it. |
306 | /// assert_eq!(iter.next_if_eq(&0), Some(0)); |
307 | /// // The next item returned is now 1, so `next_if` will return `None`. |
308 | /// assert_eq!(iter.next_if_eq(&0), None); |
309 | /// // `next_if_eq` saves the value of the next item if it was not equal to `expected`. |
310 | /// assert_eq!(iter.next(), Some(1)); |
311 | /// ``` |
312 | #[stable (feature = "peekable_next_if" , since = "1.51.0" )] |
313 | pub fn next_if_eq<T>(&mut self, expected: &T) -> Option<I::Item> |
314 | where |
315 | T: ?Sized, |
316 | I::Item: PartialEq<T>, |
317 | { |
318 | self.next_if(|next| next == expected) |
319 | } |
320 | } |
321 | |
322 | #[unstable (feature = "trusted_len" , issue = "37572" )] |
323 | unsafe impl<I> TrustedLen for Peekable<I> where I: TrustedLen {} |
324 | |
325 | #[unstable (issue = "none" , feature = "inplace_iteration" )] |
326 | unsafe impl<I: Iterator> SourceIter for Peekable<I> |
327 | where |
328 | I: SourceIter, |
329 | { |
330 | type Source = I::Source; |
331 | |
332 | #[inline ] |
333 | unsafe fn as_inner(&mut self) -> &mut I::Source { |
334 | // SAFETY: unsafe function forwarding to unsafe function with the same requirements |
335 | unsafe { SourceIter::as_inner(&mut self.iter) } |
336 | } |
337 | } |
338 | |