]> git.lizzy.rs Git - rust.git/commitdiff
Switched bitv to external iterators
authorSteven Fackler <sfackler@gmail.com>
Wed, 10 Jul 2013 05:06:38 +0000 (01:06 -0400)
committerSteven Fackler <sfackler@gmail.com>
Sun, 21 Jul 2013 07:22:21 +0000 (03:22 -0400)
src/libextra/bitv.rs

index 33a50f4e9ab1405e5b2a19f380e05d5a38cba524..8ec72f3da3463a100607b58cb6d8b9a4673e60bc 100644 (file)
@@ -392,20 +392,15 @@ pub fn is_true(&self) -> bool {
       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 @@ pub fn is_false(&self) -> bool {
       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 @@ pub fn to_bools(&self) -> ~[bool] {
      */
      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 @@ pub fn symmetric_difference_with(&mut self, other: &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 @@ fn each_outlier(&self, other: &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;