]> git.lizzy.rs Git - rust.git/commitdiff
extra: add consume iter to treemap.
authorGraydon Hoare <graydon@mozilla.com>
Thu, 18 Jul 2013 19:37:18 +0000 (12:37 -0700)
committerGraydon Hoare <graydon@mozilla.com>
Tue, 23 Jul 2013 22:23:02 +0000 (15:23 -0700)
src/libextra/treemap.rs

index f9b2c8429cff7a2f4f811c6851bfdedf8bcdf2d6..4ad1f56a9ae54a77e610dc5df53f7011a9f5c4ec 100644 (file)
@@ -204,6 +204,19 @@ pub fn each_value_reverse(&self, f: &fn(&V) -> bool) -> bool {
     pub fn iter<'a>(&'a self) -> TreeMapIterator<'a, K, V> {
         TreeMapIterator{stack: ~[], node: &self.root, remaining: self.length}
     }
+
+    /// Get a lazy iterator that consumes the treemap.
+    pub fn consume_iter(self) -> TreeMapConsumeIterator<K, V> {
+        let TreeMap { root: root, length: length } = self;
+        let stk = match root {
+            None => ~[],
+            Some(~tn) => ~[tn]
+        };
+        TreeMapConsumeIterator {
+            stack: stk,
+            remaining: length
+        }
+    }
 }
 
 /// Lazy forward iterator over a map
@@ -241,6 +254,56 @@ fn size_hint(&self) -> (uint, Option<uint>) {
     }
 }
 
+/// Lazy forward iterator over a map that consumes the map while iterating
+pub struct TreeMapConsumeIterator<K, V> {
+    priv stack: ~[TreeNode<K, V>],
+    priv remaining: uint
+}
+
+impl<K, V> Iterator<(K, V)> for TreeMapConsumeIterator<K,V> {
+    #[inline]
+    fn next(&mut self) -> Option<(K, V)> {
+        while !self.stack.is_empty() {
+            let TreeNode {
+                key: key,
+                value: value,
+                left: left,
+                right: right,
+                level: level
+            } = self.stack.pop();
+
+            match left {
+                Some(~left) => {
+                    let n = TreeNode {
+                        key: key,
+                        value: value,
+                        left: None,
+                        right: right,
+                        level: level
+                    };
+                    self.stack.push(n);
+                    self.stack.push(left);
+                }
+                None => {
+                    match right {
+                        Some(~right) => self.stack.push(right),
+                        None => ()
+                    }
+                    self.remaining -= 1;
+                    return Some((key, value))
+                }
+            }
+        }
+        None
+    }
+
+    #[inline]
+    fn size_hint(&self) -> (uint, Option<uint>) {
+        (self.remaining, Some(self.remaining))
+    }
+
+}
+
 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]