From 435fcda5e99ad5944c780f864a550b3211a6ab47 Mon Sep 17 00:00:00 2001 From: blake2-ppc Date: Thu, 18 Jul 2013 17:09:08 +0200 Subject: [PATCH] iterator: Add .cycle() to repeat an iterator --- src/libstd/iterator.rs | 49 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 49 insertions(+) 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> OrdIterator for T { } } +/// A trait for iterators that are clonable. +// FIXME #6967: Dummy A parameter to get around type inference bug +pub trait ClonableIterator { + /// 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; +} + +impl> ClonableIterator for T { + #[inline] + fn cycle(self) -> CycleIterator { + CycleIterator{orig: self.clone(), iter: self} + } +} + +/// An iterator that repeats endlessly +pub struct CycleIterator { + priv orig: T, + priv iter: T, +} + +impl> Iterator for CycleIterator { + #[inline] + fn next(&mut self) -> Option { + match self.iter.next() { + None => { self.iter = self.orig.clone(); self.iter.next() } + y => y + } + } + + #[inline] + fn size_hint(&self) -> (uint, Option) { + // 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 {