TinyPtrVector.h 8.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307
  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. #ifndef LLVM_ADT_TINYPTRVECTOR_H
  10. #define LLVM_ADT_TINYPTRVECTOR_H
  11. #include "llvm/ADT/ArrayRef.h"
  12. #include "llvm/ADT/PointerUnion.h"
  13. #include "llvm/ADT/SmallVector.h"
  14. namespace llvm {
  15. /// TinyPtrVector - This class is specialized for cases where there are
  16. /// normally 0 or 1 element in a vector, but is general enough to go beyond that
  17. /// when required.
  18. ///
  19. /// NOTE: This container doesn't allow you to store a null pointer into it.
  20. ///
  21. template <typename EltTy>
  22. class TinyPtrVector {
  23. public:
  24. typedef llvm::SmallVector<EltTy, 4> VecTy;
  25. typedef typename VecTy::value_type value_type;
  26. typedef llvm::PointerUnion<EltTy, VecTy *> PtrUnion;
  27. private:
  28. PtrUnion Val;
  29. public:
  30. TinyPtrVector() {}
  31. ~TinyPtrVector() {
  32. if (VecTy *V = Val.template dyn_cast<VecTy*>())
  33. delete V;
  34. }
  35. TinyPtrVector(const TinyPtrVector &RHS) : Val(RHS.Val) {
  36. if (VecTy *V = Val.template dyn_cast<VecTy*>())
  37. Val = new VecTy(*V);
  38. }
  39. TinyPtrVector &operator=(const TinyPtrVector &RHS) {
  40. if (this == &RHS)
  41. return *this;
  42. if (RHS.empty()) {
  43. this->clear();
  44. return *this;
  45. }
  46. // Try to squeeze into the single slot. If it won't fit, allocate a copied
  47. // vector.
  48. if (Val.template is<EltTy>()) {
  49. if (RHS.size() == 1)
  50. Val = RHS.front();
  51. else
  52. Val = new VecTy(*RHS.Val.template get<VecTy*>());
  53. return *this;
  54. }
  55. // If we have a full vector allocated, try to re-use it.
  56. if (RHS.Val.template is<EltTy>()) {
  57. Val.template get<VecTy*>()->clear();
  58. Val.template get<VecTy*>()->push_back(RHS.front());
  59. } else {
  60. *Val.template get<VecTy*>() = *RHS.Val.template get<VecTy*>();
  61. }
  62. return *this;
  63. }
  64. TinyPtrVector(TinyPtrVector &&RHS) : Val(RHS.Val) {
  65. RHS.Val = (EltTy)nullptr;
  66. }
  67. TinyPtrVector &operator=(TinyPtrVector &&RHS) {
  68. if (this == &RHS)
  69. return *this;
  70. if (RHS.empty()) {
  71. this->clear();
  72. return *this;
  73. }
  74. // If this vector has been allocated on the heap, re-use it if cheap. If it
  75. // would require more copying, just delete it and we'll steal the other
  76. // side.
  77. if (VecTy *V = Val.template dyn_cast<VecTy*>()) {
  78. if (RHS.Val.template is<EltTy>()) {
  79. V->clear();
  80. V->push_back(RHS.front());
  81. return *this;
  82. }
  83. delete V;
  84. }
  85. Val = RHS.Val;
  86. RHS.Val = (EltTy)nullptr;
  87. return *this;
  88. }
  89. /// Constructor from an ArrayRef.
  90. ///
  91. /// This also is a constructor for individual array elements due to the single
  92. /// element constructor for ArrayRef.
  93. explicit TinyPtrVector(ArrayRef<EltTy> Elts)
  94. : Val(Elts.size() == 1 ? PtrUnion(Elts[0])
  95. : PtrUnion(new VecTy(Elts.begin(), Elts.end()))) {}
  96. // implicit conversion operator to ArrayRef.
  97. operator ArrayRef<EltTy>() const {
  98. if (Val.isNull())
  99. return None;
  100. if (Val.template is<EltTy>())
  101. return *Val.getAddrOfPtr1();
  102. return *Val.template get<VecTy*>();
  103. }
  104. // implicit conversion operator to MutableArrayRef.
  105. operator MutableArrayRef<EltTy>() {
  106. if (Val.isNull())
  107. return None;
  108. if (Val.template is<EltTy>())
  109. return *Val.getAddrOfPtr1();
  110. return *Val.template get<VecTy*>();
  111. }
  112. bool empty() const {
  113. // This vector can be empty if it contains no element, or if it
  114. // contains a pointer to an empty vector.
  115. if (Val.isNull()) return true;
  116. if (VecTy *Vec = Val.template dyn_cast<VecTy*>())
  117. return Vec->empty();
  118. return false;
  119. }
  120. unsigned size() const {
  121. if (empty())
  122. return 0;
  123. if (Val.template is<EltTy>())
  124. return 1;
  125. return Val.template get<VecTy*>()->size();
  126. }
  127. typedef const EltTy *const_iterator;
  128. typedef EltTy *iterator;
  129. iterator begin() {
  130. if (Val.template is<EltTy>())
  131. return Val.getAddrOfPtr1();
  132. return Val.template get<VecTy *>()->begin();
  133. }
  134. iterator end() {
  135. if (Val.template is<EltTy>())
  136. return begin() + (Val.isNull() ? 0 : 1);
  137. return Val.template get<VecTy *>()->end();
  138. }
  139. const_iterator begin() const {
  140. return (const_iterator)const_cast<TinyPtrVector*>(this)->begin();
  141. }
  142. const_iterator end() const {
  143. return (const_iterator)const_cast<TinyPtrVector*>(this)->end();
  144. }
  145. EltTy operator[](unsigned i) const {
  146. assert(!Val.isNull() && "can't index into an empty vector");
  147. if (EltTy V = Val.template dyn_cast<EltTy>()) {
  148. assert(i == 0 && "tinyvector index out of range");
  149. return V;
  150. }
  151. assert(i < Val.template get<VecTy*>()->size() &&
  152. "tinyvector index out of range");
  153. return (*Val.template get<VecTy*>())[i];
  154. }
  155. EltTy front() const {
  156. assert(!empty() && "vector empty");
  157. if (EltTy V = Val.template dyn_cast<EltTy>())
  158. return V;
  159. return Val.template get<VecTy*>()->front();
  160. }
  161. EltTy back() const {
  162. assert(!empty() && "vector empty");
  163. if (EltTy V = Val.template dyn_cast<EltTy>())
  164. return V;
  165. return Val.template get<VecTy*>()->back();
  166. }
  167. void push_back(EltTy NewVal) {
  168. assert(NewVal && "Can't add a null value");
  169. // If we have nothing, add something.
  170. if (Val.isNull()) {
  171. Val = NewVal;
  172. return;
  173. }
  174. // If we have a single value, convert to a vector.
  175. if (EltTy V = Val.template dyn_cast<EltTy>()) {
  176. Val = new VecTy();
  177. Val.template get<VecTy*>()->push_back(V);
  178. }
  179. // Add the new value, we know we have a vector.
  180. Val.template get<VecTy*>()->push_back(NewVal);
  181. }
  182. void pop_back() {
  183. // If we have a single value, convert to empty.
  184. if (Val.template is<EltTy>())
  185. Val = (EltTy)nullptr;
  186. else if (VecTy *Vec = Val.template get<VecTy*>())
  187. Vec->pop_back();
  188. }
  189. void clear() {
  190. // If we have a single value, convert to empty.
  191. if (Val.template is<EltTy>()) {
  192. Val = (EltTy)nullptr;
  193. } else if (VecTy *Vec = Val.template dyn_cast<VecTy*>()) {
  194. // If we have a vector form, just clear it.
  195. Vec->clear();
  196. }
  197. // Otherwise, we're already empty.
  198. }
  199. iterator erase(iterator I) {
  200. assert(I >= begin() && "Iterator to erase is out of bounds.");
  201. assert(I < end() && "Erasing at past-the-end iterator.");
  202. // If we have a single value, convert to empty.
  203. if (Val.template is<EltTy>()) {
  204. if (I == begin())
  205. Val = (EltTy)nullptr;
  206. } else if (VecTy *Vec = Val.template dyn_cast<VecTy*>()) {
  207. // multiple items in a vector; just do the erase, there is no
  208. // benefit to collapsing back to a pointer
  209. return Vec->erase(I);
  210. }
  211. return end();
  212. }
  213. iterator erase(iterator S, iterator E) {
  214. assert(S >= begin() && "Range to erase is out of bounds.");
  215. assert(S <= E && "Trying to erase invalid range.");
  216. assert(E <= end() && "Trying to erase past the end.");
  217. if (Val.template is<EltTy>()) {
  218. if (S == begin() && S != E)
  219. Val = (EltTy)nullptr;
  220. } else if (VecTy *Vec = Val.template dyn_cast<VecTy*>()) {
  221. return Vec->erase(S, E);
  222. }
  223. return end();
  224. }
  225. iterator insert(iterator I, const EltTy &Elt) {
  226. assert(I >= this->begin() && "Insertion iterator is out of bounds.");
  227. assert(I <= this->end() && "Inserting past the end of the vector.");
  228. if (I == end()) {
  229. push_back(Elt);
  230. return std::prev(end());
  231. }
  232. assert(!Val.isNull() && "Null value with non-end insert iterator.");
  233. if (EltTy V = Val.template dyn_cast<EltTy>()) {
  234. assert(I == begin());
  235. Val = Elt;
  236. push_back(V);
  237. return begin();
  238. }
  239. return Val.template get<VecTy*>()->insert(I, Elt);
  240. }
  241. template<typename ItTy>
  242. iterator insert(iterator I, ItTy From, ItTy To) {
  243. assert(I >= this->begin() && "Insertion iterator is out of bounds.");
  244. assert(I <= this->end() && "Inserting past the end of the vector.");
  245. if (From == To)
  246. return I;
  247. // If we have a single value, convert to a vector.
  248. ptrdiff_t Offset = I - begin();
  249. if (Val.isNull()) {
  250. if (std::next(From) == To) {
  251. Val = *From;
  252. return begin();
  253. }
  254. Val = new VecTy();
  255. } else if (EltTy V = Val.template dyn_cast<EltTy>()) {
  256. Val = new VecTy();
  257. Val.template get<VecTy*>()->push_back(V);
  258. }
  259. return Val.template get<VecTy*>()->insert(begin() + Offset, From, To);
  260. }
  261. };
  262. } // end namespace llvm
  263. #endif