Implement a read/write operator[] for SmallBitVector with a proxy class.
authorBenjamin Kramer <benny.kra@googlemail.com>
Fri, 30 Apr 2010 12:29:39 +0000 (12:29 +0000)
committerBenjamin Kramer <benny.kra@googlemail.com>
Fri, 30 Apr 2010 12:29:39 +0000 (12:29 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@102709 91177308-0d34-0410-b5e6-96231b3b80d8

include/llvm/ADT/SmallBitVector.h
unittests/ADT/SmallBitVectorTest.cpp

index 7563e81e1cef5e46c01234f08bca20f1f16b4d42..884e631c88bce368e0fe37f1c82b70c53d1c2932 100644 (file)
@@ -52,6 +52,34 @@ class SmallBitVector {
     SmallNumDataBits = SmallNumRawBits - SmallNumSizeBits
   };
 
+public:
+  // Encapsulation of a single bit.
+  class reference {
+    SmallBitVector &TheVector;
+    unsigned BitPos;
+
+  public:
+    reference(SmallBitVector &b, unsigned Idx) : TheVector(b), BitPos(Idx) {}
+
+    reference& operator=(reference t) {
+      *this = bool(t);
+      return *this;
+    }
+
+    reference& operator=(bool t) {
+      if (t)
+        TheVector.set(BitPos);
+      else
+        TheVector.reset(BitPos);
+      return *this;
+    }
+
+    operator bool() const {
+      return const_cast<const SmallBitVector &>(TheVector).operator[](BitPos);
+    }
+  };
+
+private:
   bool isSmall() const {
     return X & uintptr_t(1);
   }
@@ -81,7 +109,7 @@ class SmallBitVector {
 
   void setSmallRawBits(uintptr_t NewRawBits) {
     assert(isSmall());
-    X = NewRawBits << 1 | uintptr_t(1);
+    X = (NewRawBits << 1) | uintptr_t(1);
   }
 
   // Return the size.
@@ -99,7 +127,7 @@ class SmallBitVector {
   }
 
   void setSmallBits(uintptr_t NewBits) {
-    setSmallRawBits(NewBits & ~(~uintptr_t(0) << getSmallSize()) |
+    setSmallRawBits((NewBits & ~(~uintptr_t(0) << getSmallSize())) |
                     (getSmallSize() << SmallNumDataBits));
   }
 
@@ -298,7 +326,11 @@ public:
   }
 
   // Indexing.
-  // TODO: Add an index operator which returns a "reference" (proxy class).
+  reference operator[](unsigned Idx) {
+    assert(Idx < size() && "Out-of-bounds Bit access.");
+    return reference(*this, Idx);
+  }
+
   bool operator[](unsigned Idx) const {
     assert(Idx < size() && "Out-of-bounds Bit access.");
     if (isSmall())
index a2cc652ca1d4440084c3321d7b499ab52ac472b0..a0c079d874a198860631666929e07fe49b73f7bc 100644 (file)
@@ -176,4 +176,12 @@ TEST(SmallBitVectorTest, CompoundAssignment) {
   EXPECT_EQ(100U, A.size());
 }
 
+TEST(SmallBitVectorTest, ProxyIndex) {
+  SmallBitVector Vec(3);
+  EXPECT_TRUE(Vec.none());
+  Vec[0] = Vec[1] = Vec[2] = true;
+  EXPECT_EQ(Vec.size(), Vec.count());
+  Vec[2] = Vec[1] = Vec[0] = false;
+  EXPECT_TRUE(Vec.none());
+}
 }