Skip to content

Commit 6ef4582

Browse files
committed
Some fixes to bitv. Close #2342.
1 parent 1e33612 commit 6ef4582

File tree

1 file changed

+34
-13
lines changed

1 file changed

+34
-13
lines changed

src/libstd/bitv.rs

Lines changed: 34 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,7 @@ fn clone(v: bitv) -> bitv {
9595
}
9696

9797
#[doc = "Retreive the value at index `i`"]
98+
#[inline(always)]
9899
pure fn get(v: bitv, i: uint) -> bool {
99100
assert (i < v.nbits);
100101
let bits = uint_bits;
@@ -104,37 +105,31 @@ pure fn get(v: bitv, i: uint) -> bool {
104105
ret x == 1u;
105106
}
106107

107-
// FIXME: This doesn't account for the actual size of the vectors,
108-
// so it could end up comparing garbage bits (#2342)
109108
#[doc = "
110109
Compares two bitvectors
111110
112111
Both bitvectors must be the same length. Returns `true` if both bitvectors
113112
contain identical elements.
114113
"]
115114
fn equal(v0: bitv, v1: bitv) -> bool {
115+
if v0.nbits != v1.nbits { ret false; }
116116
let len = vec::len(v1.storage);
117117
for uint::iterate(0u, len) {|i|
118118
if v0.storage[i] != v1.storage[i] { ret false; }
119119
}
120120
}
121121

122122
#[doc = "Set all bits to 0"]
123-
fn clear(v: bitv) {
124-
for uint::range(0u, vec::len(v.storage)) {|i| v.storage[i] = 0u; };
125-
}
123+
#[inline(always)]
124+
fn clear(v: bitv) { for each_storage(v) {|w| w = 0u } }
126125

127126
#[doc = "Set all bits to 1"]
128-
fn set_all(v: bitv) {
129-
for uint::range(0u, v.nbits) {|i| set(v, i, true); };
130-
}
127+
#[inline(always)]
128+
fn set_all(v: bitv) { for each_storage(v) {|w| w = !0u } }
131129

132130
#[doc = "Invert all bits"]
133-
fn invert(v: bitv) {
134-
for uint::range(0u, vec::len(v.storage)) {|i|
135-
v.storage[i] = !v.storage[i];
136-
};
137-
}
131+
#[inline(always)]
132+
fn invert(v: bitv) { for each_storage(v) {|w| w = !w } }
138133

139134
#[doc = "
140135
Calculate the difference between two bitvectors
@@ -156,6 +151,7 @@ Set the value of a bit at a given index
156151
157152
`i` must be less than the length of the bitvector.
158153
"]
154+
#[inline(always)]
159155
fn set(v: bitv, i: uint, x: bool) {
160156
assert (i < v.nbits);
161157
let bits = uint_bits;
@@ -193,6 +189,7 @@ fn to_vec(v: bitv) -> [uint] {
193189
ret vec::from_fn::<uint>(v.nbits, sub);
194190
}
195191

192+
#[inline(always)]
196193
fn each(v: bitv, f: fn(bool) -> bool) {
197194
let mut i = 0u;
198195
while i < v.nbits {
@@ -201,6 +198,16 @@ fn each(v: bitv, f: fn(bool) -> bool) {
201198
}
202199
}
203200

201+
#[inline(always)]
202+
fn each_storage(v: bitv, op: fn(&uint) -> bool) {
203+
for uint::range(0u, vec::len(v.storage)) {|i|
204+
let mut w = v.storage[i];
205+
let b = !op(w);
206+
v.storage[i] = w;
207+
if !b { break; }
208+
}
209+
}
210+
204211
#[doc = "
205212
Converts the bitvector to a string.
206213
@@ -524,6 +531,20 @@ mod tests {
524531
0u, 0u, 0u, 0u, 1u, 1u, 1u]));
525532
}
526533

534+
#[test]
535+
fn test_equal_differing_sizes() {
536+
let v0 = bitv(10u, false);
537+
let v1 = bitv(11u, false);
538+
assert !equal(v0, v1);
539+
}
540+
541+
#[test]
542+
fn test_equal_greatly_differing_sizes() {
543+
let v0 = bitv(10u, false);
544+
let v1 = bitv(110u, false);
545+
assert !equal(v0, v1);
546+
}
547+
527548
}
528549

529550
//

0 commit comments

Comments
 (0)