Counter Strike : Global Offensive Source Code
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

159 lines
4.3 KiB

  1. //===- llvm/ADT/PackedVector.h - Packed values vector -----------*- C++ -*-===//
  2. //
  3. // The LLVM Compiler Infrastructure
  4. //
  5. // This file is distributed under the University of Illinois Open Source
  6. // License. See LICENSE.TXT for details.
  7. //
  8. //===----------------------------------------------------------------------===//
  9. //
  10. // This file implements the PackedVector class.
  11. //
  12. //===----------------------------------------------------------------------===//
  13. #ifndef LLVM_ADT_PACKEDVECTOR_H
  14. #define LLVM_ADT_PACKEDVECTOR_H
  15. #include "llvm/ADT/BitVector.h"
  16. #include <limits>
  17. namespace llvm {
  18. template <typename T, unsigned BitNum, typename BitVectorTy, bool isSigned>
  19. class PackedVectorBase;
  20. // This won't be necessary if we can specialize members without specializing
  21. // the parent template.
  22. template <typename T, unsigned BitNum, typename BitVectorTy>
  23. class PackedVectorBase<T, BitNum, BitVectorTy, false> {
  24. protected:
  25. static T getValue(const BitVectorTy &Bits, unsigned Idx) {
  26. T val = T();
  27. for (unsigned i = 0; i != BitNum; ++i)
  28. val = T(val | ((Bits[(Idx << (BitNum-1)) + i] ? 1UL : 0UL) << i));
  29. return val;
  30. }
  31. static void setValue(BitVectorTy &Bits, unsigned Idx, T val) {
  32. assert((val >> BitNum) == 0 && "value is too big");
  33. for (unsigned i = 0; i != BitNum; ++i)
  34. Bits[(Idx << (BitNum-1)) + i] = val & (T(1) << i);
  35. }
  36. };
  37. template <typename T, unsigned BitNum, typename BitVectorTy>
  38. class PackedVectorBase<T, BitNum, BitVectorTy, true> {
  39. protected:
  40. static T getValue(const BitVectorTy &Bits, unsigned Idx) {
  41. T val = T();
  42. for (unsigned i = 0; i != BitNum-1; ++i)
  43. val = T(val | ((Bits[(Idx << (BitNum-1)) + i] ? 1UL : 0UL) << i));
  44. if (Bits[(Idx << (BitNum-1)) + BitNum-1])
  45. val = ~val;
  46. return val;
  47. }
  48. static void setValue(BitVectorTy &Bits, unsigned Idx, T val) {
  49. if (val < 0) {
  50. val = ~val;
  51. Bits.set((Idx << (BitNum-1)) + BitNum-1);
  52. }
  53. assert((val >> (BitNum-1)) == 0 && "value is too big");
  54. for (unsigned i = 0; i != BitNum-1; ++i)
  55. Bits[(Idx << (BitNum-1)) + i] = val & (T(1) << i);
  56. }
  57. };
  58. /// \brief Store a vector of values using a specific number of bits for each
  59. /// value. Both signed and unsigned types can be used, e.g
  60. /// @code
  61. /// PackedVector<signed, 2> vec;
  62. /// @endcode
  63. /// will create a vector accepting values -2, -1, 0, 1. Any other value will hit
  64. /// an assertion.
  65. template <typename T, unsigned BitNum, typename BitVectorTy = BitVector>
  66. class PackedVector : public PackedVectorBase<T, BitNum, BitVectorTy,
  67. std::numeric_limits<T>::is_signed> {
  68. BitVectorTy Bits;
  69. typedef PackedVectorBase<T, BitNum, BitVectorTy,
  70. std::numeric_limits<T>::is_signed> base;
  71. public:
  72. class reference {
  73. PackedVector &Vec;
  74. const unsigned Idx;
  75. reference(); // Undefined
  76. public:
  77. reference(PackedVector &vec, unsigned idx) : Vec(vec), Idx(idx) { }
  78. reference &operator=(T val) {
  79. Vec.setValue(Vec.Bits, Idx, val);
  80. return *this;
  81. }
  82. operator T() const {
  83. return Vec.getValue(Vec.Bits, Idx);
  84. }
  85. };
  86. PackedVector() { }
  87. explicit PackedVector(unsigned size) : Bits(size << (BitNum-1)) { }
  88. bool empty() const { return Bits.empty(); }
  89. unsigned size() const { return Bits.size() >> (BitNum-1); }
  90. void clear() { Bits.clear(); }
  91. void resize(unsigned N) { Bits.resize(N << (BitNum-1)); }
  92. void reserve(unsigned N) { Bits.reserve(N << (BitNum-1)); }
  93. PackedVector &reset() {
  94. Bits.reset();
  95. return *this;
  96. }
  97. void push_back(T val) {
  98. resize(size()+1);
  99. (*this)[size()-1] = val;
  100. }
  101. reference operator[](unsigned Idx) {
  102. return reference(*this, Idx);
  103. }
  104. T operator[](unsigned Idx) const {
  105. return base::getValue(Bits, Idx);
  106. }
  107. bool operator==(const PackedVector &RHS) const {
  108. return Bits == RHS.Bits;
  109. }
  110. bool operator!=(const PackedVector &RHS) const {
  111. return Bits != RHS.Bits;
  112. }
  113. const PackedVector &operator=(const PackedVector &RHS) {
  114. Bits = RHS.Bits;
  115. return *this;
  116. }
  117. PackedVector &operator|=(const PackedVector &RHS) {
  118. Bits |= RHS.Bits;
  119. return *this;
  120. }
  121. void swap(PackedVector &RHS) {
  122. Bits.swap(RHS.Bits);
  123. }
  124. };
  125. // Leave BitNum=0 undefined.
  126. template <typename T>
  127. class PackedVector<T, 0>;
  128. } // end llvm namespace
  129. #endif