]> git.lizzy.rs Git - rust.git/commitdiff
initial iterator object library
authorDaniel Micay <danielmicay@gmail.com>
Tue, 9 Apr 2013 14:54:32 +0000 (10:54 -0400)
committerDaniel Micay <danielmicay@gmail.com>
Sat, 13 Apr 2013 09:51:14 +0000 (05:51 -0400)
src/libcore/core.rc
src/libcore/iterator.rs [new file with mode: 0644]
src/libstd/serialize.rs
src/libstd/std.rc
src/libstd/treemap.rs

index 3368f6df870901cb7195c768ffb7d8c759b6cab5..2415ae1d1941cc55bb670e1fecd7c07f5583812d 100644 (file)
@@ -176,6 +176,7 @@ pub mod from_str;
 #[path = "num/num.rs"]
 pub mod num;
 pub mod iter;
+pub mod iterator;
 pub mod to_str;
 pub mod to_bytes;
 pub mod clone;
diff --git a/src/libcore/iterator.rs b/src/libcore/iterator.rs
new file mode 100644 (file)
index 0000000..e7a2f3a
--- /dev/null
@@ -0,0 +1,101 @@
+// Copyright 2013 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+//! Composable iterator objects
+
+use prelude::*;
+
+pub trait Iterator<T> {
+    /// Advance the iterator and return the next value. Return `None` when the end is reached.
+    fn next(&mut self) -> Option<T>;
+}
+
+/// A shim implementing the `for` loop iteration protocol for iterator objects
+#[inline]
+pub fn advance<T, U: Iterator<T>>(iter: &mut U, f: &fn(T) -> bool) {
+    loop {
+        match iter.next() {
+            Some(x) => {
+                if !f(x) { return }
+            }
+            None => return
+        }
+    }
+}
+
+pub struct ZipIterator<T, U> {
+    priv a: T,
+    priv b: U
+}
+
+pub impl<A, B, T: Iterator<A>, U: Iterator<B>> ZipIterator<T, U> {
+    #[inline(always)]
+    fn new(a: T, b: U) -> ZipIterator<T, U> {
+        ZipIterator{a: a, b: b}
+    }
+}
+
+impl<A, B, T: Iterator<A>, U: Iterator<B>> Iterator<(A, B)> for ZipIterator<T, U> {
+    #[inline]
+    fn next(&mut self) -> Option<(A, B)> {
+        match (self.a.next(), self.b.next()) {
+            (Some(x), Some(y)) => Some((x, y)),
+            _ => None
+        }
+    }
+}
+
+pub struct FilterIterator<'self, A, T> {
+    priv iter: T,
+    priv predicate: &'self fn(&A) -> bool
+}
+
+pub impl<'self, A, T: Iterator<A>> FilterIterator<'self, A, T> {
+    #[inline(always)]
+    fn new(iter: T, predicate: &'self fn(&A) -> bool) -> FilterIterator<'self, A, T> {
+        FilterIterator{iter: iter, predicate: predicate}
+    }
+}
+
+impl<'self, A, T: Iterator<A>> Iterator<A> for FilterIterator<'self, A, T> {
+    #[inline]
+    fn next(&mut self) -> Option<A> {
+        for advance(self) |x| {
+            if (self.predicate)(&x) {
+                return Some(x);
+            } else {
+                loop
+            }
+        }
+        None
+    }
+}
+
+pub struct MapIterator<'self, A, B, T> {
+    priv iter: T,
+    priv f: &'self fn(A) -> B
+}
+
+pub impl<'self, A, B, T: Iterator<A>> MapIterator<'self, A, B, T> {
+    #[inline(always)]
+    fn new(iter: T, f: &'self fn(A) -> B) -> MapIterator<'self, A, B, T> {
+        MapIterator{iter: iter, f: f}
+    }
+}
+
+impl<'self, A, B, T: Iterator<A>> Iterator<B> for MapIterator<'self, A, B, T> {
+    #[inline]
+    fn next(&mut self) -> Option<B> {
+        match self.iter.next() {
+            Some(a) => Some((self.f)(a)),
+            _ => None
+        }
+    }
+}
index 68ae9a6641726410abf5c2719c972b7ed2a706cd..e4e53b9b61486af912b192a2d4cf12185ad6168b 100644 (file)
@@ -21,6 +21,9 @@
 use core::trie::{TrieMap, TrieSet};
 use deque::Deque;
 use dlist::DList;
+#[cfg(stage1)]
+#[cfg(stage2)]
+#[cfg(stage3)]
 use treemap::{TreeMap, TreeSet};
 
 pub trait Encoder {
@@ -738,6 +741,9 @@ fn decode(d: &D) -> TrieSet {
     }
 }
 
+#[cfg(stage1)]
+#[cfg(stage2)]
+#[cfg(stage3)]
 impl<
     E: Encoder,
     K: Encodable<E> + Eq + TotalOrd,
@@ -755,6 +761,9 @@ fn encode(&self, e: &E) {
     }
 }
 
+#[cfg(stage1)]
+#[cfg(stage2)]
+#[cfg(stage3)]
 impl<
     D: Decoder,
     K: Decodable<D> + Eq + TotalOrd,
@@ -773,6 +782,9 @@ fn decode(d: &D) -> TreeMap<K, V> {
     }
 }
 
+#[cfg(stage1)]
+#[cfg(stage2)]
+#[cfg(stage3)]
 impl<
     S: Encoder,
     T: Encodable<S> + Eq + TotalOrd
@@ -788,6 +800,9 @@ fn encode(&self, s: &S) {
     }
 }
 
+#[cfg(stage1)]
+#[cfg(stage2)]
+#[cfg(stage3)]
 impl<
     D: Decoder,
     T: Decodable<D> + Eq + TotalOrd
index fb340d80c2dbc9f240ccd040068f9dc5e041c528..3dfc3200f0f5205d3680c54c609161c376a82f4d 100644 (file)
@@ -76,6 +76,9 @@ pub mod rope;
 pub mod smallintmap;
 pub mod sort;
 pub mod dlist;
+#[cfg(stage1)]
+#[cfg(stage2)]
+#[cfg(stage3)]
 pub mod treemap;
 
 // And ... other stuff
index 006455c44e429c1fcd6caddd097518024b02475f..bc8cbaa0825ce0b66725ac9f07ec0743490db768 100644 (file)
@@ -13,6 +13,7 @@
 //! `TotalOrd`.
 
 use core::prelude::*;
+use core::iterator::*;
 
 // This is implemented as an AA tree, which is a simplified variation of
 // a red-black tree where where red (horizontal) nodes can only be added
@@ -43,8 +44,7 @@ fn eq(&self, other: &TreeMap<K, V>) -> bool {
             let mut x = self.iter();
             let mut y = other.iter();
             for self.len().times {
-                if map_next(&mut x).unwrap() !=
-                   map_next(&mut y).unwrap() {
+                if x.next().unwrap() != y.next().unwrap() {
                     return false
                 }
             }
@@ -62,8 +62,8 @@ fn lt<K: Ord + TotalOrd, V>(a: &TreeMap<K, V>,
 
     let (a_len, b_len) = (a.len(), b.len());
     for uint::min(a_len, b_len).times {
-        let (key_a,_) = map_next(&mut x).unwrap();
-        let (key_b,_) = map_next(&mut y).unwrap();
+        let (key_a,_) = x.next().unwrap();
+        let (key_b,_) = y.next().unwrap();
         if *key_a < *key_b { return true; }
         if *key_a > *key_b { return false; }
     };
@@ -105,15 +105,6 @@ fn contains_key(&self, key: &K) -> bool {
     }
 
     /// Visit all key-value pairs in order
-    #[cfg(stage0)]
-    fn each(&self, f: &fn(&'self K, &'self V) -> bool) {
-        each(&self.root, f)
-    }
-
-    /// Visit all key-value pairs in order
-    #[cfg(stage1)]
-    #[cfg(stage2)]
-    #[cfg(stage3)]
     fn each<'a>(&'a self, f: &fn(&'a K, &'a V) -> bool) {
         each(&self.root, f)
     }
@@ -124,15 +115,6 @@ fn each_key(&self, f: &fn(&K) -> bool) {
     }
 
     /// Visit all values in order
-    #[cfg(stage0)]
-    fn each_value(&self, f: &fn(&V) -> bool) {
-        self.each(|_, v| f(v))
-    }
-
-    /// Visit all values in order
-    #[cfg(stage1)]
-    #[cfg(stage2)]
-    #[cfg(stage3)]
     fn each_value<'a>(&'a self, f: &fn(&'a V) -> bool) {
         self.each(|_, v| f(v))
     }
@@ -143,27 +125,6 @@ fn mutate_values(&mut self, f: &fn(&K, &mut V) -> bool) {
     }
 
     /// Return a reference to the value corresponding to the key
-    #[cfg(stage0)]
-    fn find(&self, key: &K) -> Option<&'self V> {
-        let mut current: &'self Option<~TreeNode<K, V>> = &self.root;
-        loop {
-            match *current {
-              Some(ref r) => {
-                match key.cmp(&r.key) {
-                  Less => current = &r.left,
-                  Greater => current = &r.right,
-                  Equal => return Some(&r.value)
-                }
-              }
-              None => return None
-            }
-        }
-    }
-
-    /// Return a reference to the value corresponding to the key
-    #[cfg(stage1)]
-    #[cfg(stage2)]
-    #[cfg(stage3)]
     fn find<'a>(&'a self, key: &K) -> Option<&'a V> {
         let mut current: &'a Option<~TreeNode<K, V>> = &self.root;
         loop {
@@ -182,16 +143,6 @@ fn find<'a>(&'a self, key: &K) -> Option<&'a V> {
 
     /// Return a mutable reference to the value corresponding to the key
     #[inline(always)]
-    #[cfg(stage0)]
-    fn find_mut(&mut self, key: &K) -> Option<&'self mut V> {
-        find_mut(&mut self.root, key)
-    }
-
-    /// Return a mutable reference to the value corresponding to the key
-    #[inline(always)]
-    #[cfg(stage1)]
-    #[cfg(stage2)]
-    #[cfg(stage3)]
     fn find_mut<'a>(&'a mut self, key: &K) -> Option<&'a mut V> {
         find_mut(&mut self.root, key)
     }
@@ -219,15 +170,6 @@ pub impl<K: TotalOrd, V> TreeMap<K, V> {
     fn new() -> TreeMap<K, V> { TreeMap{root: None, length: 0} }
 
     /// Visit all key-value pairs in reverse order
-    #[cfg(stage0)]
-    fn each_reverse(&self, f: &fn(&'self K, &'self V) -> bool) {
-        each_reverse(&self.root, f);
-    }
-
-    /// Visit all key-value pairs in reverse order
-    #[cfg(stage1)]
-    #[cfg(stage2)]
-    #[cfg(stage3)]
     fn each_reverse<'a>(&'a self, f: &fn(&'a K, &'a V) -> bool) {
         each_reverse(&self.root, f);
     }
@@ -244,16 +186,6 @@ fn each_value_reverse(&self, f: &fn(&V) -> bool) {
 
     /// Get a lazy iterator over the key-value pairs in the map.
     /// Requires that it be frozen (immutable).
-    #[cfg(stage0)]
-    fn iter(&self) -> TreeMapIterator<'self, K, V> {
-        TreeMapIterator{stack: ~[], node: &self.root}
-    }
-
-    /// Get a lazy iterator over the key-value pairs in the map.
-    /// Requires that it be frozen (immutable).
-    #[cfg(stage1)]
-    #[cfg(stage2)]
-    #[cfg(stage3)]
     fn iter<'a>(&'a self) -> TreeMapIterator<'a, K, V> {
         TreeMapIterator{stack: ~[], node: &self.root}
     }
@@ -265,37 +197,33 @@ pub struct TreeMapIterator<'self, K, V> {
     priv node: &'self Option<~TreeNode<K, V>>
 }
 
-/// Advance the iterator to the next node (in order) and return a
-/// tuple with a reference to the key and value. If there are no
-/// more nodes, return `None`.
-pub fn map_next<'r, K, V>(iter: &mut TreeMapIterator<'r, K, V>)
-                       -> Option<(&'r K, &'r V)> {
-    while !iter.stack.is_empty() || iter.node.is_some() {
-        match *iter.node {
-          Some(ref x) => {
-            iter.stack.push(x);
-            iter.node = &x.left;
-          }
-          None => {
-            let res = iter.stack.pop();
-            iter.node = &res.right;
-            return Some((&res.key, &res.value));
-          }
+impl<'self, K, V> Iterator<(&'self K, &'self V)> for TreeMapIterator<'self, K, V> {
+    /// Advance the iterator to the next node (in order) and return a
+    /// tuple with a reference to the key and value. If there are no
+    /// more nodes, return `None`.
+    fn next(&mut self) -> Option<(&'self K, &'self V)> {
+        while !self.stack.is_empty() || self.node.is_some() {
+            match *self.node {
+              Some(ref x) => {
+                self.stack.push(x);
+                self.node = &x.left;
+              }
+              None => {
+                let res = self.stack.pop();
+                self.node = &res.right;
+                return Some((&res.key, &res.value));
+              }
+            }
         }
+        None
     }
-    None
 }
 
-/// Advance the iterator through the map
-pub fn map_advance<'r, K, V>(iter: &mut TreeMapIterator<'r, K, V>,
-                             f: &fn((&'r K, &'r V)) -> bool) {
-    loop {
-        match map_next(iter) {
-          Some(x) => {
-            if !f(x) { return }
-          }
-          None => return
-        }
+impl<'self, T> Iterator<&'self T> for TreeSetIterator<'self, T> {
+    /// Advance the iterator to the next node (in order). If there are no more nodes, return `None`.
+    #[inline(always)]
+    fn next(&mut self) -> Option<&'self T> {
+        do self.iter.next().map |&(value, _)| { value }
     }
 }
 
@@ -375,14 +303,14 @@ fn remove(&mut self, value: &T) -> bool { self.map.remove(value) }
     fn is_disjoint(&self, other: &TreeSet<T>) -> bool {
         let mut x = self.iter();
         let mut y = other.iter();
-        let mut a = set_next(&mut x);
-        let mut b = set_next(&mut y);
+        let mut a = x.next();
+        let mut b = y.next();
         while a.is_some() && b.is_some() {
             let a1 = a.unwrap();
             let b1 = b.unwrap();
             match a1.cmp(b1) {
-              Less => a = set_next(&mut x),
-              Greater => b = set_next(&mut y),
+              Less => a = x.next(),
+              Greater => b = y.next(),
               Equal => return false
             }
         }
@@ -399,8 +327,8 @@ fn is_subset(&self, other: &TreeSet<T>) -> bool {
     fn is_superset(&self, other: &TreeSet<T>) -> bool {
         let mut x = self.iter();
         let mut y = other.iter();
-        let mut a = set_next(&mut x);
-        let mut b = set_next(&mut y);
+        let mut a = x.next();
+        let mut b = y.next();
         while b.is_some() {
             if a.is_none() {
                 return false
@@ -412,10 +340,10 @@ fn is_superset(&self, other: &TreeSet<T>) -> bool {
             match a1.cmp(b1) {
               Less => (),
               Greater => return false,
-              Equal => b = set_next(&mut y),
+              Equal => b = y.next(),
             }
 
-            a = set_next(&mut x);
+            a = x.next();
         }
         true
     }
@@ -425,13 +353,13 @@ fn difference(&self, other: &TreeSet<T>, f: &fn(&T) -> bool) {
         let mut x = self.iter();
         let mut y = other.iter();
 
-        let mut a = set_next(&mut x);
-        let mut b = set_next(&mut y);
+        let mut a = x.next();
+        let mut b = y.next();
 
         while a.is_some() {
             if b.is_none() {
                 return do a.while_some() |a1| {
-                    if f(a1) { set_next(&mut x) } else { None }
+                    if f(a1) { x.next() } else { None }
                 }
             }
 
@@ -442,10 +370,10 @@ fn difference(&self, other: &TreeSet<T>, f: &fn(&T) -> bool) {
 
             if cmp == Less {
                 if !f(a1) { return }
-                a = set_next(&mut x);
+                a = x.next();
             } else {
-                if cmp == Equal { a = set_next(&mut x) }
-                b = set_next(&mut y);
+                if cmp == Equal { a = x.next() }
+                b = y.next();
             }
         }
     }
@@ -456,13 +384,13 @@ fn symmetric_difference(&self, other: &TreeSet<T>,
         let mut x = self.iter();
         let mut y = other.iter();
 
-        let mut a = set_next(&mut x);
-        let mut b = set_next(&mut y);
+        let mut a = x.next();
+        let mut b = y.next();
 
         while a.is_some() {
             if b.is_none() {
                 return do a.while_some() |a1| {
-                    if f(a1) { set_next(&mut x) } else { None }
+                    if f(a1) { x.next() } else { None }
                 }
             }
 
@@ -473,18 +401,18 @@ fn symmetric_difference(&self, other: &TreeSet<T>,
 
             if cmp == Less {
                 if !f(a1) { return }
-                a = set_next(&mut x);
+                a = x.next();
             } else {
                 if cmp == Greater {
                     if !f(b1) { return }
                 } else {
-                    a = set_next(&mut x);
+                    a = x.next();
                 }
-                b = set_next(&mut y);
+                b = y.next();
             }
         }
         do b.while_some |b1| {
-            if f(b1) { set_next(&mut y) } else { None }
+            if f(b1) { y.next() } else { None }
         }
     }
 
@@ -493,8 +421,8 @@ fn intersection(&self, other: &TreeSet<T>, f: &fn(&T) -> bool) {
         let mut x = self.iter();
         let mut y = other.iter();
 
-        let mut a = set_next(&mut x);
-        let mut b = set_next(&mut y);
+        let mut a = x.next();
+        let mut b = y.next();
 
         while a.is_some() && b.is_some() {
             let a1 = a.unwrap();
@@ -503,12 +431,12 @@ fn intersection(&self, other: &TreeSet<T>, f: &fn(&T) -> bool) {
             let cmp = a1.cmp(b1);
 
             if cmp == Less {
-                a = set_next(&mut x);
+                a = x.next();
             } else {
                 if cmp == Equal {
                     if !f(a1) { return }
                 }
-                b = set_next(&mut y);
+                b = y.next();
             }
         }
     }
@@ -518,13 +446,13 @@ fn union(&self, other: &TreeSet<T>, f: &fn(&T) -> bool) {
         let mut x = self.iter();
         let mut y = other.iter();
 
-        let mut a = set_next(&mut x);
-        let mut b = set_next(&mut y);
+        let mut a = x.next();
+        let mut b = y.next();
 
         while a.is_some() {
             if b.is_none() {
                 return do a.while_some() |a1| {
-                    if f(a1) { set_next(&mut x) } else { None }
+                    if f(a1) { x.next() } else { None }
                 }
             }
 
@@ -535,17 +463,17 @@ fn union(&self, other: &TreeSet<T>, f: &fn(&T) -> bool) {
 
             if cmp == Greater {
                 if !f(b1) { return }
-                b = set_next(&mut y);
+                b = y.next();
             } else {
                 if !f(a1) { return }
                 if cmp == Equal {
-                    b = set_next(&mut y);
+                    b = y.next();
                 }
-                a = set_next(&mut x);
+                a = x.next();
             }
         }
         do b.while_some |b1| {
-            if f(b1) { set_next(&mut y) } else { None }
+            if f(b1) { y.next() } else { None }
         }
     }
 }
@@ -558,17 +486,6 @@ fn new() -> TreeSet<T> { TreeSet{map: TreeMap::new()} }
     /// Get a lazy iterator over the values in the set.
     /// Requires that it be frozen (immutable).
     #[inline(always)]
-    #[cfg(stage0)]
-    fn iter(&self) -> TreeSetIterator<'self, T> {
-        TreeSetIterator{iter: self.map.iter()}
-    }
-
-    /// Get a lazy iterator over the values in the set.
-    /// Requires that it be frozen (immutable).
-    #[inline(always)]
-    #[cfg(stage1)]
-    #[cfg(stage2)]
-    #[cfg(stage3)]
     fn iter<'a>(&'a self) -> TreeSetIterator<'a, T> {
         TreeSetIterator{iter: self.map.iter()}
     }
@@ -579,20 +496,6 @@ pub struct TreeSetIterator<'self, T> {
     priv iter: TreeMapIterator<'self, T, ()>
 }
 
-/// Advance the iterator to the next node (in order). If this iterator is
-/// finished, does nothing.
-#[inline(always)]
-pub fn set_next<'r, T>(iter: &mut TreeSetIterator<'r, T>) -> Option<&'r T> {
-    do map_next(&mut iter.iter).map |&(value, _)| { value }
-}
-
-/// Advance the iterator through the set
-#[inline(always)]
-pub fn set_advance<'r, T>(iter: &mut TreeSetIterator<'r, T>,
-                          f: &fn(&'r T) -> bool) {
-    do map_advance(&mut iter.iter) |(k, _)| { f(k) }
-}
-
 // Nodes keep track of their level in the tree, starting at 1 in the
 // leaves and with a red child sharing the level of the parent.
 struct TreeNode<K, V> {
@@ -792,6 +695,7 @@ fn heir_swap<K: TotalOrd, V>(node: &mut ~TreeNode<K, V>,
 #[cfg(test)]
 mod test_treemap {
     use core::prelude::*;
+    use core::iterator::*;
     use super::*;
     use core::rand::RngUtil;
     use core::rand;
@@ -1078,13 +982,13 @@ fn test_lazy_iterator() {
         let m = m;
         let mut a = m.iter();
 
-        assert!(map_next(&mut a).unwrap() == (&x1, &y1));
-        assert!(map_next(&mut a).unwrap() == (&x2, &y2));
-        assert!(map_next(&mut a).unwrap() == (&x3, &y3));
-        assert!(map_next(&mut a).unwrap() == (&x4, &y4));
-        assert!(map_next(&mut a).unwrap() == (&x5, &y5));
+        assert!(a.next().unwrap() == (&x1, &y1));
+        assert!(a.next().unwrap() == (&x2, &y2));
+        assert!(a.next().unwrap() == (&x3, &y3));
+        assert!(a.next().unwrap() == (&x4, &y4));
+        assert!(a.next().unwrap() == (&x5, &y5));
 
-        assert!(map_next(&mut a).is_none());
+        assert!(a.next().is_none());
 
         let mut b = m.iter();
 
@@ -1092,7 +996,7 @@ fn test_lazy_iterator() {
                         (&x5, &y5)];
         let mut i = 0;
 
-        for map_advance(&mut b) |x| {
+        for advance(&mut b) |x| {
             assert!(expected[i] == x);
             i += 1;
 
@@ -1101,7 +1005,7 @@ fn test_lazy_iterator() {
             }
         }
 
-        for map_advance(&mut b) |x| {
+        for advance(&mut b) |x| {
             assert!(expected[i] == x);
             i += 1;
         }
@@ -1110,6 +1014,8 @@ fn test_lazy_iterator() {
 
 #[cfg(test)]
 mod test_set {
+    use core::prelude::*;
+    use core::iterator::*;
     use super::*;
 
     #[test]
@@ -1289,4 +1195,30 @@ fn check_union(a: &[int], b: &[int],
                     [-2, 1, 5, 9, 13, 19],
                     [-2, 1, 3, 5, 9, 11, 13, 16, 19, 24]);
     }
+
+    #[test]
+    fn test_zip() {
+        let mut x = TreeSet::new();
+        x.insert(5u);
+        x.insert(12u);
+        x.insert(11u);
+
+        let mut y = TreeSet::new();
+        y.insert("foo");
+        y.insert("bar");
+
+        let x = x;
+        let y = y;
+        let mut z = ZipIterator::new(x.iter(), y.iter());
+
+        // FIXME: #5801: this needs a type hint to compile...
+        let result: Option<(&uint, & &'static str)> = z.next();
+        assert!(result.unwrap() == (&5u, & &"bar"));
+
+        let result: Option<(&uint, & &'static str)> = z.next();
+        assert!(result.unwrap() == (&11u, & &"foo"));
+
+        let result: Option<(&uint, & &'static str)> = z.next();
+        assert!(result.is_none());
+    }
 }