@@ -19,37 +19,42 @@ export to_str;
1919export eq_vec;
2020export methods;
2121
22+ /// a mask that has a 1 for each defined bit in a small_bitv, assuming n bits
23+ #[ inline( always) ]
24+ fn small_mask ( nbits : uint ) -> u32 {
25+ ( 1 << nbits) - 1
26+ }
27+
2228struct small_bitv {
29+ /// only the lowest nbits of this value are used. the rest is undefined.
2330 let mut bits : u32 ;
2431 new ( bits : u32 ) { self . bits = bits; }
2532 priv {
2633 #[ inline( always) ]
27- fn bits_op( right_bits : u32, f : fn ( u32, u32) -> u32) -> bool {
34+ fn bits_op( right_bits : u32, nbits : uint, f : fn ( u32, u32) -> u32)
35+ -> bool {
36+ let mask = small_mask ( nbits) ;
2837 let old_b: u32 = self . bits ;
2938 let new_b = f ( old_b, right_bits) ;
3039 self . bits = new_b;
31- old_b != new_b
40+ mask & old_b != mask & new_b
3241 }
3342 }
3443 #[ inline( always) ]
35- fn union ( s : & small_bitv ) -> bool {
36- self . bits_op ( s. bits , |u1, u2| { u1 | u2 } )
44+ fn union ( s : & small_bitv , nbits : uint ) -> bool {
45+ self . bits_op ( s. bits , nbits , |u1, u2| u1 | u2)
3746 }
3847 #[ inline( always) ]
39- fn intersect ( s : & small_bitv ) -> bool {
40- self . bits_op ( s. bits , |u1, u2| { u1 & u2 } )
48+ fn intersect ( s : & small_bitv , nbits : uint ) -> bool {
49+ self . bits_op ( s. bits , nbits , |u1, u2| u1 & u2)
4150 }
4251 #[ inline( always) ]
43- fn become ( s : & small_bitv ) -> bool {
44- let old = self . bits ;
45- self . bits = s. bits ;
46- old != self . bits
52+ fn become ( s : & small_bitv , nbits : uint ) -> bool {
53+ self . bits_op ( s. bits , nbits, |_u1, u2| u2)
4754 }
4855 #[ inline( always) ]
49- fn difference ( s : & small_bitv ) -> bool {
50- let old = self . bits ;
51- self . bits &= !s. bits ;
52- old != self . bits
56+ fn difference ( s : & small_bitv , nbits : uint ) -> bool {
57+ self . bits_op ( s. bits , nbits, |u1, u2| u1 ^ u2)
5358 }
5459 #[ inline( always) ]
5560 pure fn get ( i : uint ) -> bool {
@@ -61,42 +66,70 @@ struct small_bitv {
6166 self . bits |= 1 <<i;
6267 }
6368 else {
64- self . bits &= !( i as u32 ) ;
69+ self . bits &= !( 1 << i as u32 ) ;
6570 }
6671 }
6772 #[ inline( always) ]
68- fn equals ( b : & small_bitv ) -> bool { self . bits == b. bits }
73+ fn equals ( b : & small_bitv , nbits : uint ) -> bool {
74+ let mask = small_mask ( nbits) ;
75+ mask & self . bits == mask & b. bits
76+ }
6977 #[ inline( always) ]
7078 fn clear ( ) { self . bits = 0 ; }
7179 #[ inline( always) ]
7280 fn set_all ( ) { self . bits = !0 ; }
7381 #[ inline( always) ]
74- fn is_true ( ) -> bool { self . bits == !0 }
82+ fn is_true ( nbits : uint ) -> bool {
83+ small_mask ( nbits) & !self . bits == 0
84+ }
7585 #[ inline( always) ]
76- fn is_false ( ) -> bool { self . bits == 0 }
86+ fn is_false ( nbits : uint ) -> bool {
87+ small_mask ( nbits) & self . bits == 0
88+ }
7789 #[ inline( always) ]
7890 fn invert ( ) { self . bits = !self . bits ; }
7991}
8092
93+ /**
94+ * a mask that has a 1 for each defined bit in the nth element of a big_bitv,
95+ * assuming n bits.
96+ */
97+ #[ inline( always) ]
98+ fn big_mask ( nbits : uint , elem : uint ) -> uint {
99+ let rmd = nbits % uint_bits;
100+ let nelems = nbits/uint_bits + if rmd == 0 { 0 } else { 1 } ;
101+
102+ if elem < nelems - 1 || rmd == 0 {
103+ !0
104+ } else {
105+ ( 1 << rmd) - 1
106+ }
107+ }
108+
81109struct big_bitv {
82- // only mut b/c of clone and lack of other constructor
110+ // only mut b/c of clone and lack of other constructor
83111 let mut storage : ~[ mut uint ] ;
84112 new ( -storage: ~[ mut uint] ) {
85113 self . storage <- storage;
86114 }
87115 priv {
88116 #[ inline( always) ]
89- fn process( b: & big_bitv, op : fn ( uint, uint) -> uint) -> bool {
117+ fn process( b: & big_bitv, nbits : uint, op : fn ( uint, uint) -> uint)
118+ -> bool {
90119 let len = b. storage . len ( ) ;
91120 assert ( self . storage . len ( ) == len) ;
92121 let mut changed = false ;
93122 do uint:: range ( 0 , len) |i| {
94- let w0 = self . storage [ i] ;
95- let w1 = b. storage [ i] ;
96- let w = op ( w0, w1) ;
97- if w0 != w unchecked { changed = true ; self . storage [ i] = w; } ;
123+ let mask = big_mask ( nbits, i) ;
124+ let w0 = self . storage [ i] & mask;
125+ let w1 = b. storage [ i] & mask;
126+ let w = op ( w0, w1) & mask;
127+ if w0 != w unchecked {
128+ changed = true ;
129+ self . storage [ i] = w;
130+ }
98131 true
99- } ;
132+ }
100133 changed
101134 }
102135 }
@@ -112,15 +145,21 @@ struct big_bitv {
112145 #[ inline( always) ]
113146 fn invert ( ) { for self . each_storage( ) |w| { w = !w } }
114147 #[ inline( always) ]
115- fn union ( b : & big_bitv ) -> bool { self . process ( b, lor) }
148+ fn union ( b : & big_bitv , nbits : uint ) -> bool {
149+ self . process ( b, nbits, lor)
150+ }
116151 #[ inline( always) ]
117- fn intersect ( b : & big_bitv ) -> bool { self . process ( b, land) }
152+ fn intersect ( b : & big_bitv , nbits : uint ) -> bool {
153+ self . process ( b, nbits, land)
154+ }
118155 #[ inline( always) ]
119- fn become ( b : & big_bitv ) -> bool { self . process ( b, right) }
156+ fn become ( b : & big_bitv , nbits : uint ) -> bool {
157+ self . process ( b, nbits, right)
158+ }
120159 #[ inline( always) ]
121- fn difference ( b : & big_bitv ) -> bool {
160+ fn difference ( b : & big_bitv , nbits : uint ) -> bool {
122161 self . invert ( ) ;
123- let b = self . intersect ( b) ;
162+ let b = self . intersect ( b, nbits ) ;
124163 self . invert ( ) ;
125164 b
126165 }
@@ -140,10 +179,13 @@ struct big_bitv {
140179 else { self . storage [ w] & !flag } ;
141180 }
142181 #[ inline( always) ]
143- fn equals ( b : & big_bitv ) -> bool {
182+ fn equals ( b : & big_bitv , nbits : uint ) -> bool {
144183 let len = b. storage . len ( ) ;
145184 for uint:: iterate( 0 , len) |i| {
146- if self . storage [ i] != b. storage [ i] { return false ; }
185+ let mask = big_mask ( nbits, i) ;
186+ if mask & self . storage [ i] != mask & b. storage [ i] {
187+ return false ;
188+ }
147189 }
148190 }
149191}
@@ -163,8 +205,10 @@ struct bitv {
163205 self . rep = small ( ~small_bitv ( if init { !0 } else { 0 } ) ) ;
164206 }
165207 else {
166- let s = to_mut ( from_elem ( nbits / uint_bits + 1 ,
167- if init { !0 } else { 0 } ) ) ;
208+ let nelems = nbits/uint_bits +
209+ if nbits % uint_bits == 0 { 0 } else { 1 } ;
210+ let elem = if init { !0 } else { 0 } ;
211+ let s = to_mut ( from_elem ( nelems, elem) ) ;
168212 self . rep = big ( ~big_bitv ( s) ) ;
169213 } ;
170214 }
@@ -182,20 +226,20 @@ struct bitv {
182226 match self . rep {
183227 small( s) => match other. rep {
184228 small( s1) => match op {
185- union => s. union ( s1) ,
186- intersect => s. intersect ( s1) ,
187- assign => s. become ( s1) ,
188- difference => s. difference ( s1)
229+ union => s. union ( s1, self . nbits ) ,
230+ intersect => s. intersect ( s1, self . nbits ) ,
231+ assign => s. become ( s1, self . nbits ) ,
232+ difference => s. difference ( s1, self . nbits )
189233 } ,
190234 big( s1) => self . die ( )
191235 } ,
192236 big( s) => match other. rep {
193237 small( _) => self . die ( ) ,
194238 big( s1) => match op {
195- union => s. union ( s1) ,
196- intersect => s. intersect ( s1) ,
197- assign => s. become ( s1) ,
198- difference => s. difference ( s1)
239+ union => s. union ( s1, self . nbits ) ,
240+ intersect => s. intersect ( s1, self . nbits ) ,
241+ assign => s. become ( s1, self . nbits ) ,
242+ difference => s. difference ( s1, self . nbits )
199243 }
200244 }
201245 }
@@ -280,11 +324,11 @@ struct bitv {
280324 if self . nbits != v1. nbits { return false ; }
281325 match self . rep {
282326 small( b) => match v1. rep {
283- small( b1) => b. equals ( b1) ,
327+ small( b1) => b. equals ( b1, self . nbits ) ,
284328 _ => false
285329 } ,
286330 big( s) => match v1. rep {
287- big( s1) => s. equals ( s1) ,
331+ big( s1) => s. equals ( s1, self . nbits ) ,
288332 small( _) => return false
289333 }
290334 }
@@ -330,7 +374,7 @@ struct bitv {
330374 #[ inline( always) ]
331375 fn is_true ( ) -> bool {
332376 match self . rep {
333- small( b) => b. is_true ( ) ,
377+ small( b) => b. is_true ( self . nbits ) ,
334378 _ => {
335379 for self . each( ) |i| { if !i { return false ; } }
336380 true
@@ -351,7 +395,7 @@ struct bitv {
351395
352396 fn is_false ( ) -> bool {
353397 match self . rep {
354- small( b) => b. is_false ( ) ,
398+ small( b) => b. is_false ( self . nbits ) ,
355399 big( _) => {
356400 for self . each( ) |i| { if i { return false ; } }
357401 true
@@ -456,6 +500,14 @@ mod tests {
456500 assert act. eq_vec ( ~[ 1 u] ) ;
457501 }
458502
503+ #[ test]
504+ fn test_2_elements ( ) {
505+ let b = bitv:: bitv ( 2 , false ) ;
506+ b. set ( 0 , true ) ;
507+ b. set ( 1 , false ) ;
508+ assert b. to_str ( ) == ~"10 ";
509+ }
510+
459511 #[ test]
460512 fn test_10_elements ( ) {
461513 let mut act;
@@ -732,6 +784,33 @@ mod tests {
732784 let v1 = bitv ( 110 u, false ) ;
733785 assert !v0. equal ( v1) ;
734786 }
787+
788+ #[ test]
789+ fn test_equal_sneaky_small ( ) {
790+ let a = bitv:: bitv ( 1 , false ) ;
791+ a. set ( 0 , true ) ;
792+
793+ let b = bitv:: bitv ( 1 , true ) ;
794+ b. set ( 0 , true ) ;
795+
796+ assert a. equal ( b) ;
797+ }
798+
799+ #[ test]
800+ fn test_equal_sneaky_big ( ) {
801+ let a = bitv:: bitv ( 100 , false ) ;
802+ for uint:: range( 0 , 100 ) |i| {
803+ a. set ( i, true ) ;
804+ }
805+
806+ let b = bitv:: bitv ( 100 , true ) ;
807+ for uint:: range( 0 , 100 ) |i| {
808+ b. set ( i, true ) ;
809+ }
810+
811+ assert a. equal ( b) ;
812+ }
813+
735814}
736815
737816//
0 commit comments