extra: Use external iterators in bitv implementation
Convert some internally used functions to use a external iterators. Change all uses of remaining internal iterators to use `do` expr
This commit is contained in:
parent
dbcb74e247
commit
310e0b6e92
@ -12,7 +12,8 @@
|
||||
|
||||
|
||||
use std::cmp;
|
||||
use std::iterator::{DoubleEndedIterator, RandomAccessIterator, Invert};
|
||||
use std::iterator::RandomAccessIterator;
|
||||
use std::iterator::{Invert, Enumerate};
|
||||
use std::num;
|
||||
use std::ops;
|
||||
use std::uint;
|
||||
@ -164,7 +165,7 @@ impl BigBitv {
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn negate(&mut self) { for self.each_storage |w| { *w = !*w } }
|
||||
pub fn negate(&mut self) { do self.each_storage |w| { *w = !*w; true }; }
|
||||
|
||||
#[inline]
|
||||
pub fn union(&mut self, b: &BigBitv, nbits: uint) -> bool {
|
||||
@ -723,12 +724,12 @@ impl cmp::Eq for BitvSet {
|
||||
if self.size != other.size {
|
||||
return false;
|
||||
}
|
||||
for self.each_common(other) |_, w1, w2| {
|
||||
for self.common_iter(other).advance |(_, w1, w2)| {
|
||||
if w1 != w2 {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
for self.each_outlier(other) |_, _, w| {
|
||||
for self.outlier_iter(other).advance |(_, _, w)| {
|
||||
if w != 0 {
|
||||
return false;
|
||||
}
|
||||
@ -746,7 +747,7 @@ impl Container for BitvSet {
|
||||
|
||||
impl Mutable for BitvSet {
|
||||
fn clear(&mut self) {
|
||||
for self.bitv.each_storage |w| { *w = 0; }
|
||||
do self.bitv.each_storage |w| { *w = 0; true };
|
||||
self.size = 0;
|
||||
}
|
||||
}
|
||||
@ -757,14 +758,13 @@ impl Set<uint> for BitvSet {
|
||||
}
|
||||
|
||||
fn is_disjoint(&self, other: &BitvSet) -> bool {
|
||||
for self.intersection(other) |_| {
|
||||
return false;
|
||||
do self.intersection(other) |_| {
|
||||
false
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
fn is_subset(&self, other: &BitvSet) -> bool {
|
||||
for self.each_common(other) |_, w1, w2| {
|
||||
for self.common_iter(other).advance |(_, w1, w2)| {
|
||||
if w1 & w2 != w1 {
|
||||
return false;
|
||||
}
|
||||
@ -772,7 +772,7 @@ impl Set<uint> for BitvSet {
|
||||
/* If anything is not ours, then everything is not ours so we're
|
||||
definitely a subset in that case. Otherwise if there's any stray
|
||||
ones that 'other' doesn't have, we're not a subset. */
|
||||
for self.each_outlier(other) |mine, _, w| {
|
||||
for self.outlier_iter(other).advance |(mine, _, w)| {
|
||||
if !mine {
|
||||
return true;
|
||||
} else if w != 0 {
|
||||
@ -787,38 +787,38 @@ impl Set<uint> for BitvSet {
|
||||
}
|
||||
|
||||
fn difference(&self, other: &BitvSet, f: &fn(&uint) -> bool) -> bool {
|
||||
for self.each_common(other) |i, w1, w2| {
|
||||
for self.common_iter(other).advance |(i, w1, w2)| {
|
||||
if !iterate_bits(i, w1 & !w2, |b| f(&b)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
/* everything we have that they don't also shows up */
|
||||
self.each_outlier(other, |mine, i, w|
|
||||
self.outlier_iter(other).advance(|(mine, i, w)|
|
||||
!mine || iterate_bits(i, w, |b| f(&b))
|
||||
)
|
||||
}
|
||||
|
||||
fn symmetric_difference(&self, other: &BitvSet,
|
||||
f: &fn(&uint) -> bool) -> bool {
|
||||
for self.each_common(other) |i, w1, w2| {
|
||||
for self.common_iter(other).advance |(i, w1, w2)| {
|
||||
if !iterate_bits(i, w1 ^ w2, |b| f(&b)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
self.each_outlier(other, |_, i, w| iterate_bits(i, w, |b| f(&b)))
|
||||
self.outlier_iter(other).advance(|(_, i, w)| iterate_bits(i, w, |b| f(&b)))
|
||||
}
|
||||
|
||||
fn intersection(&self, other: &BitvSet, f: &fn(&uint) -> bool) -> bool {
|
||||
self.each_common(other, |i, w1, w2| iterate_bits(i, w1 & w2, |b| f(&b)))
|
||||
self.common_iter(other).advance(|(i, w1, w2)| iterate_bits(i, w1 & w2, |b| f(&b)))
|
||||
}
|
||||
|
||||
fn union(&self, other: &BitvSet, f: &fn(&uint) -> bool) -> bool {
|
||||
for self.each_common(other) |i, w1, w2| {
|
||||
for self.common_iter(other).advance |(i, w1, w2)| {
|
||||
if !iterate_bits(i, w1 | w2, |b| f(&b)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
self.each_outlier(other, |_, i, w| iterate_bits(i, w, |b| f(&b)))
|
||||
self.outlier_iter(other).advance(|(_, i, w)| iterate_bits(i, w, |b| f(&b)))
|
||||
}
|
||||
}
|
||||
|
||||
@ -861,13 +861,14 @@ impl BitvSet {
|
||||
/// both have in common. The three yielded arguments are (bit location,
|
||||
/// w1, w2) where the bit location is the number of bits offset so far,
|
||||
/// and w1/w2 are the words coming from the two vectors self, other.
|
||||
fn each_common(&self, other: &BitvSet,
|
||||
f: &fn(uint, uint, uint) -> bool) -> bool {
|
||||
fn common_iter<'a>(&'a self, other: &'a BitvSet)
|
||||
-> MapE<(uint,&uint),(uint,uint,uint), &'a ~[uint],Enumerate<vec::VecIterator<'a,uint>>> {
|
||||
let min = num::min(self.bitv.storage.len(),
|
||||
other.bitv.storage.len());
|
||||
self.bitv.storage.slice(0, min).iter().enumerate().advance(|(i, &w)| {
|
||||
f(i * uint::bits, w, other.bitv.storage[i])
|
||||
})
|
||||
MapE{iter: self.bitv.storage.slice(0, min).iter().enumerate(),
|
||||
env: &other.bitv.storage,
|
||||
f: |(i, &w): (uint, &uint), o_store| (i * uint::bits, w, o_store[i])
|
||||
}
|
||||
}
|
||||
|
||||
/// Visits each word in self or other that extends beyond the other. This
|
||||
@ -877,24 +878,45 @@ impl BitvSet {
|
||||
/// The yielded arguments are a bool, the bit offset, and a word. The bool
|
||||
/// is true if the word comes from 'self', and false if it comes from
|
||||
/// 'other'.
|
||||
fn each_outlier(&self, other: &BitvSet,
|
||||
f: &fn(bool, uint, uint) -> bool) -> bool {
|
||||
fn outlier_iter<'a>(&'a self, other: &'a BitvSet)
|
||||
-> MapE<(uint, &uint),(bool, uint, uint), uint, Enumerate<vec::VecIterator<'a, uint>>> {
|
||||
let len1 = self.bitv.storage.len();
|
||||
let len2 = other.bitv.storage.len();
|
||||
let min = num::min(len1, len2);
|
||||
|
||||
/* only one of these loops will execute and that's the point */
|
||||
foreach (i, &w) in self.bitv.storage.slice(min, len1).iter().enumerate() {
|
||||
if !f(true, (i + min) * uint::bits, w) {
|
||||
return false;
|
||||
if min < len1 {
|
||||
MapE{iter: self.bitv.storage.slice(min, len1).iter().enumerate(),
|
||||
env: min,
|
||||
f: |(i, &w): (uint, &uint), min| (true, (i + min) * uint::bits, w)
|
||||
}
|
||||
} else {
|
||||
MapE{iter: other.bitv.storage.slice(min, len2).iter().enumerate(),
|
||||
env: min,
|
||||
f: |(i, &w): (uint, &uint), min| (false, (i + min) * uint::bits, w)
|
||||
}
|
||||
}
|
||||
foreach (i, &w) in other.bitv.storage.slice(min, len2).iter().enumerate() {
|
||||
if !f(false, (i + min) * uint::bits, w) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Like iterator::Map with explicit env capture
|
||||
struct MapE<A, B, Env, I> {
|
||||
priv env: Env,
|
||||
priv f: &'static fn(A, Env) -> B,
|
||||
priv iter: I,
|
||||
}
|
||||
|
||||
impl<'self, A, B, Env: Clone, I: Iterator<A>> Iterator<B> for MapE<A, B, Env, I> {
|
||||
#[inline]
|
||||
fn next(&mut self) -> Option<B> {
|
||||
match self.iter.next() {
|
||||
Some(elt) => Some((self.f)(elt, self.env.clone())),
|
||||
None => None
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn size_hint(&self) -> (uint, Option<uint>) {
|
||||
self.iter.size_hint()
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user