diff options
| author | Jakub Wieczorek <jakub@jakub.cc> | 2014-07-07 00:50:53 +0200 |
|---|---|---|
| committer | Jakub Wieczorek <jakub@jakub.cc> | 2014-07-13 11:47:40 +0200 |
| commit | ed54162e86cd00b7a4ced8957aac7f56897f6fb5 (patch) | |
| tree | 675f830b5b9cd3b28ff9f976dab70c06b30735a4 /src | |
| parent | 88231a9b70574990363262e6be8451df8782e4ca (diff) | |
| download | rust-ed54162e86cd00b7a4ced8957aac7f56897f6fb5.tar.gz rust-ed54162e86cd00b7a4ced8957aac7f56897f6fb5.zip | |
Add an iterate function to core::iter
Implementation by Kevin Ballard. The function returns an Unfold iterator producing an infinite stream of results of repeated applications of the function, starting from the provided seed value.
Diffstat (limited to 'src')
| -rw-r--r-- | src/libcore/iter.rs | 29 | ||||
| -rw-r--r-- | src/libcoretest/iter.rs | 9 |
2 files changed, 34 insertions, 4 deletions
diff --git a/src/libcore/iter.rs b/src/libcore/iter.rs index 80b784250f0..855bccb07a7 100644 --- a/src/libcore/iter.rs +++ b/src/libcore/iter.rs @@ -64,14 +64,14 @@ the rest of the rust manuals. */ +use clone::Clone; use cmp; +use cmp::{PartialEq, PartialOrd, Ord}; +use mem; use num::{Zero, One, CheckedAdd, CheckedSub, Saturating, ToPrimitive, Int}; -use option::{Option, Some, None}; use ops::{Add, Mul, Sub}; -use cmp::{PartialEq, PartialOrd, Ord}; -use clone::Clone; +use option::{Option, Some, None}; use uint; -use mem; /// Conversion from an `Iterator` pub trait FromIterator<A> { @@ -2192,6 +2192,27 @@ impl<A: Clone> RandomAccessIterator<A> for Repeat<A> { fn idx(&mut self, _: uint) -> Option<A> { Some(self.element.clone()) } } +type IterateState<'a, T> = (|T|: 'a -> T, Option<T>, bool); + +/// An iterator that repeatedly applies a given function, starting +/// from a given seed value. +pub type Iterate<'a, T> = Unfold<'a, T, IterateState<'a, T>>; + +/// Creates a new iterator that produces an infinite sequence of +/// repeated applications of the given function `f`. +#[allow(visible_private_types)] +pub fn iterate<'a, T: Clone>(f: |T|: 'a -> T, seed: T) -> Iterate<'a, T> { + Unfold::new((f, Some(seed), true), |st| { + let &(ref mut f, ref mut val, ref mut first) = st; + if *first { + *first = false; + } else { + val.mutate(|x| (*f)(x)); + } + val.clone() + }) +} + /// Functions for lexicographical ordering of sequences. /// /// Lexicographical ordering through `<`, `<=`, `>=`, `>` requires diff --git a/src/libcoretest/iter.rs b/src/libcoretest/iter.rs index 86b5ffece41..64c33609399 100644 --- a/src/libcoretest/iter.rs +++ b/src/libcoretest/iter.rs @@ -833,3 +833,12 @@ fn test_min_max_result() { let r = MinMax(1i,2); assert_eq!(r.into_option(), Some((1,2))); } + +#[test] +fn test_iterate() { + let mut it = iterate(|x| x * 2, 1u); + assert_eq!(it.next(), Some(1u)); + assert_eq!(it.next(), Some(2u)); + assert_eq!(it.next(), Some(4u)); + assert_eq!(it.next(), Some(8u)); +} |
