Skip to content

Commit 71d2361

Browse files
committed
Add core::iter::adapters::PeekMap and core::iter::Peekable::peek_map
1 parent 475f6f8 commit 71d2361

File tree

3 files changed

+65
-3
lines changed

3 files changed

+65
-3
lines changed

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

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ mod intersperse;
1818
mod map;
1919
mod map_while;
2020
mod map_windows;
21+
mod peek_map;
2122
mod peekable;
2223
mod rev;
2324
mod scan;
@@ -31,8 +32,9 @@ mod zip;
3132
#[stable(feature = "rust1", since = "1.0.0")]
3233
pub use self::{
3334
chain::Chain, cycle::Cycle, enumerate::Enumerate, filter::Filter, filter_map::FilterMap,
34-
flatten::FlatMap, fuse::Fuse, inspect::Inspect, map::Map, peekable::Peekable, rev::Rev,
35-
scan::Scan, skip::Skip, skip_while::SkipWhile, take::Take, take_while::TakeWhile, zip::Zip,
35+
flatten::FlatMap, fuse::Fuse, inspect::Inspect, map::Map, peek_map::PeekMap,
36+
peekable::Peekable, rev::Rev, scan::Scan, skip::Skip, skip_while::SkipWhile, take::Take,
37+
take_while::TakeWhile, zip::Zip,
3638
};
3739

3840
#[unstable(feature = "iter_array_chunks", reason = "recently added", issue = "100450")]
Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
use crate::iter::adapters::{SourceIter, TrustedRandomAccess, TrustedRandomAccessNoCoerce};
2+
use crate::iter::{FusedIterator, InPlaceIterable, Peekable, TrustedFused, TrustedLen};
3+
use crate::num::NonZeroUsize;
4+
5+
/// An iterator that maps the values of `iter` with `f`.
6+
#[must_use = "iterators are lazy and do nothing unless consumed"]
7+
#[unstable(feature = "peek_map", issue = "118474")]
8+
pub struct PeekMap<P, F> {
9+
pub(crate) peekable: P,
10+
f: F,
11+
}
12+
13+
impl<I: Iterator, F> PeekMap<Peekable<I>, F> {
14+
pub(in crate::iter) fn new(peekable: Peekable<I>, f: F) -> PeekMap<Peekable<I>, F> {
15+
PeekMap { peekable, f }
16+
}
17+
}
18+
#[unstable(feature = "peek_map", issue = "118474")]
19+
impl<B, I: Iterator, F> Iterator for PeekMap<Peekable<I>, F>
20+
where
21+
F: FnMut(I::Item, Option<&I::Item>) -> B,
22+
{
23+
type Item = B;
24+
25+
#[inline]
26+
fn next(&mut self) -> Option<B> {
27+
Some((&mut self.f)(self.peekable.next()?, self.peekable.peek()))
28+
}
29+
30+
#[inline]
31+
fn size_hint(&self) -> (usize, Option<usize>) {
32+
self.peekable.size_hint()
33+
}
34+
}
35+
#[unstable(feature = "peek_map", issue = "118474")]
36+
impl<B, I: ExactSizeIterator, F> ExactSizeIterator for PeekMap<Peekable<I>, F>
37+
where
38+
F: FnMut(I::Item, Option<&I::Item>) -> B,
39+
{
40+
fn len(&self) -> usize {
41+
self.peekable.len()
42+
}
43+
44+
fn is_empty(&self) -> bool {
45+
self.peekable.is_empty()
46+
}
47+
}
48+
#[unstable(feature = "peek_map", issue = "118474")]
49+
impl<B, I: FusedIterator, F> FusedIterator for PeekMap<Peekable<I>, F> where
50+
F: FnMut(I::Item, Option<&I::Item>) -> B
51+
{
52+
}

library/core/src/iter/adapters/peekable.rs

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
use crate::iter::{adapters::SourceIter, FusedIterator, TrustedLen};
1+
use crate::iter::{adapters::PeekMap, adapters::SourceIter, FusedIterator, TrustedLen};
22
use crate::ops::{ControlFlow, Try};
33

44
/// An iterator with a `peek()` that returns an optional reference to the next
@@ -316,6 +316,14 @@ impl<I: Iterator> Peekable<I> {
316316
{
317317
self.next_if(|next| next == expected)
318318
}
319+
320+
#[unstable(feature = "peek_map", issue = "118474")]
321+
pub fn peek_map<B, F>(self, f: F) -> PeekMap<Self, F>
322+
where
323+
F: FnMut(I::Item, Option<&I::Item>) -> B,
324+
{
325+
PeekMap::new(self, f)
326+
}
319327
}
320328

321329
#[unstable(feature = "trusted_len", issue = "37572")]

0 commit comments

Comments
 (0)