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 16namespace 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/// 24template <typename EltTy> 25class TinyPtrVector { 26public: 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
| 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 16namespace 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/// 24template <typename EltTy> 25class TinyPtrVector { 26public: 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 // implicit conversion operator to ArrayRef. 41 operator ArrayRef<EltTy>() const { 42 if (Val.isNull()) 43 return ArrayRef<EltTy>(); 44 if (Val.template is<EltTy>()) 45 return *Val.getAddrOfPtr1(); 46 return *Val.template get<VecTy*>(); 47 } 48
|
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
| 49 bool empty() const { 50 // This vector can be empty if it contains no element, or if it 51 // contains a pointer to an empty vector. 52 if (Val.isNull()) return true; 53 if (VecTy *Vec = Val.template dyn_cast<VecTy*>()) 54 return Vec->empty(); 55 return false; 56 } 57 58 unsigned size() const { 59 if (empty()) 60 return 0; 61 if (Val.template is<EltTy>()) 62 return 1; 63 return Val.template get<VecTy*>()->size(); 64 } 65
|
57 typedef const EltTy *iterator; 58 iterator begin() const {
| 66 typedef const EltTy *const_iterator; 67 typedef EltTy *iterator; 68 69 iterator begin() {
|
59 if (empty()) 60 return 0; 61 62 if (Val.template is<EltTy>())
| 70 if (empty()) 71 return 0; 72 73 if (Val.template is<EltTy>())
|
63 return Val.template getAddrOf<EltTy>();
| 74 return Val.getAddrOfPtr1();
|
64 65 return Val.template get<VecTy *>()->begin(); 66 67 }
| 75 76 return Val.template get<VecTy *>()->begin(); 77 78 }
|
68 iterator end() const {
| 79 iterator end() {
|
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
| 80 if (empty()) 81 return 0; 82 83 if (Val.template is<EltTy>()) 84 return begin() + 1; 85 86 return Val.template get<VecTy *>()->end(); 87 } 88
|
78
| 89 const_iterator begin() const { 90 return (const_iterator)const_cast<TinyPtrVector*>(this)->begin(); 91 } 92 93 const_iterator end() const { 94 return (const_iterator)const_cast<TinyPtrVector*>(this)->end(); 95 } 96
|
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 }
| 97 EltTy operator[](unsigned i) const { 98 assert(!Val.isNull() && "can't index into an empty vector"); 99 if (EltTy V = Val.template dyn_cast<EltTy>()) { 100 assert(i == 0 && "tinyvector index out of range"); 101 return V; 102 } 103 104 assert(i < Val.template get<VecTy*>()->size() && 105 "tinyvector index out of range"); 106 return (*Val.template get<VecTy*>())[i]; 107 } 108 109 EltTy front() const { 110 assert(!empty() && "vector empty"); 111 if (EltTy V = Val.template dyn_cast<EltTy>()) 112 return V; 113 return Val.template get<VecTy*>()->front(); 114 } 115 116 void push_back(EltTy NewVal) { 117 assert(NewVal != 0 && "Can't add a null value"); 118 119 // If we have nothing, add something. 120 if (Val.isNull()) { 121 Val = NewVal; 122 return; 123 } 124 125 // If we have a single value, convert to a vector. 126 if (EltTy V = Val.template dyn_cast<EltTy>()) { 127 Val = new VecTy(); 128 Val.template get<VecTy*>()->push_back(V); 129 } 130 131 // Add the new value, we know we have a vector. 132 Val.template get<VecTy*>()->push_back(NewVal); 133 } 134 135 void clear() { 136 // If we have a single value, convert to empty. 137 if (Val.template is<EltTy>()) { 138 Val = (EltTy)0; 139 } else if (VecTy *Vec = Val.template dyn_cast<VecTy*>()) { 140 // If we have a vector form, just clear it. 141 Vec->clear(); 142 } 143 // Otherwise, we're already empty. 144 }
|
| 145 146 iterator erase(iterator I) { 147 // If we have a single value, convert to empty. 148 if (Val.template is<EltTy>()) { 149 if (I == begin()) 150 Val = (EltTy)0; 151 } else if (VecTy *Vec = Val.template dyn_cast<VecTy*>()) { 152 // multiple items in a vector; just do the erase, there is no 153 // benefit to collapsing back to a pointer 154 return Vec->erase(I); 155 } 156 157 return 0; 158 }
|
127 128private: 129 void operator=(const TinyPtrVector&); // NOT IMPLEMENTED YET. 130}; 131} // end namespace llvm 132 133#endif
| 159 160private: 161 void operator=(const TinyPtrVector&); // NOT IMPLEMENTED YET. 162}; 163} // end namespace llvm 164 165#endif
|