@@ -76,6 +76,25 @@ use std::hash;
76
76
use { Collection , Mutable , Set , MutableSet , MutableSeq } ;
77
77
use vec:: Vec ;
78
78
79
+ // Take two BitV's, and return iterators of their words, where the shorter one
80
+ // has been padded with 0's
81
+ macro_rules! match_words(
82
+ ( $a_expr: expr, $b_expr: expr) => ( {
83
+ let a = $a_expr;
84
+ let b = $b_expr;
85
+ let a_len = a. storage. len( ) ;
86
+ let b_len = b. storage. len( ) ;
87
+
88
+ // have to uselessly pretend to pad the longer one for type matching
89
+ if a_len < b_len {
90
+ ( a. mask_words( 0 ) . chain( iter:: Repeat :: new( 0 u) . enumerate( ) . take( b_len) . skip( a_len) ) ,
91
+ b. mask_words( 0 ) . chain( iter:: Repeat :: new( 0 u) . enumerate( ) . take( 0 ) . skip( 0 ) ) )
92
+ } else {
93
+ ( a. mask_words( 0 ) . chain( iter:: Repeat :: new( 0 u) . enumerate( ) . take( 0 ) . skip( 0 ) ) ,
94
+ b. mask_words( 0 ) . chain( iter:: Repeat :: new( 0 u) . enumerate( ) . take( a_len) . skip( b_len) ) )
95
+ }
96
+ } )
97
+ )
79
98
80
99
static TRUE : bool = true ;
81
100
static FALSE : bool = false ;
@@ -970,7 +989,7 @@ impl<'a> RandomAccessIterator<bool> for Bits<'a> {
970
989
/// assert!(bv.eq_vec([true, true, false, true,
971
990
/// false, false, false, false]));
972
991
/// ```
973
- #[ deriving( Clone , PartialEq , Eq , PartialOrd , Ord ) ]
992
+ #[ deriving( Clone ) ]
974
993
pub struct BitvSet ( Bitv ) ;
975
994
976
995
impl Default for BitvSet {
@@ -993,6 +1012,32 @@ impl Extendable<bool> for BitvSet {
993
1012
}
994
1013
}
995
1014
1015
+ impl PartialOrd for BitvSet {
1016
+ #[ inline]
1017
+ fn partial_cmp ( & self , other : & BitvSet ) -> Option < Ordering > {
1018
+ let ( a_iter, b_iter) = match_words ! ( self . get_ref( ) , other. get_ref( ) ) ;
1019
+ iter:: order:: partial_cmp ( a_iter, b_iter)
1020
+ }
1021
+ }
1022
+
1023
+ impl Ord for BitvSet {
1024
+ #[ inline]
1025
+ fn cmp ( & self , other : & BitvSet ) -> Ordering {
1026
+ let ( a_iter, b_iter) = match_words ! ( self . get_ref( ) , other. get_ref( ) ) ;
1027
+ iter:: order:: cmp ( a_iter, b_iter)
1028
+ }
1029
+ }
1030
+
1031
+ impl cmp:: PartialEq for BitvSet {
1032
+ #[ inline]
1033
+ fn eq ( & self , other : & BitvSet ) -> bool {
1034
+ let ( a_iter, b_iter) = match_words ! ( self . get_ref( ) , other. get_ref( ) ) ;
1035
+ iter:: order:: eq ( a_iter, b_iter)
1036
+ }
1037
+ }
1038
+
1039
+ impl cmp:: Eq for BitvSet { }
1040
+
996
1041
impl BitvSet {
997
1042
/// Create a new bit vector set with initially no contents.
998
1043
///
@@ -1142,10 +1187,18 @@ impl BitvSet {
1142
1187
// Unwrap Bitvs
1143
1188
let & BitvSet ( ref mut self_bitv) = self ;
1144
1189
let & BitvSet ( ref other_bitv) = other;
1190
+
1145
1191
// Expand the vector if necessary
1146
1192
self_bitv. reserve ( other_bitv. capacity ( ) ) ;
1147
- // Apply values
1148
- for ( i, w) in other_bitv. mask_words ( 0 ) {
1193
+
1194
+ // virtually pad other with 0's for equal lengths
1195
+ let self_len = self_bitv. storage . len ( ) ;
1196
+ let other_len = other_bitv. storage . len ( ) ;
1197
+ let mut other_words = other_bitv. mask_words ( 0 )
1198
+ . chain ( iter:: Repeat :: new ( 0 u) . enumerate ( ) . take ( self_len) . skip ( other_len) ) ;
1199
+
1200
+ // Apply values found in other
1201
+ for ( i, w) in other_words {
1149
1202
let old = self_bitv. storage [ i] ;
1150
1203
let new = f ( old, w) ;
1151
1204
* self_bitv. storage . get_mut ( i) = new;
@@ -2214,6 +2267,64 @@ mod tests {
2214
2267
assert ! ( set1. is_subset( & set2) ) ; // { 2 } { 2, 4 }
2215
2268
}
2216
2269
2270
+ #[ test]
2271
+ fn test_bitv_set_intersect_with ( ) {
2272
+ // Explicitly 0'ed bits
2273
+ let mut a = BitvSet :: from_bitv ( from_bytes ( [ 0b10100010 ] ) ) ;
2274
+ let mut b = BitvSet :: from_bitv ( from_bytes ( [ 0b00000000 ] ) ) ;
2275
+ let c = a. clone ( ) ;
2276
+ a. intersect_with ( & b) ;
2277
+ b. intersect_with ( & c) ;
2278
+ assert ! ( a. is_empty( ) ) ;
2279
+ assert ! ( b. is_empty( ) ) ;
2280
+
2281
+ // Uninitialized bits should behave like 0's
2282
+ let mut a = BitvSet :: from_bitv ( from_bytes ( [ 0b10100010 ] ) ) ;
2283
+ let mut b = BitvSet :: new ( ) ;
2284
+ let c = a. clone ( ) ;
2285
+ a. intersect_with ( & b) ;
2286
+ b. intersect_with ( & c) ;
2287
+ assert ! ( a. is_empty( ) ) ;
2288
+ assert ! ( b. is_empty( ) ) ;
2289
+
2290
+ // Standard
2291
+ let mut a = BitvSet :: from_bitv ( from_bytes ( [ 0b10100010 ] ) ) ;
2292
+ let mut b = BitvSet :: from_bitv ( from_bytes ( [ 0b01100010 ] ) ) ;
2293
+ let c = a. clone ( ) ;
2294
+ a. intersect_with ( & b) ;
2295
+ b. intersect_with ( & c) ;
2296
+ assert_eq ! ( a. len( ) , 2 ) ;
2297
+ assert_eq ! ( b. len( ) , 2 ) ;
2298
+ }
2299
+
2300
+ #[ test]
2301
+ fn test_bitv_set_eq ( ) {
2302
+ let a = BitvSet :: from_bitv ( from_bytes ( [ 0b10100010 ] ) ) ;
2303
+ let b = BitvSet :: from_bitv ( from_bytes ( [ 0b00000000 ] ) ) ;
2304
+ let c = BitvSet :: new ( ) ;
2305
+
2306
+ assert ! ( a == a) ;
2307
+ assert ! ( a != b) ;
2308
+ assert ! ( a != c) ;
2309
+ assert ! ( b == b) ;
2310
+ assert ! ( b == c) ;
2311
+ assert ! ( c == c) ;
2312
+ }
2313
+
2314
+ #[ test]
2315
+ fn test_bitv_set_cmp ( ) {
2316
+ let a = BitvSet :: from_bitv ( from_bytes ( [ 0b10100010 ] ) ) ;
2317
+ let b = BitvSet :: from_bitv ( from_bytes ( [ 0b00000000 ] ) ) ;
2318
+ let c = BitvSet :: new ( ) ;
2319
+
2320
+ assert_eq ! ( a. cmp( & b) , Greater ) ;
2321
+ assert_eq ! ( a. cmp( & c) , Greater ) ;
2322
+ assert_eq ! ( b. cmp( & a) , Less ) ;
2323
+ assert_eq ! ( b. cmp( & c) , Equal ) ;
2324
+ assert_eq ! ( c. cmp( & a) , Less ) ;
2325
+ assert_eq ! ( c. cmp( & b) , Equal ) ;
2326
+ }
2327
+
2217
2328
#[ test]
2218
2329
fn test_bitv_remove ( ) {
2219
2330
let mut a = BitvSet :: new ( ) ;
0 commit comments