LLVM API Documentation
00001 //===- llvm/ADT/PackedVector.h - Packed values vector -----------*- C++ -*-===// 00002 // 00003 // The LLVM Compiler Infrastructure 00004 // 00005 // This file is distributed under the University of Illinois Open Source 00006 // License. See LICENSE.TXT for details. 00007 // 00008 //===----------------------------------------------------------------------===// 00009 // 00010 // This file implements the PackedVector class. 00011 // 00012 //===----------------------------------------------------------------------===// 00013 00014 #ifndef LLVM_ADT_PACKEDVECTOR_H 00015 #define LLVM_ADT_PACKEDVECTOR_H 00016 00017 #include "llvm/ADT/BitVector.h" 00018 #include <limits> 00019 00020 namespace llvm { 00021 00022 template <typename T, unsigned BitNum, typename BitVectorTy, bool isSigned> 00023 class PackedVectorBase; 00024 00025 // This won't be necessary if we can specialize members without specializing 00026 // the parent template. 00027 template <typename T, unsigned BitNum, typename BitVectorTy> 00028 class PackedVectorBase<T, BitNum, BitVectorTy, false> { 00029 protected: 00030 static T getValue(const BitVectorTy &Bits, unsigned Idx) { 00031 T val = T(); 00032 for (unsigned i = 0; i != BitNum; ++i) 00033 val = T(val | ((Bits[(Idx << (BitNum-1)) + i] ? 1UL : 0UL) << i)); 00034 return val; 00035 } 00036 00037 static void setValue(BitVectorTy &Bits, unsigned Idx, T val) { 00038 assert((val >> BitNum) == 0 && "value is too big"); 00039 for (unsigned i = 0; i != BitNum; ++i) 00040 Bits[(Idx << (BitNum-1)) + i] = val & (T(1) << i); 00041 } 00042 }; 00043 00044 template <typename T, unsigned BitNum, typename BitVectorTy> 00045 class PackedVectorBase<T, BitNum, BitVectorTy, true> { 00046 protected: 00047 static T getValue(const BitVectorTy &Bits, unsigned Idx) { 00048 T val = T(); 00049 for (unsigned i = 0; i != BitNum-1; ++i) 00050 val = T(val | ((Bits[(Idx << (BitNum-1)) + i] ? 1UL : 0UL) << i)); 00051 if (Bits[(Idx << (BitNum-1)) + BitNum-1]) 00052 val = ~val; 00053 return val; 00054 } 00055 00056 static void setValue(BitVectorTy &Bits, unsigned Idx, T val) { 00057 if (val < 0) { 00058 val = ~val; 00059 Bits.set((Idx << (BitNum-1)) + BitNum-1); 00060 } 00061 assert((val >> (BitNum-1)) == 0 && "value is too big"); 00062 for (unsigned i = 0; i != BitNum-1; ++i) 00063 Bits[(Idx << (BitNum-1)) + i] = val & (T(1) << i); 00064 } 00065 }; 00066 00067 /// \brief Store a vector of values using a specific number of bits for each 00068 /// value. Both signed and unsigned types can be used, e.g 00069 /// @code 00070 /// PackedVector<signed, 2> vec; 00071 /// @endcode 00072 /// will create a vector accepting values -2, -1, 0, 1. Any other value will hit 00073 /// an assertion. 00074 template <typename T, unsigned BitNum, typename BitVectorTy = BitVector> 00075 class PackedVector : public PackedVectorBase<T, BitNum, BitVectorTy, 00076 std::numeric_limits<T>::is_signed> { 00077 BitVectorTy Bits; 00078 typedef PackedVectorBase<T, BitNum, BitVectorTy, 00079 std::numeric_limits<T>::is_signed> base; 00080 00081 public: 00082 class reference { 00083 PackedVector &Vec; 00084 const unsigned Idx; 00085 00086 reference(); // Undefined 00087 public: 00088 reference(PackedVector &vec, unsigned idx) : Vec(vec), Idx(idx) { } 00089 00090 reference &operator=(T val) { 00091 Vec.setValue(Vec.Bits, Idx, val); 00092 return *this; 00093 } 00094 operator T() const { 00095 return Vec.getValue(Vec.Bits, Idx); 00096 } 00097 }; 00098 00099 PackedVector() { } 00100 explicit PackedVector(unsigned size) : Bits(size << (BitNum-1)) { } 00101 00102 bool empty() const { return Bits.empty(); } 00103 00104 unsigned size() const { return Bits.size() >> (BitNum-1); } 00105 00106 void clear() { Bits.clear(); } 00107 00108 void resize(unsigned N) { Bits.resize(N << (BitNum-1)); } 00109 00110 void reserve(unsigned N) { Bits.reserve(N << (BitNum-1)); } 00111 00112 PackedVector &reset() { 00113 Bits.reset(); 00114 return *this; 00115 } 00116 00117 void push_back(T val) { 00118 resize(size()+1); 00119 (*this)[size()-1] = val; 00120 } 00121 00122 reference operator[](unsigned Idx) { 00123 return reference(*this, Idx); 00124 } 00125 00126 T operator[](unsigned Idx) const { 00127 return base::getValue(Bits, Idx); 00128 } 00129 00130 bool operator==(const PackedVector &RHS) const { 00131 return Bits == RHS.Bits; 00132 } 00133 00134 bool operator!=(const PackedVector &RHS) const { 00135 return Bits != RHS.Bits; 00136 } 00137 00138 const PackedVector &operator=(const PackedVector &RHS) { 00139 Bits = RHS.Bits; 00140 return *this; 00141 } 00142 00143 PackedVector &operator|=(const PackedVector &RHS) { 00144 Bits |= RHS.Bits; 00145 return *this; 00146 } 00147 00148 void swap(PackedVector &RHS) { 00149 Bits.swap(RHS.Bits); 00150 } 00151 }; 00152 00153 // Leave BitNum=0 undefined. 00154 template <typename T> 00155 class PackedVector<T, 0>; 00156 00157 } // end llvm namespace 00158 00159 #endif