Index: include/llvm/ADT/BitVector.h =================================================================== --- include/llvm/ADT/BitVector.h +++ include/llvm/ADT/BitVector.h @@ -295,6 +295,29 @@ return *this; } + /// Set bit \p Idx to true. This function allows BitVector to be used in + /// contexts expecting std::set/DenseSet like API. + std::pair insert(unsigned Idx) { + reference ref(*this, Idx); + bool Res = !ref; + ref = true; + return std::make_pair(ref, Res); + } + + /// Clear bit \p Idx. This function allows BitVector to be used in contexts + /// expecting std::set/DenseSet like API. + bool erase(unsigned Idx) { + bool Res = test(Idx); + reset(Idx); + return Res; + } + + /// Returns 1 if bit \p Idx is set, 0 otherwise. This function allows + /// BitVector to be used in contexts expecting std::set/DenseSet like API. + size_type count(unsigned Idx) const { + return test(Idx); + } + BitVector &flip() { for (unsigned i = 0; i < NumBitWords(size()); ++i) Bits[i] = ~Bits[i]; Index: include/llvm/ADT/SmallBitVector.h =================================================================== --- include/llvm/ADT/SmallBitVector.h +++ include/llvm/ADT/SmallBitVector.h @@ -452,6 +452,29 @@ return false; } + /// Set bit \p Idx to true. This function allows BitVector to be used in + /// contexts expecting std::set/DenseSet like API. + std::pair insert(unsigned Idx) { + reference ref(*this, Idx); + bool Res = !ref; + ref = true; + return std::make_pair(ref, Res); + } + + /// Clear bit \p Idx. This function allows BitVector to be used in contexts + /// expecting std::set/DenseSet like API. + bool erase(unsigned Idx) { + bool Res = test(Idx); + reset(Idx); + return Res; + } + + /// Returns 1 if bit \p Idx is set, 0 otherwise. This function allows + /// BitVector to be used in contexts expecting std::set/DenseSet like API. + size_type count(unsigned Idx) const { + return test(Idx); + } + SmallBitVector &operator|=(const SmallBitVector &RHS) { resize(std::max(size(), RHS.size())); if (isSmall()) Index: unittests/ADT/BitVectorTest.cpp =================================================================== --- unittests/ADT/BitVectorTest.cpp +++ unittests/ADT/BitVectorTest.cpp @@ -78,12 +78,19 @@ ++Count; EXPECT_TRUE(Vec[i]); EXPECT_TRUE(Vec.test(i)); + EXPECT_EQ(Vec.count(i), 1u); } EXPECT_EQ(Count, Vec.count()); EXPECT_EQ(Count, 23u); EXPECT_FALSE(Vec[0]); + EXPECT_FALSE(Vec.test(0)); + EXPECT_EQ(Vec.count(0), 0u); EXPECT_TRUE(Vec[32]); + EXPECT_TRUE(Vec.test(32)); + EXPECT_EQ(Vec.count(32), 1u); EXPECT_FALSE(Vec[56]); + EXPECT_FALSE(Vec.test(56)); + EXPECT_EQ(Vec.count(56), 0u); Vec.resize(61, false); TypeParam Copy = Vec; @@ -108,13 +115,22 @@ ++Count; EXPECT_TRUE(Vec[i]); EXPECT_TRUE(Vec.test(i)); + EXPECT_EQ(Vec.count(i), 1u); } EXPECT_EQ(Count, Vec.count()); EXPECT_EQ(Count, 42u); EXPECT_FALSE(Vec[0]); + EXPECT_FALSE(Vec.test(0)); + EXPECT_EQ(Vec.count(0), 0u); EXPECT_TRUE(Vec[32]); + EXPECT_TRUE(Vec.test(32)); + EXPECT_EQ(Vec.count(32), 1u); EXPECT_FALSE(Vec[60]); + EXPECT_FALSE(Vec.test(60)); + EXPECT_EQ(Vec.count(60), 0u); EXPECT_FALSE(Vec[129]); + EXPECT_FALSE(Vec.test(129)); + EXPECT_EQ(Vec.count(129), 0u); Vec.flip(60); EXPECT_TRUE(Vec[60]); @@ -399,5 +415,50 @@ C.reset(C); EXPECT_TRUE(C.none()); } + +TYPED_TEST(BitVectorTest, InsertErase) { + TypeParam A(83); + + EXPECT_EQ(A.count(), 0u); + + EXPECT_TRUE(A.insert(7).second); + EXPECT_EQ(A.count(), 1u); + EXPECT_FALSE(A.insert(7).second); + EXPECT_EQ(A.count(), 1u); + EXPECT_TRUE(A[7]); + + A.set(10); + EXPECT_FALSE(A.insert(10).second); + EXPECT_TRUE(A[10]); + EXPECT_EQ(A.count(), 2u); + + std::pair P0 = A.insert(12); + EXPECT_TRUE(P0.second); + EXPECT_TRUE(A[12]); + P0.first = false; + EXPECT_FALSE(A[12]); + EXPECT_EQ(A.count(), 2u); + P0.first = true; + EXPECT_TRUE(A[12]); + EXPECT_EQ(A.count(), 3u); + + std::pair P1 = A.insert(10); + EXPECT_FALSE(P1.second); + EXPECT_TRUE(A[10]); + P1.first = false; + EXPECT_FALSE(A[10]); + EXPECT_EQ(A.count(), 2u); + P1.first = true; + EXPECT_TRUE(A[10]); + EXPECT_EQ(A.count(), 3u); + + EXPECT_FALSE(A.erase(3)); + EXPECT_EQ(A.count(), 3u); + A.set(77); + EXPECT_TRUE(A.erase(77)); + EXPECT_EQ(A.count(), 3u); + EXPECT_FALSE(A.erase(77)); + EXPECT_EQ(A.count(), 3u); } +} // end anonymous namespace #endif