@@ -75,6 +75,25 @@ use std::hash;
75
75
use { Mutable , Set , MutableSet , MutableSeq } ;
76
76
use vec:: Vec ;
77
77
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( 0 u) . enumerate( ) . take( b_len) . skip( a_len) ) ,
90
+ b. mask_words( 0 ) . chain( iter:: Repeat :: new( 0 u) . enumerate( ) . take( 0 ) . skip( 0 ) ) )
91
+ } else {
92
+ ( a. mask_words( 0 ) . chain( iter:: Repeat :: new( 0 u) . enumerate( ) . take( 0 ) . skip( 0 ) ) ,
93
+ b. mask_words( 0 ) . chain( iter:: Repeat :: new( 0 u) . enumerate( ) . take( a_len) . skip( b_len) ) )
94
+ }
95
+ } )
96
+ )
78
97
79
98
static TRUE : bool = true ;
80
99
static FALSE : bool = false ;
@@ -969,7 +988,7 @@ impl<'a> RandomAccessIterator<bool> for Bits<'a> {
969
988
/// assert!(bv.eq_vec([true, true, false, true,
970
989
/// false, false, false, false]));
971
990
/// ```
972
- #[ deriving( Clone , PartialEq , Eq , PartialOrd , Ord ) ]
991
+ #[ deriving( Clone ) ]
973
992
pub struct BitvSet ( Bitv ) ;
974
993
975
994
impl Default for BitvSet {
@@ -992,6 +1011,32 @@ impl Extendable<bool> for BitvSet {
992
1011
}
993
1012
}
994
1013
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
+
995
1040
impl BitvSet {
996
1041
/// Create a new bit vector set with initially no contents.
997
1042
///
@@ -1141,10 +1186,18 @@ impl BitvSet {
1141
1186
// Unwrap Bitvs
1142
1187
let & BitvSet ( ref mut self_bitv) = self ;
1143
1188
let & BitvSet ( ref other_bitv) = other;
1189
+
1144
1190
// Expand the vector if necessary
1145
1191
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 ( 0 u) . enumerate ( ) . take ( self_len) . skip ( other_len) ) ;
1198
+
1199
+ // Apply values found in other
1200
+ for ( i, w) in other_words {
1148
1201
let old = self_bitv. storage [ i] ;
1149
1202
let new = f ( old, w) ;
1150
1203
* self_bitv. storage . get_mut ( i) = new;
@@ -2213,6 +2266,64 @@ mod tests {
2213
2266
assert ! ( set1. is_subset( & set2) ) ; // { 2 } { 2, 4 }
2214
2267
}
2215
2268
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
+
2216
2327
#[ test]
2217
2328
fn test_bitv_remove ( ) {
2218
2329
let mut a = BitvSet :: new ( ) ;
0 commit comments