LLVM API Documentation
00001 //===- llvm/ADT/TinyPtrVector.h - 'Normally tiny' vectors -------*- 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 #ifndef LLVM_ADT_TINYPTRVECTOR_H 00011 #define LLVM_ADT_TINYPTRVECTOR_H 00012 00013 #include "llvm/ADT/ArrayRef.h" 00014 #include "llvm/ADT/PointerUnion.h" 00015 #include "llvm/ADT/STLExtras.h" 00016 #include "llvm/ADT/SmallVector.h" 00017 #include "llvm/Support/Compiler.h" 00018 00019 namespace llvm { 00020 00021 /// TinyPtrVector - This class is specialized for cases where there are 00022 /// normally 0 or 1 element in a vector, but is general enough to go beyond that 00023 /// when required. 00024 /// 00025 /// NOTE: This container doesn't allow you to store a null pointer into it. 00026 /// 00027 template <typename EltTy> 00028 class TinyPtrVector { 00029 public: 00030 typedef llvm::SmallVector<EltTy, 4> VecTy; 00031 typedef typename VecTy::value_type value_type; 00032 00033 llvm::PointerUnion<EltTy, VecTy*> Val; 00034 00035 TinyPtrVector() {} 00036 ~TinyPtrVector() { 00037 if (VecTy *V = Val.template dyn_cast<VecTy*>()) 00038 delete V; 00039 } 00040 00041 TinyPtrVector(const TinyPtrVector &RHS) : Val(RHS.Val) { 00042 if (VecTy *V = Val.template dyn_cast<VecTy*>()) 00043 Val = new VecTy(*V); 00044 } 00045 TinyPtrVector &operator=(const TinyPtrVector &RHS) { 00046 if (this == &RHS) 00047 return *this; 00048 if (RHS.empty()) { 00049 this->clear(); 00050 return *this; 00051 } 00052 00053 // Try to squeeze into the single slot. If it won't fit, allocate a copied 00054 // vector. 00055 if (Val.template is<EltTy>()) { 00056 if (RHS.size() == 1) 00057 Val = RHS.front(); 00058 else 00059 Val = new VecTy(*RHS.Val.template get<VecTy*>()); 00060 return *this; 00061 } 00062 00063 // If we have a full vector allocated, try to re-use it. 00064 if (RHS.Val.template is<EltTy>()) { 00065 Val.template get<VecTy*>()->clear(); 00066 Val.template get<VecTy*>()->push_back(RHS.front()); 00067 } else { 00068 *Val.template get<VecTy*>() = *RHS.Val.template get<VecTy*>(); 00069 } 00070 return *this; 00071 } 00072 00073 #if LLVM_HAS_RVALUE_REFERENCES 00074 TinyPtrVector(TinyPtrVector &&RHS) : Val(RHS.Val) { 00075 RHS.Val = (EltTy)0; 00076 } 00077 TinyPtrVector &operator=(TinyPtrVector &&RHS) { 00078 if (this == &RHS) 00079 return *this; 00080 if (RHS.empty()) { 00081 this->clear(); 00082 return *this; 00083 } 00084 00085 // If this vector has been allocated on the heap, re-use it if cheap. If it 00086 // would require more copying, just delete it and we'll steal the other 00087 // side. 00088 if (VecTy *V = Val.template dyn_cast<VecTy*>()) { 00089 if (RHS.Val.template is<EltTy>()) { 00090 V->clear(); 00091 V->push_back(RHS.front()); 00092 return *this; 00093 } 00094 delete V; 00095 } 00096 00097 Val = RHS.Val; 00098 RHS.Val = (EltTy)0; 00099 return *this; 00100 } 00101 #endif 00102 00103 // implicit conversion operator to ArrayRef. 00104 operator ArrayRef<EltTy>() const { 00105 if (Val.isNull()) 00106 return ArrayRef<EltTy>(); 00107 if (Val.template is<EltTy>()) 00108 return *Val.getAddrOfPtr1(); 00109 return *Val.template get<VecTy*>(); 00110 } 00111 00112 bool empty() const { 00113 // This vector can be empty if it contains no element, or if it 00114 // contains a pointer to an empty vector. 00115 if (Val.isNull()) return true; 00116 if (VecTy *Vec = Val.template dyn_cast<VecTy*>()) 00117 return Vec->empty(); 00118 return false; 00119 } 00120 00121 unsigned size() const { 00122 if (empty()) 00123 return 0; 00124 if (Val.template is<EltTy>()) 00125 return 1; 00126 return Val.template get<VecTy*>()->size(); 00127 } 00128 00129 typedef const EltTy *const_iterator; 00130 typedef EltTy *iterator; 00131 00132 iterator begin() { 00133 if (Val.template is<EltTy>()) 00134 return Val.getAddrOfPtr1(); 00135 00136 return Val.template get<VecTy *>()->begin(); 00137 00138 } 00139 iterator end() { 00140 if (Val.template is<EltTy>()) 00141 return begin() + (Val.isNull() ? 0 : 1); 00142 00143 return Val.template get<VecTy *>()->end(); 00144 } 00145 00146 const_iterator begin() const { 00147 return (const_iterator)const_cast<TinyPtrVector*>(this)->begin(); 00148 } 00149 00150 const_iterator end() const { 00151 return (const_iterator)const_cast<TinyPtrVector*>(this)->end(); 00152 } 00153 00154 EltTy operator[](unsigned i) const { 00155 assert(!Val.isNull() && "can't index into an empty vector"); 00156 if (EltTy V = Val.template dyn_cast<EltTy>()) { 00157 assert(i == 0 && "tinyvector index out of range"); 00158 return V; 00159 } 00160 00161 assert(i < Val.template get<VecTy*>()->size() && 00162 "tinyvector index out of range"); 00163 return (*Val.template get<VecTy*>())[i]; 00164 } 00165 00166 EltTy front() const { 00167 assert(!empty() && "vector empty"); 00168 if (EltTy V = Val.template dyn_cast<EltTy>()) 00169 return V; 00170 return Val.template get<VecTy*>()->front(); 00171 } 00172 00173 EltTy back() const { 00174 assert(!empty() && "vector empty"); 00175 if (EltTy V = Val.template dyn_cast<EltTy>()) 00176 return V; 00177 return Val.template get<VecTy*>()->back(); 00178 } 00179 00180 void push_back(EltTy NewVal) { 00181 assert(NewVal != 0 && "Can't add a null value"); 00182 00183 // If we have nothing, add something. 00184 if (Val.isNull()) { 00185 Val = NewVal; 00186 return; 00187 } 00188 00189 // If we have a single value, convert to a vector. 00190 if (EltTy V = Val.template dyn_cast<EltTy>()) { 00191 Val = new VecTy(); 00192 Val.template get<VecTy*>()->push_back(V); 00193 } 00194 00195 // Add the new value, we know we have a vector. 00196 Val.template get<VecTy*>()->push_back(NewVal); 00197 } 00198 00199 void pop_back() { 00200 // If we have a single value, convert to empty. 00201 if (Val.template is<EltTy>()) 00202 Val = (EltTy)0; 00203 else if (VecTy *Vec = Val.template get<VecTy*>()) 00204 Vec->pop_back(); 00205 } 00206 00207 void clear() { 00208 // If we have a single value, convert to empty. 00209 if (Val.template is<EltTy>()) { 00210 Val = (EltTy)0; 00211 } else if (VecTy *Vec = Val.template dyn_cast<VecTy*>()) { 00212 // If we have a vector form, just clear it. 00213 Vec->clear(); 00214 } 00215 // Otherwise, we're already empty. 00216 } 00217 00218 iterator erase(iterator I) { 00219 assert(I >= begin() && "Iterator to erase is out of bounds."); 00220 assert(I < end() && "Erasing at past-the-end iterator."); 00221 00222 // If we have a single value, convert to empty. 00223 if (Val.template is<EltTy>()) { 00224 if (I == begin()) 00225 Val = (EltTy)0; 00226 } else if (VecTy *Vec = Val.template dyn_cast<VecTy*>()) { 00227 // multiple items in a vector; just do the erase, there is no 00228 // benefit to collapsing back to a pointer 00229 return Vec->erase(I); 00230 } 00231 return end(); 00232 } 00233 00234 iterator erase(iterator S, iterator E) { 00235 assert(S >= begin() && "Range to erase is out of bounds."); 00236 assert(S <= E && "Trying to erase invalid range."); 00237 assert(E <= end() && "Trying to erase past the end."); 00238 00239 if (Val.template is<EltTy>()) { 00240 if (S == begin() && S != E) 00241 Val = (EltTy)0; 00242 } else if (VecTy *Vec = Val.template dyn_cast<VecTy*>()) { 00243 return Vec->erase(S, E); 00244 } 00245 return end(); 00246 } 00247 00248 iterator insert(iterator I, const EltTy &Elt) { 00249 assert(I >= this->begin() && "Insertion iterator is out of bounds."); 00250 assert(I <= this->end() && "Inserting past the end of the vector."); 00251 if (I == end()) { 00252 push_back(Elt); 00253 return llvm::prior(end()); 00254 } 00255 assert(!Val.isNull() && "Null value with non-end insert iterator."); 00256 if (EltTy V = Val.template dyn_cast<EltTy>()) { 00257 assert(I == begin()); 00258 Val = Elt; 00259 push_back(V); 00260 return begin(); 00261 } 00262 00263 return Val.template get<VecTy*>()->insert(I, Elt); 00264 } 00265 00266 template<typename ItTy> 00267 iterator insert(iterator I, ItTy From, ItTy To) { 00268 assert(I >= this->begin() && "Insertion iterator is out of bounds."); 00269 assert(I <= this->end() && "Inserting past the end of the vector."); 00270 if (From == To) 00271 return I; 00272 00273 // If we have a single value, convert to a vector. 00274 ptrdiff_t Offset = I - begin(); 00275 if (Val.isNull()) { 00276 if (llvm::next(From) == To) { 00277 Val = *From; 00278 return begin(); 00279 } 00280 00281 Val = new VecTy(); 00282 } else if (EltTy V = Val.template dyn_cast<EltTy>()) { 00283 Val = new VecTy(); 00284 Val.template get<VecTy*>()->push_back(V); 00285 } 00286 return Val.template get<VecTy*>()->insert(begin() + Offset, From, To); 00287 } 00288 }; 00289 } // end namespace llvm 00290 00291 #endif