Skip to content

Commit 9af4e32

Browse files
committed
auto merge of #16582 : Gankro/rust/bitv, r=alexcrichton
This was bothering me (and some other people). The macro was necessary in a transient step of my development, but I converged on a design where it was unnecessary, but it didn't really click that that had happened. This fixes it up.
2 parents d16a5cd + dcccf82 commit 9af4e32

File tree

1 file changed

+41
-26
lines changed

1 file changed

+41
-26
lines changed

src/libcollections/bitv.rs

+41-26
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,7 @@ use core::prelude::*;
6666
use core::cmp;
6767
use core::default::Default;
6868
use core::fmt;
69-
use core::iter::Take;
69+
use core::iter::{Chain, Enumerate, Repeat, Skip, Take};
7070
use core::iter;
7171
use core::slice;
7272
use core::uint;
@@ -75,25 +75,22 @@ use std::hash;
7575
use {Mutable, Set, MutableSet, MutableSeq};
7676
use vec::Vec;
7777

78+
type MatchWords<'a> = Chain<MaskWords<'a>, Skip<Take<Enumerate<Repeat<uint>>>>>;
7879
// Take two BitV's, and return iterators of their words, where the shorter one
7980
// has been padded with 0's
80-
macro_rules! match_words(
81-
($a_expr:expr, $b_expr:expr) => ({
82-
let a = $a_expr;
83-
let b = $b_expr;
84-
let a_len = a.storage.len();
85-
let b_len = b.storage.len();
86-
87-
// have to uselessly pretend to pad the longer one for type matching
88-
if a_len < b_len {
89-
(a.mask_words(0).chain(iter::Repeat::new(0u).enumerate().take(b_len).skip(a_len)),
90-
b.mask_words(0).chain(iter::Repeat::new(0u).enumerate().take(0).skip(0)))
91-
} else {
92-
(a.mask_words(0).chain(iter::Repeat::new(0u).enumerate().take(0).skip(0)),
93-
b.mask_words(0).chain(iter::Repeat::new(0u).enumerate().take(a_len).skip(b_len)))
94-
}
95-
})
96-
)
81+
fn match_words <'a,'b>(a: &'a Bitv, b: &'b Bitv) -> (MatchWords<'a>, MatchWords<'b>) {
82+
let a_len = a.storage.len();
83+
let b_len = b.storage.len();
84+
85+
// have to uselessly pretend to pad the longer one for type matching
86+
if a_len < b_len {
87+
(a.mask_words(0).chain(Repeat::new(0u).enumerate().take(b_len).skip(a_len)),
88+
b.mask_words(0).chain(Repeat::new(0u).enumerate().take(0).skip(0)))
89+
} else {
90+
(a.mask_words(0).chain(Repeat::new(0u).enumerate().take(0).skip(0)),
91+
b.mask_words(0).chain(Repeat::new(0u).enumerate().take(a_len).skip(b_len)))
92+
}
93+
}
9794

9895
static TRUE: bool = true;
9996
static FALSE: bool = false;
@@ -1014,23 +1011,23 @@ impl Extendable<bool> for BitvSet {
10141011
impl PartialOrd for BitvSet {
10151012
#[inline]
10161013
fn partial_cmp(&self, other: &BitvSet) -> Option<Ordering> {
1017-
let (a_iter, b_iter) = match_words!(self.get_ref(), other.get_ref());
1014+
let (a_iter, b_iter) = match_words(self.get_ref(), other.get_ref());
10181015
iter::order::partial_cmp(a_iter, b_iter)
10191016
}
10201017
}
10211018

10221019
impl Ord for BitvSet {
10231020
#[inline]
10241021
fn cmp(&self, other: &BitvSet) -> Ordering {
1025-
let (a_iter, b_iter) = match_words!(self.get_ref(), other.get_ref());
1022+
let (a_iter, b_iter) = match_words(self.get_ref(), other.get_ref());
10261023
iter::order::cmp(a_iter, b_iter)
10271024
}
10281025
}
10291026

10301027
impl cmp::PartialEq for BitvSet {
10311028
#[inline]
10321029
fn eq(&self, other: &BitvSet) -> bool {
1033-
let (a_iter, b_iter) = match_words!(self.get_ref(), other.get_ref());
1030+
let (a_iter, b_iter) = match_words(self.get_ref(), other.get_ref());
10341031
iter::order::eq(a_iter, b_iter)
10351032
}
10361033
}
@@ -1191,10 +1188,10 @@ impl BitvSet {
11911188
self_bitv.reserve(other_bitv.capacity());
11921189

11931190
// virtually pad other with 0's for equal lengths
1194-
let self_len = self_bitv.storage.len();
1195-
let other_len = other_bitv.storage.len();
1196-
let mut other_words = other_bitv.mask_words(0)
1197-
.chain(iter::Repeat::new(0u).enumerate().take(self_len).skip(other_len));
1191+
let mut other_words = {
1192+
let (_, result) = match_words(self_bitv, other_bitv);
1193+
result
1194+
};
11981195

11991196
// Apply values found in other
12001197
for (i, w) in other_words {
@@ -1524,7 +1521,7 @@ impl Set<uint> for BitvSet {
15241521

15251522
#[inline]
15261523
fn is_disjoint(&self, other: &BitvSet) -> bool {
1527-
self.intersection(other).count() > 0
1524+
self.intersection(other).next().is_none()
15281525
}
15291526

15301527
#[inline]
@@ -2266,6 +2263,24 @@ mod tests {
22662263
assert!(set1.is_subset(&set2)); // { 2 } { 2, 4 }
22672264
}
22682265

2266+
#[test]
2267+
fn test_bitv_set_is_disjoint() {
2268+
let a = BitvSet::from_bitv(from_bytes([0b10100010]));
2269+
let b = BitvSet::from_bitv(from_bytes([0b01000000]));
2270+
let c = BitvSet::new();
2271+
let d = BitvSet::from_bitv(from_bytes([0b00110000]));
2272+
2273+
assert!(!a.is_disjoint(&d));
2274+
assert!(!d.is_disjoint(&a));
2275+
2276+
assert!(a.is_disjoint(&b))
2277+
assert!(a.is_disjoint(&c))
2278+
assert!(b.is_disjoint(&a))
2279+
assert!(b.is_disjoint(&c))
2280+
assert!(c.is_disjoint(&a))
2281+
assert!(c.is_disjoint(&b))
2282+
}
2283+
22692284
#[test]
22702285
fn test_bitv_set_intersect_with() {
22712286
// Explicitly 0'ed bits

0 commit comments

Comments
 (0)