Skip to content

Commit ab2cd60

Browse files
committed
Add unstable Iterator::copied()
1 parent 705383a commit ab2cd60

File tree

2 files changed

+128
-1
lines changed

2 files changed

+128
-1
lines changed

src/libcore/iter/iterator.rs

+30-1
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ use cmp::Ordering;
1212
use ops::Try;
1313

1414
use super::LoopState;
15-
use super::{Chain, Cycle, Cloned, Enumerate, Filter, FilterMap, Fuse};
15+
use super::{Chain, Cycle, Copied, Cloned, Enumerate, Filter, FilterMap, Fuse};
1616
use super::{Flatten, FlatMap, flatten_compat};
1717
use super::{Inspect, Map, Peekable, Scan, Skip, SkipWhile, StepBy, Take, TakeWhile, Rev};
1818
use super::{Zip, Sum, Product};
@@ -2234,6 +2234,35 @@ pub trait Iterator {
22342234
(ts, us)
22352235
}
22362236

2237+
/// Creates an iterator which copies all of its elements.
2238+
///
2239+
/// This is useful when you have an iterator over `&T`, but you need an
2240+
/// iterator over `T`.
2241+
///
2242+
/// # Examples
2243+
///
2244+
/// Basic usage:
2245+
///
2246+
/// ```
2247+
/// #![feature(iter_copied)]
2248+
///
2249+
/// let a = [1, 2, 3];
2250+
///
2251+
/// let v_cloned: Vec<_> = a.iter().copied().collect();
2252+
///
2253+
/// // copied is the same as .map(|&x| x)
2254+
/// let v_map: Vec<_> = a.iter().map(|&x| x).collect();
2255+
///
2256+
/// assert_eq!(v_cloned, vec![1, 2, 3]);
2257+
/// assert_eq!(v_map, vec![1, 2, 3]);
2258+
/// ```
2259+
#[unstable(feature = "iter_copied", issue = "0")]
2260+
fn copied<'a, T: 'a>(self) -> Copied<Self>
2261+
where Self: Sized + Iterator<Item=&'a T>, T: Copy
2262+
{
2263+
Copied { it: self }
2264+
}
2265+
22372266
/// Creates an iterator which [`clone`]s all of its elements.
22382267
///
22392268
/// This is useful when you have an iterator over `&T`, but you need an

src/libcore/iter/mod.rs

+98
Original file line numberDiff line numberDiff line change
@@ -501,6 +501,104 @@ impl<I> FusedIterator for Rev<I>
501501
unsafe impl<I> TrustedLen for Rev<I>
502502
where I: TrustedLen + DoubleEndedIterator {}
503503

504+
/// An iterator that copies the elements of an underlying iterator.
505+
///
506+
/// This `struct` is created by the [`copied`] method on [`Iterator`]. See its
507+
/// documentation for more.
508+
///
509+
/// [`copied`]: trait.Iterator.html#method.copied
510+
/// [`Iterator`]: trait.Iterator.html
511+
#[unstable(feature = "iter_copied", issue = "0")]
512+
#[must_use = "iterator adaptors are lazy and do nothing unless consumed"]
513+
#[derive(Clone, Debug)]
514+
pub struct Copied<I> {
515+
it: I,
516+
}
517+
518+
#[unstable(feature = "iter_copied", issue = "0")]
519+
impl<'a, I, T: 'a> Iterator for Copied<I>
520+
where I: Iterator<Item=&'a T>, T: Copy
521+
{
522+
type Item = T;
523+
524+
fn next(&mut self) -> Option<T> {
525+
self.it.next().copied()
526+
}
527+
528+
fn size_hint(&self) -> (usize, Option<usize>) {
529+
self.it.size_hint()
530+
}
531+
532+
fn try_fold<B, F, R>(&mut self, init: B, mut f: F) -> R where
533+
Self: Sized, F: FnMut(B, Self::Item) -> R, R: Try<Ok=B>
534+
{
535+
self.it.try_fold(init, move |acc, &elt| f(acc, elt))
536+
}
537+
538+
fn fold<Acc, F>(self, init: Acc, mut f: F) -> Acc
539+
where F: FnMut(Acc, Self::Item) -> Acc,
540+
{
541+
self.it.fold(init, move |acc, &elt| f(acc, elt))
542+
}
543+
}
544+
545+
#[unstable(feature = "iter_copied", issue = "0")]
546+
impl<'a, I, T: 'a> DoubleEndedIterator for Copied<I>
547+
where I: DoubleEndedIterator<Item=&'a T>, T: Copy
548+
{
549+
fn next_back(&mut self) -> Option<T> {
550+
self.it.next_back().cloned()
551+
}
552+
553+
fn try_rfold<B, F, R>(&mut self, init: B, mut f: F) -> R where
554+
Self: Sized, F: FnMut(B, Self::Item) -> R, R: Try<Ok=B>
555+
{
556+
self.it.try_rfold(init, move |acc, elt| f(acc, elt.clone()))
557+
}
558+
559+
fn rfold<Acc, F>(self, init: Acc, mut f: F) -> Acc
560+
where F: FnMut(Acc, Self::Item) -> Acc,
561+
{
562+
self.it.rfold(init, move |acc, elt| f(acc, elt.clone()))
563+
}
564+
}
565+
566+
#[unstable(feature = "iter_copied", issue = "0")]
567+
impl<'a, I, T: 'a> ExactSizeIterator for Copied<I>
568+
where I: ExactSizeIterator<Item=&'a T>, T: Copy
569+
{
570+
fn len(&self) -> usize {
571+
self.it.len()
572+
}
573+
574+
fn is_empty(&self) -> bool {
575+
self.it.is_empty()
576+
}
577+
}
578+
579+
#[unstable(feature = "iter_copied", issue = "0")]
580+
impl<'a, I, T: 'a> FusedIterator for Copied<I>
581+
where I: FusedIterator<Item=&'a T>, T: Copy
582+
{}
583+
584+
#[doc(hidden)]
585+
unsafe impl<'a, I, T: 'a> TrustedRandomAccess for Copied<I>
586+
where I: TrustedRandomAccess<Item=&'a T>, T: Copy
587+
{
588+
unsafe fn get_unchecked(&mut self, i: usize) -> Self::Item {
589+
*self.it.get_unchecked(i)
590+
}
591+
592+
#[inline]
593+
fn may_have_side_effect() -> bool { false }
594+
}
595+
596+
#[unstable(feature = "iter_copied", issue = "0")]
597+
unsafe impl<'a, I, T: 'a> TrustedLen for Copied<I>
598+
where I: TrustedLen<Item=&'a T>,
599+
T: Copy
600+
{}
601+
504602
/// An iterator that clones the elements of an underlying iterator.
505603
///
506604
/// This `struct` is created by the [`cloned`] method on [`Iterator`]. See its

0 commit comments

Comments
 (0)