@@ -75,6 +75,25 @@ use std::hash;
7575use { Mutable , Set , MutableSet , MutableSeq } ;
7676use 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( 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+ )
7897
7998static TRUE : bool = true ;
8099static 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 ) ]
973992pub struct BitvSet ( Bitv ) ;
974993
975994impl 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+
9951040impl 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 ( 0 u) . 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