Skip to content

Commit 75b4b1b

Browse files
committed
auto merge of #7882 : blake2-ppc/rust/iterator-clone, r=thestinger
Implement method .cycle() that repeats an iterator endlessly Implement Clone for simple iterators (without closures), including VecIterator. > The theory is simple, the immutable iterators simply hold state > variables (indicies or pointers) into frozen containers. We can freely > clone these iterators, just like we can clone borrowed pointers.
2 parents bb8ca1f + fe134b9 commit 75b4b1b

File tree

5 files changed

+120
-0
lines changed

5 files changed

+120
-0
lines changed

src/libextra/dlist.rs

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@ struct Node<T> {
4747
}
4848

4949
/// Double-ended DList iterator
50+
#[deriving(Clone)]
5051
pub struct DListIterator<'self, T> {
5152
priv head: &'self Link<T>,
5253
priv tail: Rawlink<Node<T>>,
@@ -62,6 +63,7 @@ pub struct MutDListIterator<'self, T> {
6263
}
6364

6465
/// DList consuming iterator
66+
#[deriving(Clone)]
6567
pub struct ConsumeIterator<T> {
6668
priv list: DList<T>
6769
}
@@ -93,6 +95,13 @@ impl<T> Rawlink<T> {
9395
}
9496
}
9597

98+
impl<T> Clone for Rawlink<T> {
99+
#[inline]
100+
fn clone(&self) -> Rawlink<T> {
101+
Rawlink{p: self.p}
102+
}
103+
}
104+
96105
/// Set the .prev field on `next`, then return `Some(next)`
97106
fn link_with_prev<T>(mut next: ~Node<T>, prev: Rawlink<Node<T>>) -> Link<T> {
98107
next.prev = prev;
@@ -686,6 +695,20 @@ mod tests {
686695
assert_eq!(it.next(), None);
687696
}
688697

698+
#[test]
699+
fn test_iterator_clone() {
700+
let mut n = DList::new();
701+
n.push_back(2);
702+
n.push_back(3);
703+
n.push_back(4);
704+
let mut it = n.iter();
705+
it.next();
706+
let mut jt = it.clone();
707+
assert_eq!(it.next(), jt.next());
708+
assert_eq!(it.next_back(), jt.next_back());
709+
assert_eq!(it.next(), jt.next());
710+
}
711+
689712
#[test]
690713
fn test_iterator_double_end() {
691714
let mut n = DList::new();

src/libstd/hashmap.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -548,6 +548,7 @@ impl<K:Hash + Eq + Clone,V:Clone> Clone for HashMap<K,V> {
548548
}
549549

550550
/// HashMap iterator
551+
#[deriving(Clone)]
551552
pub struct HashMapIterator<'self, K, V> {
552553
priv iter: vec::VecIterator<'self, Option<Bucket<K, V>>>,
553554
}
@@ -563,6 +564,7 @@ pub struct HashMapConsumeIterator<K, V> {
563564
}
564565

565566
/// HashSet iterator
567+
#[deriving(Clone)]
566568
pub struct HashSetIterator<'self, K> {
567569
priv iter: vec::VecIterator<'self, Option<Bucket<K, ()>>>,
568570
}

src/libstd/iterator.rs

Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,7 @@ impl<A, T: DoubleEndedIterator<A>> DoubleEndedIteratorUtil<A> for T {
7474

7575
/// An double-ended iterator with the direction inverted
7676
// FIXME #6967: Dummy A parameter to get around type inference bug
77+
#[deriving(Clone)]
7778
pub struct InvertIterator<A, T> {
7879
priv iter: T
7980
}
@@ -729,8 +730,59 @@ impl<A: Ord, T: Iterator<A>> OrdIterator<A> for T {
729730
}
730731
}
731732

733+
/// A trait for iterators that are clonable.
734+
// FIXME #6967: Dummy A parameter to get around type inference bug
735+
pub trait ClonableIterator<A> {
736+
/// Repeats an iterator endlessly
737+
///
738+
/// # Example
739+
///
740+
/// ~~~ {.rust}
741+
/// let a = Counter::new(1,1).take_(1);
742+
/// let mut cy = a.cycle();
743+
/// assert_eq!(cy.next(), Some(1));
744+
/// assert_eq!(cy.next(), Some(1));
745+
/// ~~~
746+
fn cycle(self) -> CycleIterator<A, Self>;
747+
}
748+
749+
impl<A, T: Clone + Iterator<A>> ClonableIterator<A> for T {
750+
#[inline]
751+
fn cycle(self) -> CycleIterator<A, T> {
752+
CycleIterator{orig: self.clone(), iter: self}
753+
}
754+
}
755+
756+
/// An iterator that repeats endlessly
757+
#[deriving(Clone)]
758+
pub struct CycleIterator<A, T> {
759+
priv orig: T,
760+
priv iter: T,
761+
}
762+
763+
impl<A, T: Clone + Iterator<A>> Iterator<A> for CycleIterator<A, T> {
764+
#[inline]
765+
fn next(&mut self) -> Option<A> {
766+
match self.iter.next() {
767+
None => { self.iter = self.orig.clone(); self.iter.next() }
768+
y => y
769+
}
770+
}
771+
772+
#[inline]
773+
fn size_hint(&self) -> (uint, Option<uint>) {
774+
// the cycle iterator is either empty or infinite
775+
match self.orig.size_hint() {
776+
sz @ (0, Some(0)) => sz,
777+
(0, _) => (0, None),
778+
_ => (uint::max_value, None)
779+
}
780+
}
781+
}
782+
732783
/// An iterator which strings two iterators together
733784
// FIXME #6967: Dummy A parameter to get around type inference bug
785+
#[deriving(Clone)]
734786
pub struct ChainIterator<A, T, U> {
735787
priv a: T,
736788
priv b: U,
@@ -786,6 +838,7 @@ for ChainIterator<A, T, U> {
786838

787839
/// An iterator which iterates two other iterators simultaneously
788840
// FIXME #6967: Dummy A & B parameters to get around type inference bug
841+
#[deriving(Clone)]
789842
pub struct ZipIterator<A, T, B, U> {
790843
priv a: T,
791844
priv b: U
@@ -939,6 +992,7 @@ for FilterMapIterator<'self, A, B, T> {
939992

940993
/// An iterator which yields the current count and the element during iteration
941994
// FIXME #6967: Dummy A parameter to get around type inference bug
995+
#[deriving(Clone)]
942996
pub struct EnumerateIterator<A, T> {
943997
priv iter: T,
944998
priv count: uint
@@ -1037,6 +1091,7 @@ impl<'self, A, T: Iterator<A>> Iterator<A> for TakeWhileIterator<'self, A, T> {
10371091

10381092
/// An iterator which skips over `n` elements of `iter`.
10391093
// FIXME #6967: Dummy A parameter to get around type inference bug
1094+
#[deriving(Clone)]
10401095
pub struct SkipIterator<A, T> {
10411096
priv iter: T,
10421097
priv n: uint
@@ -1085,6 +1140,7 @@ impl<A, T: Iterator<A>> Iterator<A> for SkipIterator<A, T> {
10851140

10861141
/// An iterator which only iterates over the first `n` iterations of `iter`.
10871142
// FIXME #6967: Dummy A parameter to get around type inference bug
1143+
#[deriving(Clone)]
10881144
pub struct TakeIterator<A, T> {
10891145
priv iter: T,
10901146
priv n: uint
@@ -1236,6 +1292,7 @@ impl<'self, A, St> Iterator<A> for UnfoldrIterator<'self, A, St> {
12361292

12371293
/// An infinite iterator starting at `start` and advancing by `step` with each
12381294
/// iteration
1295+
#[deriving(Clone)]
12391296
pub struct Counter<A> {
12401297
/// The current state the counter is at (next value to be yielded)
12411298
state: A,
@@ -1437,6 +1494,20 @@ mod tests {
14371494
assert_eq!(i, 10);
14381495
}
14391496

1497+
#[test]
1498+
fn test_cycle() {
1499+
let cycle_len = 3;
1500+
let it = Counter::new(0u,1).take_(cycle_len).cycle();
1501+
assert_eq!(it.size_hint(), (uint::max_value, None));
1502+
for it.take_(100).enumerate().advance |(i, x)| {
1503+
assert_eq!(i % cycle_len, x);
1504+
}
1505+
1506+
let mut it = Counter::new(0u,1).take_(0).cycle();
1507+
assert_eq!(it.size_hint(), (0, Some(0)));
1508+
assert_eq!(it.next(), None);
1509+
}
1510+
14401511
#[test]
14411512
fn test_iterator_nth() {
14421513
let v = &[0, 1, 2, 3, 4];

src/libstd/str.rs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -288,6 +288,7 @@ impl<'self, C: CharEq> CharEq for &'self [C] {
288288

289289

290290
/// An iterator over the substrings of a string, separated by `sep`.
291+
#[deriving(Clone)]
291292
pub struct StrCharSplitIterator<'self,Sep> {
292293
priv string: &'self str,
293294
priv position: uint,
@@ -355,6 +356,7 @@ impl<'self, Sep: CharEq> Iterator<&'self str> for StrCharSplitIterator<'self, Se
355356

356357
/// An iterator over the start and end indicies of the matches of a
357358
/// substring within a larger string
359+
#[deriving(Clone)]
358360
pub struct StrMatchesIndexIterator<'self> {
359361
priv haystack: &'self str,
360362
priv needle: &'self str,
@@ -363,6 +365,7 @@ pub struct StrMatchesIndexIterator<'self> {
363365

364366
/// An iterator over the substrings of a string separated by a given
365367
/// search string
368+
#[deriving(Clone)]
366369
pub struct StrStrSplitIterator<'self> {
367370
priv it: StrMatchesIndexIterator<'self>,
368371
priv last_end: uint,
@@ -2269,6 +2272,7 @@ impl Clone for @str {
22692272
22702273
/// External iterator for a string's characters. Use with the `std::iterator`
22712274
/// module.
2275+
#[deriving(Clone)]
22722276
pub struct StrCharIterator<'self> {
22732277
priv index: uint,
22742278
priv string: &'self str,
@@ -2288,6 +2292,7 @@ impl<'self> Iterator<char> for StrCharIterator<'self> {
22882292
}
22892293
/// External iterator for a string's characters in reverse order. Use
22902294
/// with the `std::iterator` module.
2295+
#[deriving(Clone)]
22912296
pub struct StrCharRevIterator<'self> {
22922297
priv index: uint,
22932298
priv string: &'self str,
@@ -2308,6 +2313,7 @@ impl<'self> Iterator<char> for StrCharRevIterator<'self> {
23082313
23092314
/// External iterator for a string's bytes. Use with the `std::iterator`
23102315
/// module.
2316+
#[deriving(Clone)]
23112317
pub struct StrBytesIterator<'self> {
23122318
priv it: vec::VecIterator<'self, u8>
23132319
}
@@ -2321,6 +2327,7 @@ impl<'self> Iterator<u8> for StrBytesIterator<'self> {
23212327
23222328
/// External iterator for a string's bytes in reverse order. Use with
23232329
/// the `std::iterator` module.
2330+
#[deriving(Clone)]
23242331
pub struct StrBytesRevIterator<'self> {
23252332
priv it: vec::VecRevIterator<'self, u8>
23262333
}

src/libstd/vec.rs

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2232,6 +2232,10 @@ iterator!{impl VecIterator -> &'self T}
22322232
double_ended_iterator!{impl VecIterator -> &'self T}
22332233
pub type VecRevIterator<'self, T> = InvertIterator<&'self T, VecIterator<'self, T>>;
22342234

2235+
impl<'self, T> Clone for VecIterator<'self, T> {
2236+
fn clone(&self) -> VecIterator<'self, T> { *self }
2237+
}
2238+
22352239
//iterator!{struct VecMutIterator -> *mut T, &'self mut T}
22362240
/// An iterator for mutating the elements of a vector.
22372241
pub struct VecMutIterator<'self, T> {
@@ -2244,6 +2248,7 @@ double_ended_iterator!{impl VecMutIterator -> &'self mut T}
22442248
pub type VecMutRevIterator<'self, T> = InvertIterator<&'self mut T, VecMutIterator<'self, T>>;
22452249

22462250
/// An iterator that moves out of a vector.
2251+
#[deriving(Clone)]
22472252
pub struct VecConsumeIterator<T> {
22482253
priv v: ~[T],
22492254
priv idx: uint,
@@ -2270,6 +2275,7 @@ impl<T> Iterator<T> for VecConsumeIterator<T> {
22702275
}
22712276

22722277
/// An iterator that moves out of a vector in reverse order.
2278+
#[deriving(Clone)]
22732279
pub struct VecConsumeRevIterator<T> {
22742280
priv v: ~[T]
22752281
}
@@ -3185,6 +3191,17 @@ mod tests {
31853191
assert_eq!(xs.mut_rev_iter().size_hint(), (5, Some(5)));
31863192
}
31873193

3194+
#[test]
3195+
fn test_iter_clone() {
3196+
let xs = [1, 2, 5];
3197+
let mut it = xs.iter();
3198+
it.next();
3199+
let mut jt = it.clone();
3200+
assert_eq!(it.next(), jt.next());
3201+
assert_eq!(it.next(), jt.next());
3202+
assert_eq!(it.next(), jt.next());
3203+
}
3204+
31883205
#[test]
31893206
fn test_mut_iterator() {
31903207
use iterator::*;

0 commit comments

Comments
 (0)