Skip to content

Commit

Permalink
Add unstable Iterator::copied()
Browse files Browse the repository at this point in the history
  • Loading branch information
KamilaBorowska committed Dec 5, 2018
1 parent 705383a commit ab2cd60
Show file tree
Hide file tree
Showing 2 changed files with 128 additions and 1 deletion.
31 changes: 30 additions & 1 deletion src/libcore/iter/iterator.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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};
Expand Down Expand Up @@ -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
Expand Down
98 changes: 98 additions & 0 deletions src/libcore/iter/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down

0 comments on commit ab2cd60

Please sign in to comment.