about summary refs log tree commit diff
path: root/src/libextra
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2013-07-20 16:58:30 -0700
committerbors <bors@rust-lang.org>2013-07-20 16:58:30 -0700
commit75b4b1b027ec5c5b72d496b7a10da418d5308c01 (patch)
treeddfc2e765cb0ca29eea8fb60196e7bff10fbb7c9 /src/libextra
parentbb8ca1f52cfa59e0040c2c749a1c46048fc6d48d (diff)
parentfe134b9509821e5e2fad5545cdd23c5325dfd583 (diff)
downloadrust-75b4b1b027ec5c5b72d496b7a10da418d5308c01.tar.gz
rust-75b4b1b027ec5c5b72d496b7a10da418d5308c01.zip
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.
Diffstat (limited to 'src/libextra')
-rw-r--r--src/libextra/dlist.rs23
1 files changed, 23 insertions, 0 deletions
diff --git a/src/libextra/dlist.rs b/src/libextra/dlist.rs
index c42eba1ffa2..fe05b48988e 100644
--- a/src/libextra/dlist.rs
+++ b/src/libextra/dlist.rs
@@ -47,6 +47,7 @@ struct Node<T> {
 }
 
 /// Double-ended DList iterator
+#[deriving(Clone)]
 pub struct DListIterator<'self, T> {
     priv head: &'self Link<T>,
     priv tail: Rawlink<Node<T>>,
@@ -62,6 +63,7 @@ pub struct MutDListIterator<'self, T> {
 }
 
 /// DList consuming iterator
+#[deriving(Clone)]
 pub struct ConsumeIterator<T> {
     priv list: DList<T>
 }
@@ -93,6 +95,13 @@ impl<T> Rawlink<T> {
     }
 }
 
+impl<T> Clone for Rawlink<T> {
+    #[inline]
+    fn clone(&self) -> Rawlink<T> {
+        Rawlink{p: self.p}
+    }
+}
+
 /// Set the .prev field on `next`, then return `Some(next)`
 fn link_with_prev<T>(mut next: ~Node<T>, prev: Rawlink<Node<T>>) -> Link<T> {
     next.prev = prev;
@@ -687,6 +696,20 @@ mod tests {
     }
 
     #[test]
+    fn test_iterator_clone() {
+        let mut n = DList::new();
+        n.push_back(2);
+        n.push_back(3);
+        n.push_back(4);
+        let mut it = n.iter();
+        it.next();
+        let mut jt = it.clone();
+        assert_eq!(it.next(), jt.next());
+        assert_eq!(it.next_back(), jt.next_back());
+        assert_eq!(it.next(), jt.next());
+    }
+
+    #[test]
     fn test_iterator_double_end() {
         let mut n = DList::new();
         assert_eq!(n.iter().next(), None);