1 //===- llvm/ADT/TinyPtrVector.h - 'Normally tiny' vectors -------*- 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 #ifndef LLVM_ADT_TINYPTRVECTOR_H 11 #define LLVM_ADT_TINYPTRVECTOR_H 12 13 #include "llvm/ADT/SmallVector.h" 14 #include "llvm/ADT/PointerUnion.h" 15 16 namespace llvm { 17 18 /// TinyPtrVector - This class is specialized for cases where there are 19 /// normally 0 or 1 element in a vector, but is general enough to go beyond that 20 /// when required. 21 /// 22 /// NOTE: This container doesn't allow you to store a null pointer into it. 23 /// 24 template <typename EltTy> 25 class TinyPtrVector { 26 public: 27 typedef llvm::SmallVector<EltTy, 4> VecTy; 28 llvm::PointerUnion<EltTy, VecTy*> Val; 29 30 TinyPtrVector() {} 31 TinyPtrVector(const TinyPtrVector &RHS) : Val(RHS.Val) { 32 if (VecTy *V = Val.template dyn_cast<VecTy*>()) 33 Val = new VecTy(*V); 34 } 35 ~TinyPtrVector() { 36 if (VecTy *V = Val.template dyn_cast<VecTy*>()) 37 delete V; 38 } 39 40 bool empty() const { 41 // This vector can be empty if it contains no element, or if it 42 // contains a pointer to an empty vector. 43 if (Val.isNull()) return true; 44 if (VecTy *Vec = Val.template dyn_cast<VecTy*>()) 45 return Vec->empty(); 46 return false; 47 } 48 49 unsigned size() const { 50 if (empty()) 51 return 0; 52 if (Val.template is<EltTy>()) 53 return 1; 54 return Val.template get<VecTy*>()->size(); 55 } 56 57 typedef const EltTy *iterator; 58 iterator begin() const { 59 if (empty()) 60 return 0; 61 62 if (Val.template is<EltTy>()) 63 return Val.template getAddrOf<EltTy>(); 64 65 return Val.template get<VecTy *>()->begin(); 66 67 } 68 iterator end() const { 69 if (empty()) 70 return 0; 71 72 if (Val.template is<EltTy>()) 73 return begin() + 1; 74 75 return Val.template get<VecTy *>()->end(); 76 } 77 78 79 EltTy operator[](unsigned i) const { 80 assert(!Val.isNull() && "can't index into an empty vector"); 81 if (EltTy V = Val.template dyn_cast<EltTy>()) { 82 assert(i == 0 && "tinyvector index out of range"); 83 return V; 84 } 85 86 assert(i < Val.template get<VecTy*>()->size() && 87 "tinyvector index out of range"); 88 return (*Val.template get<VecTy*>())[i]; 89 } 90 91 EltTy front() const { 92 assert(!empty() && "vector empty"); 93 if (EltTy V = Val.template dyn_cast<EltTy>()) 94 return V; 95 return Val.template get<VecTy*>()->front(); 96 } 97 98 void push_back(EltTy NewVal) { 99 assert(NewVal != 0 && "Can't add a null value"); 100 101 // If we have nothing, add something. 102 if (Val.isNull()) { 103 Val = NewVal; 104 return; 105 } 106 107 // If we have a single value, convert to a vector. 108 if (EltTy V = Val.template dyn_cast<EltTy>()) { 109 Val = new VecTy(); 110 Val.template get<VecTy*>()->push_back(V); 111 } 112 113 // Add the new value, we know we have a vector. 114 Val.template get<VecTy*>()->push_back(NewVal); 115 } 116 117 void clear() { 118 // If we have a single value, convert to empty. 119 if (Val.template is<EltTy>()) { 120 Val = (EltTy)0; 121 } else if (VecTy *Vec = Val.template dyn_cast<VecTy*>()) { 122 // If we have a vector form, just clear it. 123 Vec->clear(); 124 } 125 // Otherwise, we're already empty. 126 } 127 128 private: 129 void operator=(const TinyPtrVector&); // NOT IMPLEMENTED YET. 130 }; 131 } // end namespace llvm 132 133 #endif 134