Skip to content

Commit 38e446a

Browse files
committed
Add peekable_iterator
1 parent 0060d5a commit 38e446a

File tree

3 files changed

+47
-0
lines changed

3 files changed

+47
-0
lines changed

library/core/src/iter/mod.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -452,6 +452,8 @@ pub use self::traits::FusedIterator;
452452
pub use self::traits::InPlaceIterable;
453453
#[stable(feature = "rust1", since = "1.0.0")]
454454
pub use self::traits::Iterator;
455+
#[unstable(feature = "peekable_iterator", issue = "132973")]
456+
pub use self::traits::PeekableIterator;
455457
#[unstable(issue = "none", feature = "trusted_fused")]
456458
pub use self::traits::TrustedFused;
457459
#[unstable(feature = "trusted_len", issue = "37572")]

library/core/src/iter/traits/mod.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ mod double_ended;
44
mod exact_size;
55
mod iterator;
66
mod marker;
7+
mod peekable;
78
mod unchecked_iterator;
89

910
#[unstable(issue = "none", feature = "inplace_iteration")]
@@ -12,6 +13,8 @@ pub use self::marker::InPlaceIterable;
1213
pub use self::marker::TrustedFused;
1314
#[unstable(feature = "trusted_step", issue = "85731")]
1415
pub use self::marker::TrustedStep;
16+
#[unstable(feature = "peekable_iterator", issue = "132973")]
17+
pub use self::peekable::PeekableIterator;
1518
pub(crate) use self::unchecked_iterator::UncheckedIterator;
1619
#[stable(feature = "rust1", since = "1.0.0")]
1720
pub use self::{
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
#[unstable(feature = "peekable_iterator", issue = "132973")]
2+
/// Iterators which inherently support `peek()` without needing to be wrapped by a `Peekable`.
3+
pub trait PeekableIterator: Iterator {
4+
/// returns a reference to the `next()` value without advancing the iterator.
5+
/// Just like `next()`, if there is a value, it returns a reference to it in Some()
6+
/// if the iteration is finished, a `None` is returned
7+
///
8+
/// # Examples
9+
/// Basic usage:
10+
/// ```
11+
/// let xs = [1, 2, 3];
12+
/// let mut iter = xs.iter();
13+
///
14+
/// // peek() allows us to check the future value
15+
/// assert_eq!(iter.peek(), Some(&&1));
16+
/// assert_eq!(iter.next(), Some(&1));
17+
///
18+
/// // peek() doesn't move the iterator forward
19+
/// assert_eq!(iter.peek(), Some(&&2));
20+
/// assert_eq!(iter.peek(), Some(&&2));
21+
///
22+
/// ```
23+
fn peek(&mut self) -> Option<&Self::Item>;
24+
25+
/// returns the `next()` element if a predicate holds true
26+
fn next_if(&mut self, func: impl FnOnce(&Self::Item) -> bool) -> Option<Self::Item> {
27+
let Some(item) = self.peek() else {
28+
return None;
29+
};
30+
31+
if func(item) { self.next() } else { None }
32+
}
33+
34+
/// move forward and return the `next()` item if it is equal to the expected value
35+
fn next_if_eq<T>(&mut self, expected: &T) -> Option<Self::Item>
36+
where
37+
Self::Item: PartialEq<T>,
38+
T: ?Sized,
39+
{
40+
self.next_if(|x| x == expected)
41+
}
42+
}

0 commit comments

Comments
 (0)