Skip to content

Commit 435fcda

Browse files
author
blake2-ppc
committed
iterator: Add .cycle() to repeat an iterator
1 parent 8aae6ed commit 435fcda

File tree

1 file changed

+49
-0
lines changed

1 file changed

+49
-0
lines changed

src/libstd/iterator.rs

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -729,6 +729,55 @@ impl<A: Ord, T: Iterator<A>> OrdIterator<A> for T {
729729
}
730730
}
731731

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

0 commit comments

Comments
 (0)