@@ -66,7 +66,7 @@ use core::prelude::*;
66
66
use core:: cmp;
67
67
use core:: default:: Default ;
68
68
use core:: fmt;
69
- use core:: iter:: Take ;
69
+ use core:: iter:: { Chain , Enumerate , Repeat , Skip , Take } ;
70
70
use core:: iter;
71
71
use core:: slice;
72
72
use core:: uint;
@@ -75,25 +75,22 @@ use std::hash;
75
75
use { Mutable , Set , MutableSet , MutableSeq } ;
76
76
use vec:: Vec ;
77
77
78
+ type MatchWords < ' a > = Chain < MaskWords < ' a > , Skip < Take < Enumerate < Repeat < uint > > > > > ;
78
79
// Take two BitV's, and return iterators of their words, where the shorter one
79
80
// 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
- )
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 ( 0 u) . enumerate ( ) . take ( b_len) . skip ( a_len) ) ,
88
+ b. mask_words ( 0 ) . chain ( Repeat :: new ( 0 u) . enumerate ( ) . take ( 0 ) . skip ( 0 ) ) )
89
+ } else {
90
+ ( a. mask_words ( 0 ) . chain ( Repeat :: new ( 0 u) . enumerate ( ) . take ( 0 ) . skip ( 0 ) ) ,
91
+ b. mask_words ( 0 ) . chain ( Repeat :: new ( 0 u) . enumerate ( ) . take ( a_len) . skip ( b_len) ) )
92
+ }
93
+ }
97
94
98
95
static TRUE : bool = true ;
99
96
static FALSE : bool = false ;
@@ -1014,23 +1011,23 @@ impl Extendable<bool> for BitvSet {
1014
1011
impl PartialOrd for BitvSet {
1015
1012
#[ inline]
1016
1013
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 ( ) ) ;
1018
1015
iter:: order:: partial_cmp ( a_iter, b_iter)
1019
1016
}
1020
1017
}
1021
1018
1022
1019
impl Ord for BitvSet {
1023
1020
#[ inline]
1024
1021
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 ( ) ) ;
1026
1023
iter:: order:: cmp ( a_iter, b_iter)
1027
1024
}
1028
1025
}
1029
1026
1030
1027
impl cmp:: PartialEq for BitvSet {
1031
1028
#[ inline]
1032
1029
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 ( ) ) ;
1034
1031
iter:: order:: eq ( a_iter, b_iter)
1035
1032
}
1036
1033
}
@@ -1191,10 +1188,10 @@ impl BitvSet {
1191
1188
self_bitv. reserve ( other_bitv. capacity ( ) ) ;
1192
1189
1193
1190
// 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 ) ) ;
1191
+ let mut other_words = {
1192
+ let ( _ , result ) = match_words ( self_bitv , other_bitv) ;
1193
+ result
1194
+ } ;
1198
1195
1199
1196
// Apply values found in other
1200
1197
for ( i, w) in other_words {
@@ -1524,7 +1521,7 @@ impl Set<uint> for BitvSet {
1524
1521
1525
1522
#[ inline]
1526
1523
fn is_disjoint ( & self , other : & BitvSet ) -> bool {
1527
- self . intersection ( other) . count ( ) > 0
1524
+ self . intersection ( other) . next ( ) . is_none ( )
1528
1525
}
1529
1526
1530
1527
#[ inline]
@@ -2266,6 +2263,24 @@ mod tests {
2266
2263
assert ! ( set1. is_subset( & set2) ) ; // { 2 } { 2, 4 }
2267
2264
}
2268
2265
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
+
2269
2284
#[ test]
2270
2285
fn test_bitv_set_intersect_with ( ) {
2271
2286
// Explicitly 0'ed bits
0 commit comments