@@ -19,37 +19,42 @@ export to_str;
19
19
export eq_vec;
20
20
export methods;
21
21
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
+
22
28
struct small_bitv {
29
+ /// only the lowest nbits of this value are used. the rest is undefined.
23
30
let mut bits : u32 ;
24
31
new ( bits : u32 ) { self . bits = bits; }
25
32
priv {
26
33
#[ 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) ;
28
37
let old_b: u32 = self . bits ;
29
38
let new_b = f ( old_b, right_bits) ;
30
39
self . bits = new_b;
31
- old_b != new_b
40
+ mask & old_b != mask & new_b
32
41
}
33
42
}
34
43
#[ 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)
37
46
}
38
47
#[ 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)
41
50
}
42
51
#[ 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)
47
54
}
48
55
#[ 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)
53
58
}
54
59
#[ inline( always) ]
55
60
pure fn get ( i : uint ) -> bool {
@@ -61,42 +66,70 @@ struct small_bitv {
61
66
self . bits |= 1 <<i;
62
67
}
63
68
else {
64
- self . bits &= !( i as u32 ) ;
69
+ self . bits &= !( 1 << i as u32 ) ;
65
70
}
66
71
}
67
72
#[ 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
+ }
69
77
#[ inline( always) ]
70
78
fn clear ( ) { self . bits = 0 ; }
71
79
#[ inline( always) ]
72
80
fn set_all ( ) { self . bits = !0 ; }
73
81
#[ 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
+ }
75
85
#[ 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
+ }
77
89
#[ inline( always) ]
78
90
fn invert ( ) { self . bits = !self . bits ; }
79
91
}
80
92
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
+
81
109
struct 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
83
111
let mut storage : ~[ mut uint ] ;
84
112
new ( -storage: ~[ mut uint] ) {
85
113
self . storage <- storage;
86
114
}
87
115
priv {
88
116
#[ 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 {
90
119
let len = b. storage . len ( ) ;
91
120
assert ( self . storage . len ( ) == len) ;
92
121
let mut changed = false ;
93
122
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
+ }
98
131
true
99
- } ;
132
+ }
100
133
changed
101
134
}
102
135
}
@@ -112,15 +145,21 @@ struct big_bitv {
112
145
#[ inline( always) ]
113
146
fn invert ( ) { for self . each_storage( ) |w| { w = !w } }
114
147
#[ 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
+ }
116
151
#[ 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
+ }
118
155
#[ 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
+ }
120
159
#[ inline( always) ]
121
- fn difference ( b : & big_bitv ) -> bool {
160
+ fn difference ( b : & big_bitv , nbits : uint ) -> bool {
122
161
self . invert ( ) ;
123
- let b = self . intersect ( b) ;
162
+ let b = self . intersect ( b, nbits ) ;
124
163
self . invert ( ) ;
125
164
b
126
165
}
@@ -140,10 +179,13 @@ struct big_bitv {
140
179
else { self . storage [ w] & !flag } ;
141
180
}
142
181
#[ inline( always) ]
143
- fn equals ( b : & big_bitv ) -> bool {
182
+ fn equals ( b : & big_bitv , nbits : uint ) -> bool {
144
183
let len = b. storage . len ( ) ;
145
184
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
+ }
147
189
}
148
190
}
149
191
}
@@ -163,8 +205,10 @@ struct bitv {
163
205
self . rep = small ( ~small_bitv ( if init { !0 } else { 0 } ) ) ;
164
206
}
165
207
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) ) ;
168
212
self . rep = big ( ~big_bitv ( s) ) ;
169
213
} ;
170
214
}
@@ -182,20 +226,20 @@ struct bitv {
182
226
match self . rep {
183
227
small( s) => match other. rep {
184
228
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 )
189
233
} ,
190
234
big( s1) => self . die ( )
191
235
} ,
192
236
big( s) => match other. rep {
193
237
small( _) => self . die ( ) ,
194
238
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 )
199
243
}
200
244
}
201
245
}
@@ -280,11 +324,11 @@ struct bitv {
280
324
if self . nbits != v1. nbits { return false ; }
281
325
match self . rep {
282
326
small( b) => match v1. rep {
283
- small( b1) => b. equals ( b1) ,
327
+ small( b1) => b. equals ( b1, self . nbits ) ,
284
328
_ => false
285
329
} ,
286
330
big( s) => match v1. rep {
287
- big( s1) => s. equals ( s1) ,
331
+ big( s1) => s. equals ( s1, self . nbits ) ,
288
332
small( _) => return false
289
333
}
290
334
}
@@ -330,7 +374,7 @@ struct bitv {
330
374
#[ inline( always) ]
331
375
fn is_true ( ) -> bool {
332
376
match self . rep {
333
- small( b) => b. is_true ( ) ,
377
+ small( b) => b. is_true ( self . nbits ) ,
334
378
_ => {
335
379
for self . each( ) |i| { if !i { return false ; } }
336
380
true
@@ -351,7 +395,7 @@ struct bitv {
351
395
352
396
fn is_false ( ) -> bool {
353
397
match self . rep {
354
- small( b) => b. is_false ( ) ,
398
+ small( b) => b. is_false ( self . nbits ) ,
355
399
big( _) => {
356
400
for self . each( ) |i| { if i { return false ; } }
357
401
true
@@ -456,6 +500,14 @@ mod tests {
456
500
assert act. eq_vec ( ~[ 1 u] ) ;
457
501
}
458
502
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
+
459
511
#[ test]
460
512
fn test_10_elements ( ) {
461
513
let mut act;
@@ -732,6 +784,33 @@ mod tests {
732
784
let v1 = bitv ( 110 u, false ) ;
733
785
assert !v0. equal ( v1) ;
734
786
}
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
+
735
814
}
736
815
737
816
//
0 commit comments