SmallNumDataBits = SmallNumRawBits - SmallNumSizeBits
};
+ static_assert(NumBaseBits == 64 || NumBaseBits == 32,
+ "Unsupported word size");
+
public:
+ typedef unsigned size_type;
// Encapsulation of a single bit.
class reference {
SmallBitVector &TheVector;
public:
reference(SmallBitVector &b, unsigned Idx) : TheVector(b), BitPos(Idx) {}
+ reference(const reference&) = default;
+
reference& operator=(reference t) {
*this = bool(t);
return *this;
switchToLarge(new BitVector(*RHS.getPointer()));
}
-#if LLVM_USE_RVALUE_REFERENCES
SmallBitVector(SmallBitVector &&RHS) : X(RHS.X) {
RHS.X = 1;
}
-#endif
~SmallBitVector() {
if (!isSmall())
}
/// count - Returns the number of bits which are set.
- unsigned count() const {
+ size_type count() const {
if (isSmall()) {
uintptr_t Bits = getSmallBits();
- if (sizeof(uintptr_t) * CHAR_BIT == 32)
- return CountPopulation_32(Bits);
- if (sizeof(uintptr_t) * CHAR_BIT == 64)
- return CountPopulation_64(Bits);
- llvm_unreachable("Unsupported!");
+ return countPopulation(Bits);
}
return getPointer()->count();
}
uintptr_t Bits = getSmallBits();
if (Bits == 0)
return -1;
- if (sizeof(uintptr_t) * CHAR_BIT == 32)
- return CountTrailingZeros_32(Bits);
- if (sizeof(uintptr_t) * CHAR_BIT == 64)
- return CountTrailingZeros_64(Bits);
- llvm_unreachable("Unsupported!");
+ return countTrailingZeros(Bits);
}
return getPointer()->find_first();
}
Bits &= ~uintptr_t(0) << (Prev + 1);
if (Bits == 0 || Prev + 1 >= getSmallSize())
return -1;
- if (sizeof(uintptr_t) * CHAR_BIT == 32)
- return CountTrailingZeros_32(Bits);
- if (sizeof(uintptr_t) * CHAR_BIT == 64)
- return CountTrailingZeros_64(Bits);
- llvm_unreachable("Unsupported!");
+ return countTrailingZeros(Bits);
}
return getPointer()->find_next(Prev);
}
}
SmallBitVector &set(unsigned Idx) {
- if (isSmall())
+ if (isSmall()) {
+ assert(Idx <= static_cast<unsigned>(
+ std::numeric_limits<uintptr_t>::digits) &&
+ "undefined behavior");
setSmallBits(getSmallBits() | (uintptr_t(1) << Idx));
+ }
else
getPointer()->set(Idx);
return *this;
assert(E <= size() && "Attempted to set out-of-bounds range!");
if (I == E) return *this;
if (isSmall()) {
- uintptr_t EMask = 1 << E;
- uintptr_t IMask = 1 << I;
+ uintptr_t EMask = ((uintptr_t)1) << E;
+ uintptr_t IMask = ((uintptr_t)1) << I;
uintptr_t Mask = EMask - IMask;
setSmallBits(getSmallBits() | Mask);
} else
assert(E <= size() && "Attempted to reset out-of-bounds range!");
if (I == E) return *this;
if (isSmall()) {
- uintptr_t EMask = 1 << E;
- uintptr_t IMask = 1 << I;
+ uintptr_t EMask = ((uintptr_t)1) << E;
+ uintptr_t IMask = ((uintptr_t)1) << I;
uintptr_t Mask = EMask - IMask;
setSmallBits(getSmallBits() & ~Mask);
} else
return *this;
}
+ /// reset - Reset bits that are set in RHS. Same as *this &= ~RHS.
+ SmallBitVector &reset(const SmallBitVector &RHS) {
+ if (isSmall() && RHS.isSmall())
+ setSmallBits(getSmallBits() & ~RHS.getSmallBits());
+ else if (!isSmall() && !RHS.isSmall())
+ getPointer()->reset(*RHS.getPointer());
+ else
+ for (unsigned i = 0, e = std::min(size(), RHS.size()); i != e; ++i)
+ if (RHS.test(i))
+ reset(i);
+
+ return *this;
+ }
+
+ /// test - Check if (This - RHS) is zero.
+ /// This is the same as reset(RHS) and any().
+ bool test(const SmallBitVector &RHS) const {
+ if (isSmall() && RHS.isSmall())
+ return (getSmallBits() & ~RHS.getSmallBits()) != 0;
+ if (!isSmall() && !RHS.isSmall())
+ return getPointer()->test(*RHS.getPointer());
+
+ unsigned i, e;
+ for (i = 0, e = std::min(size(), RHS.size()); i != e; ++i)
+ if (test(i) && !RHS.test(i))
+ return true;
+
+ for (e = size(); i != e; ++i)
+ if (test(i))
+ return true;
+
+ return false;
+ }
+
SmallBitVector &operator|=(const SmallBitVector &RHS) {
resize(std::max(size(), RHS.size()));
if (isSmall())
return *this;
}
-#if LLVM_USE_RVALUE_REFERENCES
const SmallBitVector &operator=(SmallBitVector &&RHS) {
if (this != &RHS) {
clear();
}
return *this;
}
-#endif
void swap(SmallBitVector &RHS) {
std::swap(X, RHS.X);
}
private:
- template<bool AddBits, bool InvertMask>
+ template <bool AddBits, bool InvertMask>
void applyMask(const uint32_t *Mask, unsigned MaskWords) {
- assert((NumBaseBits == 64 || NumBaseBits == 32) && "Unsupported word size");
- if (NumBaseBits == 64 && MaskWords >= 2) {
- uint64_t M = Mask[0] | (uint64_t(Mask[1]) << 32);
- if (InvertMask) M = ~M;
- if (AddBits) setSmallBits(getSmallBits() | M);
- else setSmallBits(getSmallBits() & ~M);
- } else {
- uint32_t M = Mask[0];
- if (InvertMask) M = ~M;
- if (AddBits) setSmallBits(getSmallBits() | M);
- else setSmallBits(getSmallBits() & ~M);
- }
+ assert(MaskWords <= sizeof(uintptr_t) && "Mask is larger than base!");
+ uintptr_t M = Mask[0];
+ if (NumBaseBits == 64)
+ M |= uint64_t(Mask[1]) << 32;
+ if (InvertMask)
+ M = ~M;
+ if (AddBits)
+ setSmallBits(getSmallBits() | M);
+ else
+ setSmallBits(getSmallBits() & ~M);
}
};