diff options
| author | Konrad Borowski <konrad@borowski.pw> | 2018-12-05 14:39:42 +0100 |
|---|---|---|
| committer | Konrad Borowski <konrad@borowski.pw> | 2018-12-05 15:40:14 +0100 |
| commit | ab2cd6070e73dc79a5b5e0b67cad120f0ccb4217 (patch) | |
| tree | 0ba4c6db9c99a6aa6fbc1f820fad8febbb15db9f | |
| parent | 705383adb037dddd834970d2c10edb32dae9fa56 (diff) | |
| download | rust-ab2cd6070e73dc79a5b5e0b67cad120f0ccb4217.tar.gz rust-ab2cd6070e73dc79a5b5e0b67cad120f0ccb4217.zip | |
Add unstable Iterator::copied()
| -rw-r--r-- | src/libcore/iter/iterator.rs | 31 | ||||
| -rw-r--r-- | src/libcore/iter/mod.rs | 98 |
2 files changed, 128 insertions, 1 deletions
diff --git a/src/libcore/iter/iterator.rs b/src/libcore/iter/iterator.rs index 3063cb1a7df..80bd5698c47 100644 --- a/src/libcore/iter/iterator.rs +++ b/src/libcore/iter/iterator.rs @@ -12,7 +12,7 @@ use cmp::Ordering; use ops::Try; use super::LoopState; -use super::{Chain, Cycle, Cloned, Enumerate, Filter, FilterMap, Fuse}; +use super::{Chain, Cycle, Copied, Cloned, Enumerate, Filter, FilterMap, Fuse}; use super::{Flatten, FlatMap, flatten_compat}; use super::{Inspect, Map, Peekable, Scan, Skip, SkipWhile, StepBy, Take, TakeWhile, Rev}; use super::{Zip, Sum, Product}; @@ -2234,6 +2234,35 @@ pub trait Iterator { (ts, us) } + /// Creates an iterator which copies all of its elements. + /// + /// This is useful when you have an iterator over `&T`, but you need an + /// iterator over `T`. + /// + /// # Examples + /// + /// Basic usage: + /// + /// ``` + /// #![feature(iter_copied)] + /// + /// let a = [1, 2, 3]; + /// + /// let v_cloned: Vec<_> = a.iter().copied().collect(); + /// + /// // copied is the same as .map(|&x| x) + /// let v_map: Vec<_> = a.iter().map(|&x| x).collect(); + /// + /// assert_eq!(v_cloned, vec![1, 2, 3]); + /// assert_eq!(v_map, vec![1, 2, 3]); + /// ``` + #[unstable(feature = "iter_copied", issue = "0")] + fn copied<'a, T: 'a>(self) -> Copied<Self> + where Self: Sized + Iterator<Item=&'a T>, T: Copy + { + Copied { it: self } + } + /// Creates an iterator which [`clone`]s all of its elements. /// /// This is useful when you have an iterator over `&T`, but you need an diff --git a/src/libcore/iter/mod.rs b/src/libcore/iter/mod.rs index 62e1f9fcb64..a23a404e378 100644 --- a/src/libcore/iter/mod.rs +++ b/src/libcore/iter/mod.rs @@ -501,6 +501,104 @@ impl<I> FusedIterator for Rev<I> unsafe impl<I> TrustedLen for Rev<I> where I: TrustedLen + DoubleEndedIterator {} +/// An iterator that copies the elements of an underlying iterator. +/// +/// This `struct` is created by the [`copied`] method on [`Iterator`]. See its +/// documentation for more. +/// +/// [`copied`]: trait.Iterator.html#method.copied +/// [`Iterator`]: trait.Iterator.html +#[unstable(feature = "iter_copied", issue = "0")] +#[must_use = "iterator adaptors are lazy and do nothing unless consumed"] +#[derive(Clone, Debug)] +pub struct Copied<I> { + it: I, +} + +#[unstable(feature = "iter_copied", issue = "0")] +impl<'a, I, T: 'a> Iterator for Copied<I> + where I: Iterator<Item=&'a T>, T: Copy +{ + type Item = T; + + fn next(&mut self) -> Option<T> { + self.it.next().copied() + } + + fn size_hint(&self) -> (usize, Option<usize>) { + self.it.size_hint() + } + + fn try_fold<B, F, R>(&mut self, init: B, mut f: F) -> R where + Self: Sized, F: FnMut(B, Self::Item) -> R, R: Try<Ok=B> + { + self.it.try_fold(init, move |acc, &elt| f(acc, elt)) + } + + fn fold<Acc, F>(self, init: Acc, mut f: F) -> Acc + where F: FnMut(Acc, Self::Item) -> Acc, + { + self.it.fold(init, move |acc, &elt| f(acc, elt)) + } +} + +#[unstable(feature = "iter_copied", issue = "0")] +impl<'a, I, T: 'a> DoubleEndedIterator for Copied<I> + where I: DoubleEndedIterator<Item=&'a T>, T: Copy +{ + fn next_back(&mut self) -> Option<T> { + self.it.next_back().cloned() + } + + fn try_rfold<B, F, R>(&mut self, init: B, mut f: F) -> R where + Self: Sized, F: FnMut(B, Self::Item) -> R, R: Try<Ok=B> + { + self.it.try_rfold(init, move |acc, elt| f(acc, elt.clone())) + } + + fn rfold<Acc, F>(self, init: Acc, mut f: F) -> Acc + where F: FnMut(Acc, Self::Item) -> Acc, + { + self.it.rfold(init, move |acc, elt| f(acc, elt.clone())) + } +} + +#[unstable(feature = "iter_copied", issue = "0")] +impl<'a, I, T: 'a> ExactSizeIterator for Copied<I> + where I: ExactSizeIterator<Item=&'a T>, T: Copy +{ + fn len(&self) -> usize { + self.it.len() + } + + fn is_empty(&self) -> bool { + self.it.is_empty() + } +} + +#[unstable(feature = "iter_copied", issue = "0")] +impl<'a, I, T: 'a> FusedIterator for Copied<I> + where I: FusedIterator<Item=&'a T>, T: Copy +{} + +#[doc(hidden)] +unsafe impl<'a, I, T: 'a> TrustedRandomAccess for Copied<I> + where I: TrustedRandomAccess<Item=&'a T>, T: Copy +{ + unsafe fn get_unchecked(&mut self, i: usize) -> Self::Item { + *self.it.get_unchecked(i) + } + + #[inline] + fn may_have_side_effect() -> bool { false } +} + +#[unstable(feature = "iter_copied", issue = "0")] +unsafe impl<'a, I, T: 'a> TrustedLen for Copied<I> + where I: TrustedLen<Item=&'a T>, + T: Copy +{} + /// An iterator that clones the elements of an underlying iterator. /// /// This `struct` is created by the [`cloned`] method on [`Iterator`]. See its |
