Skip to content

Commit 5f208b8

Browse files
committed
Switched bitv to external iterators
1 parent c325cb0 commit 5f208b8

File tree

1 file changed

+54
-17
lines changed

1 file changed

+54
-17
lines changed

src/libextra/bitv.rs

Lines changed: 54 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -392,28 +392,23 @@ impl Bitv {
392392
match self.rep {
393393
Small(ref b) => b.is_true(self.nbits),
394394
_ => {
395-
for self.each() |i| { if !i { return false; } }
395+
for self.iter().advance |i| { if !i { return false; } }
396396
true
397397
}
398398
}
399399
}
400400

401401
#[inline]
402-
pub fn each(&self, f: &fn(bool) -> bool) -> bool {
403-
let mut i = 0;
404-
while i < self.nbits {
405-
if !f(self.get(i)) { return false; }
406-
i += 1;
407-
}
408-
return true;
402+
pub fn iter<'a>(&'a self) -> BitvIterator<'a> {
403+
BitvIterator {bitv: self, next_idx: 0}
409404
}
410405

411406
/// Returns true if all bits are 0
412407
pub fn is_false(&self) -> bool {
413408
match self.rep {
414409
Small(ref b) => b.is_false(self.nbits),
415410
Big(_) => {
416-
for self.each() |i| { if i { return false; } }
411+
for self.iter().advance |i| { if i { return false; } }
417412
true
418413
}
419414
}
@@ -477,7 +472,7 @@ impl Bitv {
477472
*/
478473
pub fn to_str(&self) -> ~str {
479474
let mut rs = ~"";
480-
for self.each() |i| {
475+
for self.iter().advance |i| {
481476
if i {
482477
rs.push_char('1');
483478
} else {
@@ -580,6 +575,29 @@ fn iterate_bits(base: uint, bits: uint, f: &fn(uint) -> bool) -> bool {
580575
return true;
581576
}
582577

578+
/// An iterator for Bitv
579+
pub struct BitvIterator<'self> {
580+
priv bitv: &'self Bitv,
581+
priv next_idx: uint
582+
}
583+
584+
impl<'self> Iterator<bool> for BitvIterator<'self> {
585+
fn next(&mut self) -> Option<bool> {
586+
if self.next_idx < self.bitv.nbits {
587+
let idx = self.next_idx;
588+
self.next_idx += 1;
589+
Some(self.bitv.get(idx))
590+
} else {
591+
None
592+
}
593+
}
594+
595+
fn size_hint(&self) -> (uint, Option<uint>) {
596+
let rem = self.bitv.nbits - self.next_idx;
597+
(rem, Some(rem))
598+
}
599+
}
600+
583601
/// An implementation of a set using a bit vector as an underlying
584602
/// representation for holding numerical elements.
585603
///
@@ -670,13 +688,8 @@ impl BitvSet {
670688
self.other_op(other, |w1, w2| w1 ^ w2);
671689
}
672690

673-
pub fn each(&self, blk: &fn(v: &uint) -> bool) -> bool {
674-
for self.bitv.storage.iter().enumerate().advance |(i, &w)| {
675-
if !iterate_bits(i * uint::bits, w, |b| blk(&b)) {
676-
return false;
677-
}
678-
}
679-
return true;
691+
pub fn iter<'a>(&'a self) -> BitvSetIterator<'a> {
692+
BitvSetIterator {set: self, next_idx: 0}
680693
}
681694
}
682695

@@ -860,6 +873,30 @@ impl BitvSet {
860873
}
861874
}
862875

876+
pub struct BitvSetIterator<'self> {
877+
priv set: &'self BitvSet,
878+
priv next_idx: uint
879+
}
880+
881+
impl<'self> Iterator<uint> for BitvSetIterator<'self> {
882+
fn next(&mut self) -> Option<uint> {
883+
while self.next_idx < self.set.capacity() {
884+
let idx = self.next_idx;
885+
self.next_idx += 1;
886+
887+
if self.set.contains(&idx) {
888+
return Some(idx);
889+
}
890+
}
891+
892+
return None;
893+
}
894+
895+
fn size_hint(&self) -> (uint, Option<uint>) {
896+
(0, Some(self.set.capacity() - self.next_idx))
897+
}
898+
}
899+
863900
#[cfg(test)]
864901
mod tests {
865902
use extra::test::BenchHarness;

0 commit comments

Comments
 (0)