about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
authorTim Chevalier <chevalier@alum.wellesley.edu>2013-01-19 17:40:59 -0800
committerTim Chevalier <chevalier@alum.wellesley.edu>2013-01-19 17:40:59 -0800
commit1cfa01decfbec571ac2d985339d6ebe0dbdf4a47 (patch)
tree85721f111484995879a65bdefb8756f63e3b6eac /src
parentef0f71dc3fc8b203975c3da5230bed77becd0ee0 (diff)
parent95d25ca47c0afe8c72bf16777ed266c4e033c54e (diff)
downloadrust-1cfa01decfbec571ac2d985339d6ebe0dbdf4a47.tar.gz
rust-1cfa01decfbec571ac2d985339d6ebe0dbdf4a47.zip
Merge pull request #4546 from alexcrichton/bitv-difference-bug
Fix the difference method on bit vectors
Diffstat (limited to 'src')
-rw-r--r--src/libstd/bitv.rs37
1 files changed, 32 insertions, 5 deletions
diff --git a/src/libstd/bitv.rs b/src/libstd/bitv.rs
index 834edc3f464..288163accfe 100644
--- a/src/libstd/bitv.rs
+++ b/src/libstd/bitv.rs
@@ -59,7 +59,7 @@ impl SmallBitv {
 
     #[inline(always)]
     fn difference(s: &SmallBitv, nbits: uint) -> bool {
-        self.bits_op(s.bits, nbits, |u1, u2| u1 ^ u2)
+        self.bits_op(s.bits, nbits, |u1, u2| u1 & !u2)
     }
 
     #[inline(always)]
@@ -180,10 +180,7 @@ impl BigBitv {
 
     #[inline(always)]
     fn difference(b: &BigBitv, nbits: uint) -> bool {
-        self.invert();
-        let b = self.intersect(b, nbits);
-        self.invert();
-        b
+        self.process(b, nbits, difference)
     }
 
     #[inline(always)]
@@ -567,6 +564,8 @@ pure fn lor(w0: uint, w1: uint) -> uint { return w0 | w1; }
 
 pure fn land(w0: uint, w1: uint) -> uint { return w0 & w1; }
 
+pure fn difference(w0: uint, w1: uint) -> uint { return w0 & !w1; }
+
 pure fn right(_w0: uint, w1: uint) -> uint { return w1; }
 
 impl Bitv: ops::Index<uint,bool> {
@@ -954,6 +953,34 @@ mod tests {
         let bools = ~[false, false, true, false, false, true, true, false];
         assert from_bytes([0b00100110]).to_bools() == bools;
     }
+
+    #[test]
+    fn test_small_difference() {
+      let b1 = Bitv(3, false);
+      let b2 = Bitv(3, false);
+      b1.set(0, true);
+      b1.set(1, true);
+      b2.set(1, true);
+      b2.set(2, true);
+      assert b1.difference(&b2);
+      assert b1[0];
+      assert !b1[1];
+      assert !b1[2];
+    }
+
+    #[test]
+    fn test_big_difference() {
+      let b1 = Bitv(100, false);
+      let b2 = Bitv(100, false);
+      b1.set(0, true);
+      b1.set(40, true);
+      b2.set(40, true);
+      b2.set(80, true);
+      assert b1.difference(&b2);
+      assert b1[0];
+      assert !b1[40];
+      assert !b1[80];
+    }
 }
 
 //