about summary refs log tree commit diff
diff options
context:
space:
mode:
authorSteven Fackler <sfackler@gmail.com>2013-07-10 01:06:38 -0400
committerSteven Fackler <sfackler@gmail.com>2013-07-21 03:22:21 -0400
commit5f208b82e9af1150030095377ea7ad5dda4021fb (patch)
tree0bd4d6ba6c323c4285d3b4a615fc72b8ec48bb1e
parentc325cb0a42c2b2c0b12eeb1ebf4cc22bca0fe994 (diff)
downloadrust-5f208b82e9af1150030095377ea7ad5dda4021fb.tar.gz
rust-5f208b82e9af1150030095377ea7ad5dda4021fb.zip
Switched bitv to external iterators
-rw-r--r--src/libextra/bitv.rs71
1 files changed, 54 insertions, 17 deletions
diff --git a/src/libextra/bitv.rs b/src/libextra/bitv.rs
index 33a50f4e9ab..8ec72f3da34 100644
--- a/src/libextra/bitv.rs
+++ b/src/libextra/bitv.rs
@@ -392,20 +392,15 @@ impl Bitv {
       match self.rep {
         Small(ref b) => b.is_true(self.nbits),
         _ => {
-          for self.each() |i| { if !i { return false; } }
+          for self.iter().advance |i| { if !i { return false; } }
           true
         }
       }
     }
 
     #[inline]
-    pub fn each(&self, f: &fn(bool) -> bool) -> bool {
-        let mut i = 0;
-        while i < self.nbits {
-            if !f(self.get(i)) { return false; }
-            i += 1;
-        }
-        return true;
+    pub fn iter<'a>(&'a self) -> BitvIterator<'a> {
+        BitvIterator {bitv: self, next_idx: 0}
     }
 
     /// Returns true if all bits are 0
@@ -413,7 +408,7 @@ impl Bitv {
       match self.rep {
         Small(ref b) => b.is_false(self.nbits),
         Big(_) => {
-          for self.each() |i| { if i { return false; } }
+          for self.iter().advance |i| { if i { return false; } }
           true
         }
       }
@@ -477,7 +472,7 @@ impl Bitv {
      */
      pub fn to_str(&self) -> ~str {
         let mut rs = ~"";
-        for self.each() |i| {
+        for self.iter().advance |i| {
             if i {
                 rs.push_char('1');
             } else {
@@ -580,6 +575,29 @@ fn iterate_bits(base: uint, bits: uint, f: &fn(uint) -> bool) -> bool {
     return true;
 }
 
+/// An iterator for Bitv
+pub struct BitvIterator<'self> {
+    priv bitv: &'self Bitv,
+    priv next_idx: uint
+}
+
+impl<'self> Iterator<bool> for BitvIterator<'self> {
+    fn next(&mut self) -> Option<bool> {
+        if self.next_idx < self.bitv.nbits {
+            let idx = self.next_idx;
+            self.next_idx += 1;
+            Some(self.bitv.get(idx))
+        } else {
+            None
+        }
+    }
+
+    fn size_hint(&self) -> (uint, Option<uint>) {
+        let rem = self.bitv.nbits - self.next_idx;
+        (rem, Some(rem))
+    }
+}
+
 /// An implementation of a set using a bit vector as an underlying
 /// representation for holding numerical elements.
 ///
@@ -670,13 +688,8 @@ impl BitvSet {
         self.other_op(other, |w1, w2| w1 ^ w2);
     }
 
-    pub fn each(&self, blk: &fn(v: &uint) -> bool) -> bool {
-        for self.bitv.storage.iter().enumerate().advance |(i, &w)| {
-            if !iterate_bits(i * uint::bits, w, |b| blk(&b)) {
-                return false;
-            }
-        }
-        return true;
+    pub fn iter<'a>(&'a self) -> BitvSetIterator<'a> {
+        BitvSetIterator {set: self, next_idx: 0}
     }
 }
 
@@ -860,6 +873,30 @@ impl BitvSet {
     }
 }
 
+pub struct BitvSetIterator<'self> {
+    priv set: &'self BitvSet,
+    priv next_idx: uint
+}
+
+impl<'self> Iterator<uint> for BitvSetIterator<'self> {
+    fn next(&mut self) -> Option<uint> {
+        while self.next_idx < self.set.capacity() {
+            let idx = self.next_idx;
+            self.next_idx += 1;
+
+            if self.set.contains(&idx) {
+                return Some(idx);
+            }
+        }
+
+        return None;
+    }
+
+    fn size_hint(&self) -> (uint, Option<uint>) {
+        (0, Some(self.set.capacity() - self.next_idx))
+    }
+}
+
 #[cfg(test)]
 mod tests {
     use extra::test::BenchHarness;