about summary refs log tree commit diff
path: root/src/libstd
diff options
context:
space:
mode:
authorblake2-ppc <blake2-ppc>2013-07-18 17:09:08 +0200
committerblake2-ppc <blake2-ppc>2013-07-20 20:22:48 +0200
commit435fcda5e99ad5944c780f864a550b3211a6ab47 (patch)
tree28ab4408fc76942c0581436c2ea4e6a1ba5ec94b /src/libstd
parent8aae6edce09a8e2a32a154acb55c9879dbebf99c (diff)
downloadrust-435fcda5e99ad5944c780f864a550b3211a6ab47.tar.gz
rust-435fcda5e99ad5944c780f864a550b3211a6ab47.zip
iterator: Add .cycle() to repeat an iterator
Diffstat (limited to 'src/libstd')
-rw-r--r--src/libstd/iterator.rs49
1 files changed, 49 insertions, 0 deletions
diff --git a/src/libstd/iterator.rs b/src/libstd/iterator.rs
index c8cde69197b..13c234d6397 100644
--- a/src/libstd/iterator.rs
+++ b/src/libstd/iterator.rs
@@ -729,6 +729,55 @@ impl<A: Ord, T: Iterator<A>> OrdIterator<A> for T {
     }
 }
 
+/// A trait for iterators that are clonable.
+// FIXME #6967: Dummy A parameter to get around type inference bug
+pub trait ClonableIterator<A> {
+    /// Repeats an iterator endlessly
+    ///
+    /// # Example
+    ///
+    /// ~~~ {.rust}
+    /// let a = Counter::new(1,1).take_(1);
+    /// let mut cy = a.cycle();
+    /// assert_eq!(cy.next(), Some(1));
+    /// assert_eq!(cy.next(), Some(1));
+    /// ~~~
+    fn cycle(self) -> CycleIterator<A, Self>;
+}
+
+impl<A, T: Clone + Iterator<A>> ClonableIterator<A> for T {
+    #[inline]
+    fn cycle(self) -> CycleIterator<A, T> {
+        CycleIterator{orig: self.clone(), iter: self}
+    }
+}
+
+/// An iterator that repeats endlessly
+pub struct CycleIterator<A, T> {
+    priv orig: T,
+    priv iter: T,
+}
+
+impl<A, T: Clone + Iterator<A>> Iterator<A> for CycleIterator<A, T> {
+    #[inline]
+    fn next(&mut self) -> Option<A> {
+        match self.iter.next() {
+            None => { self.iter = self.orig.clone(); self.iter.next() }
+            y => y
+        }
+    }
+
+    #[inline]
+    fn size_hint(&self) -> (uint, Option<uint>) {
+        // the cycle iterator is either empty or infinite
+        match self.orig.size_hint() {
+            sz @ (0, Some(0)) => sz,
+            (0, _) => (0, None),
+            _ => (uint::max_value, None)
+        }
+    }
+}
+
 /// An iterator which strings two iterators together
 // FIXME #6967: Dummy A parameter to get around type inference bug
 pub struct ChainIterator<A, T, U> {