提交 310e0b6e 编写于 作者: B blake2-ppc

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
上级 dbcb74e2
......@@ -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 @@ pub fn each_storage(&mut self, op: &fn(v: &mut uint) -> bool) -> bool {
}
#[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 @@ fn eq(&self, other: &BitvSet) -> bool {
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 @@ fn len(&self) -> uint { self.size }
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 @@ fn contains(&self, value: &uint) -> bool {
}
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 @@ fn is_subset(&self, other: &BitvSet) -> bool {
/* 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 @@ fn is_superset(&self, other: &BitvSet) -> bool {
}
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 @@ fn each_common(&self, other: &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)
}
}
foreach (i, &w) in other.bitv.storage.slice(min, len2).iter().enumerate() {
if !f(false, (i + min) * uint::bits, w) {
return false;
} 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)
}
}
return true;
}
}
/// 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
}
}
#[inline]
fn size_hint(&self) -> (uint, Option<uint>) {
self.iter.size_hint()
}
}
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册