Skip to content

Commit

Permalink
add Cloned iterator adaptor
Browse files Browse the repository at this point in the history
  • Loading branch information
Gankra committed Nov 18, 2014
1 parent 9702fb9 commit 4a65606
Show file tree
Hide file tree
Showing 2 changed files with 57 additions and 1 deletion.
41 changes: 40 additions & 1 deletion src/libcore/iter.rs
Expand Up @@ -65,9 +65,10 @@ use cmp;
use cmp::Ord;
use mem;
use num::{ToPrimitive, Int};
use ops::Add;
use ops::{Add, Deref};
use option::{Option, Some, None};
use uint;

#[deprecated = "renamed to Extend"] pub use self::Extend as Extendable;

/// Conversion from an `Iterator`
Expand Down Expand Up @@ -1021,6 +1022,44 @@ impl<T: Clone> MinMaxResult<T> {
}
}

/// A trait for iterators that contain cloneable elements
pub trait CloneIteratorExt<A> {
/// Creates an iterator that clones the elements it yields. Useful for converting an
/// Iterator<&T> to an Iterator<T>.
fn cloned(self) -> Cloned<Self>;
}


impl<A: Clone, D: Deref<A>, I: Iterator<D>> CloneIteratorExt<A> for I {
fn cloned(self) -> Cloned<I> {
Cloned { it: self }
}
}

/// An iterator that clones the elements of an underlying iterator
pub struct Cloned<I> {
it: I,
}

impl<A: Clone, D: Deref<A>, I: Iterator<D>> Iterator<A> for Cloned<I> {
fn next(&mut self) -> Option<A> {
self.it.next().cloned()
}

fn size_hint(&self) -> (uint, Option<uint>) {
self.it.size_hint()
}
}

impl<A: Clone, D: Deref<A>, I: DoubleEndedIterator<D>>
DoubleEndedIterator<A> for Cloned<I> {
fn next_back(&mut self) -> Option<A> {
self.it.next_back().cloned()
}
}

impl<A: Clone, D: Deref<A>, I: ExactSize<D>> ExactSize<A> for Cloned<I> {}

/// A trait for iterators that are cloneable.
pub trait CloneableIterator {
/// Repeats an iterator endlessly
Expand Down
17 changes: 17 additions & 0 deletions src/libcoretest/iter.rs
Expand Up @@ -440,6 +440,23 @@ fn test_rev() {
vec![16, 14, 12, 10, 8, 6]);
}

#[test]
fn test_cloned() {
let xs = [2u8, 4, 6, 8];

let mut it = xs.iter().cloned();
assert_eq!(it.len(), 4);
assert_eq!(it.next(), Some(2));
assert_eq!(it.len(), 3);
assert_eq!(it.next(), Some(4));
assert_eq!(it.len(), 2);
assert_eq!(it.next_back(), Some(8));
assert_eq!(it.len(), 1);
assert_eq!(it.next_back(), Some(6));
assert_eq!(it.len(), 0);
assert_eq!(it.next_back(), None);
}

#[test]
fn test_double_ended_map() {
let xs = [1i, 2, 3, 4, 5, 6];
Expand Down

5 comments on commit 4a65606

@bors
Copy link
Contributor

@bors bors commented on 4a65606 Nov 18, 2014

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

saw approval from aturon
at Gankra@4a65606

@bors
Copy link
Contributor

@bors bors commented on 4a65606 Nov 18, 2014

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

merging Gankro/rust/super-cloned = 4a656062 into auto

@bors
Copy link
Contributor

@bors bors commented on 4a65606 Nov 18, 2014

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Gankro/rust/super-cloned = 4a656062 merged ok, testing candidate = 09e2ad1

@bors
Copy link
Contributor

@bors bors commented on 4a65606 Nov 18, 2014

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@bors
Copy link
Contributor

@bors bors commented on 4a65606 Nov 18, 2014

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fast-forwarding master to auto = 09e2ad1

Please sign in to comment.