about summary refs log tree commit diff
diff options
context:
space:
mode:
authorJakub Wieczorek <jakub@jakub.cc>2014-07-07 00:50:53 +0200
committerJakub Wieczorek <jakub@jakub.cc>2014-07-13 11:47:40 +0200
commited54162e86cd00b7a4ced8957aac7f56897f6fb5 (patch)
tree675f830b5b9cd3b28ff9f976dab70c06b30735a4
parent88231a9b70574990363262e6be8451df8782e4ca (diff)
downloadrust-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.
-rw-r--r--src/libcore/iter.rs29
-rw-r--r--src/libcoretest/iter.rs9
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));
+}