Skip to content

Commit 3a1d045

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

File tree

3 files changed

+66
-3
lines changed

3 files changed

+66
-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::{FusedIterator, Peekable};
2+
3+
/// An iterator that maps the values of `iter` with `f`.
4+
#[must_use = "iterators are lazy and do nothing unless consumed"]
5+
#[unstable(feature = "peek_map", issue = "118474")]
6+
#[derive(Debug)]
7+
pub struct PeekMap<P, F> {
8+
pub(crate) peekable: P,
9+
f: F,
10+
}
11+
12+
impl<I: Iterator, F> PeekMap<Peekable<I>, F> {
13+
pub(in crate::iter) fn new(peekable: Peekable<I>, f: F) -> PeekMap<Peekable<I>, F> {
14+
PeekMap { peekable, f }
15+
}
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: 10 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,15 @@ impl<I: Iterator> Peekable<I> {
316316
{
317317
self.next_if(|next| next == expected)
318318
}
319+
320+
/// Honestly I'm adding this doc to get rid of the error just to make sure everything else actually works.
321+
#[unstable(feature = "peek_map", issue = "118474")]
322+
pub fn peek_map<B, F>(self, f: F) -> PeekMap<Self, F>
323+
where
324+
F: FnMut(I::Item, Option<&I::Item>) -> B,
325+
{
326+
PeekMap::new(self, f)
327+
}
319328
}
320329

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

0 commit comments

Comments
 (0)