diff --git a/llvm/include/llvm/ADT/PackedVector.h b/llvm/include/llvm/ADT/PackedVector.h index 77fcbf24b2861..09c20e39d1552 100644 --- a/llvm/include/llvm/ADT/PackedVector.h +++ b/llvm/include/llvm/ADT/PackedVector.h @@ -20,53 +20,6 @@ namespace llvm { -template -class PackedVectorBase; - -// This won't be necessary if we can specialize members without specializing -// the parent template. -template -class PackedVectorBase { -protected: - static T getValue(const BitVectorTy &Bits, unsigned Idx) { - T val = T(); - for (unsigned i = 0; i != BitNum; ++i) - val = T(val | ((Bits[(Idx * BitNum) + i] ? 1UL : 0UL) << i)); - return val; - } - - static void setValue(BitVectorTy &Bits, unsigned Idx, T val) { - assert((val >> BitNum) == 0 && "value is too big"); - for (unsigned i = 0; i != BitNum; ++i) - Bits[(Idx * BitNum) + i] = val & (T(1) << i); - } -}; - -template -class PackedVectorBase { -protected: - static T getValue(const BitVectorTy &Bits, unsigned Idx) { - T val = T(); - for (unsigned i = 0; i != BitNum - 1; ++i) - val = T(val | ((Bits[(Idx * BitNum) + i] ? 1UL : 0UL) << i)); - if (Bits[(Idx * BitNum) + BitNum - 1]) - val = ~val; - return val; - } - - static void setValue(BitVectorTy &Bits, unsigned Idx, T val) { - if (val < 0) { - val = ~val; - Bits.set((Idx * BitNum) + BitNum - 1); - } else { - Bits.reset((Idx * BitNum) + BitNum - 1); - } - assert((val >> (BitNum - 1)) == 0 && "value is too big"); - for (unsigned i = 0; i != BitNum - 1; ++i) - Bits[(Idx * BitNum) + i] = val & (T(1) << i); - } -}; - /// Store a vector of values using a specific number of bits for each /// value. Both signed and unsigned types can be used, e.g /// @code @@ -75,16 +28,46 @@ class PackedVectorBase { /// will create a vector accepting values -2, -1, 0, 1. Any other value will hit /// an assertion. template -class PackedVector - : public PackedVectorBase::is_signed> { +class PackedVector { BitVectorTy Bits; // Keep track of the number of elements on our own. // We always maintain Bits.size() == NumElements * BitNum. // Used to avoid an integer division in size(). unsigned NumElements = 0; - using base = PackedVectorBase::is_signed>; + + static T getValue(const BitVectorTy &Bits, unsigned Idx) { + if constexpr (std::numeric_limits::is_signed) { + T val = T(); + for (unsigned i = 0; i != BitNum - 1; ++i) + val = T(val | ((Bits[(Idx * BitNum) + i] ? 1UL : 0UL) << i)); + if (Bits[(Idx * BitNum) + BitNum - 1]) + val = ~val; + return val; + } else { + T val = T(); + for (unsigned i = 0; i != BitNum; ++i) + val = T(val | ((Bits[(Idx * BitNum) + i] ? 1UL : 0UL) << i)); + return val; + } + } + + static void setValue(BitVectorTy &Bits, unsigned Idx, T val) { + if constexpr (std::numeric_limits::is_signed) { + if (val < 0) { + val = ~val; + Bits.set((Idx * BitNum) + BitNum - 1); + } else { + Bits.reset((Idx * BitNum) + BitNum - 1); + } + assert((val >> (BitNum - 1)) == 0 && "value is too big"); + for (unsigned i = 0; i != BitNum - 1; ++i) + Bits[(Idx * BitNum) + i] = val & (T(1) << i); + } else { + assert((val >> BitNum) == 0 && "value is too big"); + for (unsigned i = 0; i != BitNum; ++i) + Bits[(Idx * BitNum) + i] = val & (T(1) << i); + } + } public: class reference { @@ -135,7 +118,7 @@ class PackedVector reference operator[](unsigned Idx) { return reference(*this, Idx); } - T operator[](unsigned Idx) const { return base::getValue(Bits, Idx); } + T operator[](unsigned Idx) const { return getValue(Bits, Idx); } bool operator==(const PackedVector &RHS) const { return Bits == RHS.Bits; }