@@ -15,16 +15,20 @@ export is_false;
15
15
export to_vec;
16
16
export to_str;
17
17
export eq_vec;
18
+ export methods;
18
19
19
20
// FIXME (#2341): With recursive object types, we could implement binary
20
21
// methods like union, intersection, and difference. At that point, we could
21
22
// write an optimizing version of this module that produces a different obj
22
23
// for the case where nbits <= 32.
23
24
24
25
/// The bitvector type
25
- type bitv = @ { storage : ~[ mut uint ] , nbits : uint } ;
26
+ type bitv = { storage : ~[ mut uint ] , nbits : uint } ;
26
27
27
- const uint_bits: uint = 32 u + ( 1 u << 32 u >> 27 u) ;
28
+ #[ cfg( target_arch="x86" ) ]
29
+ const uint_bits: uint = 32 ;
30
+ #[ cfg( target_arch="x86_64" ) ]
31
+ const uint_bits: uint = 64 ;
28
32
29
33
/**
30
34
* Constructs a bitvector
@@ -37,7 +41,7 @@ const uint_bits: uint = 32u + (1u << 32u >> 27u);
37
41
fn bitv ( nbits : uint , init : bool ) -> bitv {
38
42
let elt = if init { !0 u } else { 0 u } ;
39
43
let storage = vec:: to_mut ( vec:: from_elem ( nbits / uint_bits + 1 u, elt) ) ;
40
- ret @ { storage : storage, nbits : nbits} ;
44
+ ret { storage : storage, nbits : nbits} ;
41
45
}
42
46
43
47
fn process ( v0 : bitv , v1 : bitv , op : fn ( uint , uint ) -> uint ) -> bool {
@@ -55,23 +59,24 @@ fn process(v0: bitv, v1: bitv, op: fn(uint, uint) -> uint) -> bool {
55
59
}
56
60
57
61
58
- fn lor ( w0 : uint , w1 : uint ) -> uint { ret w0 | w1; }
59
-
62
+ /**
63
+ * Calculates the union of two bitvectors
64
+ *
65
+ * Sets `v0` to the union of `v0` and `v1`. Both bitvectors must be the
66
+ * same length. Returns 'true' if `v0` was changed.
67
+ */
60
68
fn union ( v0 : bitv , v1 : bitv ) -> bool {
61
- let sub = lor ; ret process( v0, v1, sub ) ;
69
+ process ( v0, v1, |a , b| a | b )
62
70
}
63
71
64
- fn land ( w0 : uint , w1 : uint ) -> uint { ret w0 & w1; }
65
-
66
72
/**
67
73
* Calculates the intersection of two bitvectors
68
74
*
69
75
* Sets `v0` to the intersection of `v0` and `v1`. Both bitvectors must be the
70
76
* same length. Returns 'true' if `v0` was changed.
71
77
*/
72
78
fn intersect ( v0 : bitv , v1 : bitv ) -> bool {
73
- let sub = land;
74
- ret process( v0, v1, sub) ;
79
+ process ( v0, v1, |a, b| a & b)
75
80
}
76
81
77
82
fn right ( _w0 : uint , w1 : uint ) -> uint { ret w1; }
@@ -87,10 +92,7 @@ fn assign(v0: bitv, v1: bitv) -> bool {
87
92
88
93
/// Makes a copy of a bitvector
89
94
fn clone ( v : bitv ) -> bitv {
90
- let storage = vec:: to_mut ( vec:: from_elem ( v. nbits / uint_bits + 1 u, 0 u) ) ;
91
- let len = vec:: len ( v. storage ) ;
92
- for uint:: range( 0 u, len) |i| { storage[ i] = v. storage [ i] ; } ;
93
- ret @{ storage : storage, nbits : v. nbits } ;
95
+ copy v
94
96
}
95
97
96
98
/// Retrieve the value at index `i`
@@ -174,18 +176,13 @@ fn is_false(v: bitv) -> bool {
174
176
ret true;
175
177
}
176
178
177
- fn init_to_vec( v: bitv, i: uint) -> uint {
178
- ret if get( v, i) { 1 u } else { 0 u } ;
179
- }
180
-
181
179
/**
182
180
* Converts the bitvector to a vector of uint with the same length.
183
181
*
184
182
* Each uint in the resulting vector has either value 0u or 1u.
185
183
*/
186
184
fn to_vec ( v : bitv ) -> ~[ uint ] {
187
- let sub = |x| init_to_vec ( v, x) ;
188
- ret vec:: from_fn :: < uint > ( v. nbits , sub) ;
185
+ vec:: from_fn :: < uint > ( v. nbits , |i| if get ( v, i) { 1 } else { 0 } )
189
186
}
190
187
191
188
#[ inline( always) ]
@@ -238,6 +235,30 @@ fn eq_vec(v0: bitv, v1: ~[uint]) -> bool {
238
235
ret true;
239
236
}
240
237
238
+ impl methods for bitv {
239
+ fn union ( rhs : bitv ) -> bool { union ( self , rhs) }
240
+ fn intersect ( rhs : bitv ) -> bool { intersect ( self , rhs) }
241
+ fn assign ( rhs : bitv ) -> bool { assign ( self , rhs) }
242
+ fn get ( i : uint ) -> bool { get ( self , i) }
243
+ fn [ ] ( i: uint) -> bool { self . get ( i ) }
244
+ fn eq ( rhs : bitv ) -> bool { equal ( self , rhs) }
245
+ fn clear ( ) { clear ( self ) }
246
+ fn set_all ( ) { set_all ( self ) }
247
+ fn invert ( ) { invert ( self ) }
248
+ fn difference ( rhs : bitv ) -> bool { difference ( self , rhs) }
249
+ fn set ( i : uint , x : bool ) { set ( self , i, x) }
250
+ fn is_true ( ) -> bool { is_true ( self ) }
251
+ fn is_false ( ) -> bool { is_false ( self ) }
252
+ fn to_vec ( ) -> ~[ uint ] { to_vec ( self ) }
253
+ fn each ( f : fn ( bool ) -> bool ) { each ( self , f) }
254
+ fn each_storage ( f : fn ( & uint ) -> bool ) { each_storage ( self , f) }
255
+ fn eq_vec ( v : ~[ uint ] ) -> bool { eq_vec ( self , v) }
256
+ }
257
+
258
+ impl of to_str:: to_str for bitv {
259
+ fn to_str ( ) -> ~str { to_str ( self ) }
260
+ }
261
+
241
262
#[ cfg( test) ]
242
263
mod tests {
243
264
#[ test]
0 commit comments