From 3a1d0453b192edb79bfd521d16d22b88dbda7119 Mon Sep 17 00:00:00 2001 From: MiguelX413 Date: Thu, 30 Nov 2023 18:22:25 -0800 Subject: [PATCH 1/2] Add `core::iter::adapters::PeekMap` and `core::iter::Peekable::peek_map` --- library/core/src/iter/adapters/mod.rs | 6 ++- library/core/src/iter/adapters/peek_map.rs | 52 ++++++++++++++++++++++ library/core/src/iter/adapters/peekable.rs | 11 ++++- 3 files changed, 66 insertions(+), 3 deletions(-) create mode 100644 library/core/src/iter/adapters/peek_map.rs diff --git a/library/core/src/iter/adapters/mod.rs b/library/core/src/iter/adapters/mod.rs index a691039c789c6..fb1ed26d4acd8 100644 --- a/library/core/src/iter/adapters/mod.rs +++ b/library/core/src/iter/adapters/mod.rs @@ -18,6 +18,7 @@ mod intersperse; mod map; mod map_while; mod map_windows; +mod peek_map; mod peekable; mod rev; mod scan; @@ -31,8 +32,9 @@ mod zip; #[stable(feature = "rust1", since = "1.0.0")] pub use self::{ chain::Chain, cycle::Cycle, enumerate::Enumerate, filter::Filter, filter_map::FilterMap, - flatten::FlatMap, fuse::Fuse, inspect::Inspect, map::Map, peekable::Peekable, rev::Rev, - scan::Scan, skip::Skip, skip_while::SkipWhile, take::Take, take_while::TakeWhile, zip::Zip, + flatten::FlatMap, fuse::Fuse, inspect::Inspect, map::Map, peek_map::PeekMap, + peekable::Peekable, rev::Rev, scan::Scan, skip::Skip, skip_while::SkipWhile, take::Take, + take_while::TakeWhile, zip::Zip, }; #[unstable(feature = "iter_array_chunks", reason = "recently added", issue = "100450")] diff --git a/library/core/src/iter/adapters/peek_map.rs b/library/core/src/iter/adapters/peek_map.rs new file mode 100644 index 0000000000000..83655162c9df6 --- /dev/null +++ b/library/core/src/iter/adapters/peek_map.rs @@ -0,0 +1,52 @@ +use crate::iter::{FusedIterator, Peekable}; + +/// An iterator that maps the values of `iter` with `f`. +#[must_use = "iterators are lazy and do nothing unless consumed"] +#[unstable(feature = "peek_map", issue = "118474")] +#[derive(Debug)] +pub struct PeekMap { + pub(crate) peekable: P, + f: F, +} + +impl PeekMap, F> { + pub(in crate::iter) fn new(peekable: Peekable, f: F) -> PeekMap, F> { + PeekMap { peekable, f } + } +} + +#[unstable(feature = "peek_map", issue = "118474")] +impl Iterator for PeekMap, F> +where + F: FnMut(I::Item, Option<&I::Item>) -> B, +{ + type Item = B; + + #[inline] + fn next(&mut self) -> Option { + Some((&mut self.f)(self.peekable.next()?, self.peekable.peek())) + } + + #[inline] + fn size_hint(&self) -> (usize, Option) { + self.peekable.size_hint() + } +} +#[unstable(feature = "peek_map", issue = "118474")] +impl ExactSizeIterator for PeekMap, F> +where + F: FnMut(I::Item, Option<&I::Item>) -> B, +{ + fn len(&self) -> usize { + self.peekable.len() + } + + fn is_empty(&self) -> bool { + self.peekable.is_empty() + } +} +#[unstable(feature = "peek_map", issue = "118474")] +impl FusedIterator for PeekMap, F> where + F: FnMut(I::Item, Option<&I::Item>) -> B +{ +} diff --git a/library/core/src/iter/adapters/peekable.rs b/library/core/src/iter/adapters/peekable.rs index 65ba42920c93d..b26699b4317b6 100644 --- a/library/core/src/iter/adapters/peekable.rs +++ b/library/core/src/iter/adapters/peekable.rs @@ -1,4 +1,4 @@ -use crate::iter::{adapters::SourceIter, FusedIterator, TrustedLen}; +use crate::iter::{adapters::PeekMap, adapters::SourceIter, FusedIterator, TrustedLen}; use crate::ops::{ControlFlow, Try}; /// An iterator with a `peek()` that returns an optional reference to the next @@ -316,6 +316,15 @@ impl Peekable { { self.next_if(|next| next == expected) } + + /// Honestly I'm adding this doc to get rid of the error just to make sure everything else actually works. + #[unstable(feature = "peek_map", issue = "118474")] + pub fn peek_map(self, f: F) -> PeekMap + where + F: FnMut(I::Item, Option<&I::Item>) -> B, + { + PeekMap::new(self, f) + } } #[unstable(feature = "trusted_len", issue = "37572")] From aa61b124b4eb87c41a75e5926267a0381dcd21c6 Mon Sep 17 00:00:00 2001 From: MiguelX413 Date: Sat, 2 Dec 2023 20:30:24 -0800 Subject: [PATCH 2/2] Add docs to `core::iter::adapters::PeekMap` --- library/core/src/iter/adapters/peek_map.rs | 36 +++++++++++++++++----- 1 file changed, 29 insertions(+), 7 deletions(-) diff --git a/library/core/src/iter/adapters/peek_map.rs b/library/core/src/iter/adapters/peek_map.rs index 83655162c9df6..df65d4fd5001f 100644 --- a/library/core/src/iter/adapters/peek_map.rs +++ b/library/core/src/iter/adapters/peek_map.rs @@ -1,17 +1,39 @@ use crate::iter::{FusedIterator, Peekable}; /// An iterator that maps the values of `iter` with `f`. +/// +/// This struct is created by the [`peek_map`] method on [`Peekable`]. See its +/// documentation for more. +/// +/// [`peek_map`]: Peekable::peek_map +/// [`Peekable`]: struct.Peekable.html +/// +/// # Examples +/// +/// Basic usage: +/// +/// ``` +/// #![feature(peek_map)] +/// +/// let a = [1, 2, 3]; +/// let mut iter = a.into_iter().peekable().peek_map(|x, next| x * *next.unwrap_or(&1)); +/// +/// assert_eq!(iter.next(), Some(2)); +/// assert_eq!(iter.next(), Some(6)); +/// assert_eq!(iter.next(), Some(3)); +/// assert_eq!(iter.next(), None); +/// ``` #[must_use = "iterators are lazy and do nothing unless consumed"] #[unstable(feature = "peek_map", issue = "118474")] #[derive(Debug)] -pub struct PeekMap { - pub(crate) peekable: P, +pub struct PeekMap { + pub(crate) t: T, f: F, } impl PeekMap, F> { pub(in crate::iter) fn new(peekable: Peekable, f: F) -> PeekMap, F> { - PeekMap { peekable, f } + PeekMap { t: peekable, f } } } @@ -24,12 +46,12 @@ where #[inline] fn next(&mut self) -> Option { - Some((&mut self.f)(self.peekable.next()?, self.peekable.peek())) + Some((&mut self.f)(self.t.next()?, self.t.peek())) } #[inline] fn size_hint(&self) -> (usize, Option) { - self.peekable.size_hint() + self.t.size_hint() } } #[unstable(feature = "peek_map", issue = "118474")] @@ -38,11 +60,11 @@ where F: FnMut(I::Item, Option<&I::Item>) -> B, { fn len(&self) -> usize { - self.peekable.len() + self.t.len() } fn is_empty(&self) -> bool { - self.peekable.is_empty() + self.t.is_empty() } } #[unstable(feature = "peek_map", issue = "118474")]