Skip to content

Commit 01ec6fa

Browse files
committed
auto merge of #16559 : Gankro/rust/bitv, r=pcwalton
These were the only differing-size-based errors I noticed. Might be more.
2 parents 0d8738f + 8c9bdda commit 01ec6fa

File tree

1 file changed

+114
-3
lines changed

1 file changed

+114
-3
lines changed

src/libcollections/bitv.rs

+114-3
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,25 @@ use std::hash;
7575
use {Mutable, Set, MutableSet, MutableSeq};
7676
use vec::Vec;
7777

78+
// Take two BitV's, and return iterators of their words, where the shorter one
79+
// 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+
)
7897

7998
static TRUE: bool = true;
8099
static FALSE: bool = false;
@@ -969,7 +988,7 @@ impl<'a> RandomAccessIterator<bool> for Bits<'a> {
969988
/// assert!(bv.eq_vec([true, true, false, true,
970989
/// false, false, false, false]));
971990
/// ```
972-
#[deriving(Clone, PartialEq, Eq, PartialOrd, Ord)]
991+
#[deriving(Clone)]
973992
pub struct BitvSet(Bitv);
974993

975994
impl Default for BitvSet {
@@ -992,6 +1011,32 @@ impl Extendable<bool> for BitvSet {
9921011
}
9931012
}
9941013

1014+
impl PartialOrd for BitvSet {
1015+
#[inline]
1016+
fn partial_cmp(&self, other: &BitvSet) -> Option<Ordering> {
1017+
let (a_iter, b_iter) = match_words!(self.get_ref(), other.get_ref());
1018+
iter::order::partial_cmp(a_iter, b_iter)
1019+
}
1020+
}
1021+
1022+
impl Ord for BitvSet {
1023+
#[inline]
1024+
fn cmp(&self, other: &BitvSet) -> Ordering {
1025+
let (a_iter, b_iter) = match_words!(self.get_ref(), other.get_ref());
1026+
iter::order::cmp(a_iter, b_iter)
1027+
}
1028+
}
1029+
1030+
impl cmp::PartialEq for BitvSet {
1031+
#[inline]
1032+
fn eq(&self, other: &BitvSet) -> bool {
1033+
let (a_iter, b_iter) = match_words!(self.get_ref(), other.get_ref());
1034+
iter::order::eq(a_iter, b_iter)
1035+
}
1036+
}
1037+
1038+
impl cmp::Eq for BitvSet {}
1039+
9951040
impl BitvSet {
9961041
/// Create a new bit vector set with initially no contents.
9971042
///
@@ -1141,10 +1186,18 @@ impl BitvSet {
11411186
// Unwrap Bitvs
11421187
let &BitvSet(ref mut self_bitv) = self;
11431188
let &BitvSet(ref other_bitv) = other;
1189+
11441190
// Expand the vector if necessary
11451191
self_bitv.reserve(other_bitv.capacity());
1146-
// Apply values
1147-
for (i, w) in other_bitv.mask_words(0) {
1192+
1193+
// 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));
1198+
1199+
// Apply values found in other
1200+
for (i, w) in other_words {
11481201
let old = self_bitv.storage[i];
11491202
let new = f(old, w);
11501203
*self_bitv.storage.get_mut(i) = new;
@@ -2213,6 +2266,64 @@ mod tests {
22132266
assert!(set1.is_subset(&set2)); // { 2 } { 2, 4 }
22142267
}
22152268

2269+
#[test]
2270+
fn test_bitv_set_intersect_with() {
2271+
// Explicitly 0'ed bits
2272+
let mut a = BitvSet::from_bitv(from_bytes([0b10100010]));
2273+
let mut b = BitvSet::from_bitv(from_bytes([0b00000000]));
2274+
let c = a.clone();
2275+
a.intersect_with(&b);
2276+
b.intersect_with(&c);
2277+
assert!(a.is_empty());
2278+
assert!(b.is_empty());
2279+
2280+
// Uninitialized bits should behave like 0's
2281+
let mut a = BitvSet::from_bitv(from_bytes([0b10100010]));
2282+
let mut b = BitvSet::new();
2283+
let c = a.clone();
2284+
a.intersect_with(&b);
2285+
b.intersect_with(&c);
2286+
assert!(a.is_empty());
2287+
assert!(b.is_empty());
2288+
2289+
// Standard
2290+
let mut a = BitvSet::from_bitv(from_bytes([0b10100010]));
2291+
let mut b = BitvSet::from_bitv(from_bytes([0b01100010]));
2292+
let c = a.clone();
2293+
a.intersect_with(&b);
2294+
b.intersect_with(&c);
2295+
assert_eq!(a.len(), 2);
2296+
assert_eq!(b.len(), 2);
2297+
}
2298+
2299+
#[test]
2300+
fn test_bitv_set_eq() {
2301+
let a = BitvSet::from_bitv(from_bytes([0b10100010]));
2302+
let b = BitvSet::from_bitv(from_bytes([0b00000000]));
2303+
let c = BitvSet::new();
2304+
2305+
assert!(a == a);
2306+
assert!(a != b);
2307+
assert!(a != c);
2308+
assert!(b == b);
2309+
assert!(b == c);
2310+
assert!(c == c);
2311+
}
2312+
2313+
#[test]
2314+
fn test_bitv_set_cmp() {
2315+
let a = BitvSet::from_bitv(from_bytes([0b10100010]));
2316+
let b = BitvSet::from_bitv(from_bytes([0b00000000]));
2317+
let c = BitvSet::new();
2318+
2319+
assert_eq!(a.cmp(&b), Greater);
2320+
assert_eq!(a.cmp(&c), Greater);
2321+
assert_eq!(b.cmp(&a), Less);
2322+
assert_eq!(b.cmp(&c), Equal);
2323+
assert_eq!(c.cmp(&a), Less);
2324+
assert_eq!(c.cmp(&b), Equal);
2325+
}
2326+
22162327
#[test]
22172328
fn test_bitv_remove() {
22182329
let mut a = BitvSet::new();

0 commit comments

Comments
 (0)