Skip to content

Commit 4a65606

Browse files
committed
add Cloned iterator adaptor
1 parent 9702fb9 commit 4a65606

File tree

2 files changed

+57
-1
lines changed

2 files changed

+57
-1
lines changed

src/libcore/iter.rs

Lines changed: 40 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -65,9 +65,10 @@ use cmp;
6565
use cmp::Ord;
6666
use mem;
6767
use num::{ToPrimitive, Int};
68-
use ops::Add;
68+
use ops::{Add, Deref};
6969
use option::{Option, Some, None};
7070
use uint;
71+
7172
#[deprecated = "renamed to Extend"] pub use self::Extend as Extendable;
7273

7374
/// Conversion from an `Iterator`
@@ -1021,6 +1022,44 @@ impl<T: Clone> MinMaxResult<T> {
10211022
}
10221023
}
10231024

1025+
/// A trait for iterators that contain cloneable elements
1026+
pub trait CloneIteratorExt<A> {
1027+
/// Creates an iterator that clones the elements it yields. Useful for converting an
1028+
/// Iterator<&T> to an Iterator<T>.
1029+
fn cloned(self) -> Cloned<Self>;
1030+
}
1031+
1032+
1033+
impl<A: Clone, D: Deref<A>, I: Iterator<D>> CloneIteratorExt<A> for I {
1034+
fn cloned(self) -> Cloned<I> {
1035+
Cloned { it: self }
1036+
}
1037+
}
1038+
1039+
/// An iterator that clones the elements of an underlying iterator
1040+
pub struct Cloned<I> {
1041+
it: I,
1042+
}
1043+
1044+
impl<A: Clone, D: Deref<A>, I: Iterator<D>> Iterator<A> for Cloned<I> {
1045+
fn next(&mut self) -> Option<A> {
1046+
self.it.next().cloned()
1047+
}
1048+
1049+
fn size_hint(&self) -> (uint, Option<uint>) {
1050+
self.it.size_hint()
1051+
}
1052+
}
1053+
1054+
impl<A: Clone, D: Deref<A>, I: DoubleEndedIterator<D>>
1055+
DoubleEndedIterator<A> for Cloned<I> {
1056+
fn next_back(&mut self) -> Option<A> {
1057+
self.it.next_back().cloned()
1058+
}
1059+
}
1060+
1061+
impl<A: Clone, D: Deref<A>, I: ExactSize<D>> ExactSize<A> for Cloned<I> {}
1062+
10241063
/// A trait for iterators that are cloneable.
10251064
pub trait CloneableIterator {
10261065
/// Repeats an iterator endlessly

src/libcoretest/iter.rs

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -440,6 +440,23 @@ fn test_rev() {
440440
vec![16, 14, 12, 10, 8, 6]);
441441
}
442442

443+
#[test]
444+
fn test_cloned() {
445+
let xs = [2u8, 4, 6, 8];
446+
447+
let mut it = xs.iter().cloned();
448+
assert_eq!(it.len(), 4);
449+
assert_eq!(it.next(), Some(2));
450+
assert_eq!(it.len(), 3);
451+
assert_eq!(it.next(), Some(4));
452+
assert_eq!(it.len(), 2);
453+
assert_eq!(it.next_back(), Some(8));
454+
assert_eq!(it.len(), 1);
455+
assert_eq!(it.next_back(), Some(6));
456+
assert_eq!(it.len(), 0);
457+
assert_eq!(it.next_back(), None);
458+
}
459+
443460
#[test]
444461
fn test_double_ended_map() {
445462
let xs = [1i, 2, 3, 4, 5, 6];

0 commit comments

Comments
 (0)