1 //===- llvm/ADT/TinyPtrVector.h - 'Normally tiny' vectors -------*- C++ -*-===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 #ifndef LLVM_ADT_TINYPTRVECTOR_H
11 #define LLVM_ADT_TINYPTRVECTOR_H
13 #include "llvm/ADT/ArrayRef.h"
14 #include "llvm/ADT/SmallVector.h"
15 #include "llvm/ADT/PointerUnion.h"
16 #include "llvm/Support/Compiler.h"
20 /// TinyPtrVector - This class is specialized for cases where there are
21 /// normally 0 or 1 element in a vector, but is general enough to go beyond that
24 /// NOTE: This container doesn't allow you to store a null pointer into it.
26 template <typename EltTy>
29 typedef llvm::SmallVector<EltTy, 4> VecTy;
30 typedef typename VecTy::value_type value_type;
32 llvm::PointerUnion<EltTy, VecTy*> Val;
35 TinyPtrVector(const TinyPtrVector &RHS) : Val(RHS.Val) {
36 if (VecTy *V = Val.template dyn_cast<VecTy*>())
39 #if LLVM_USE_RVALUE_REFERENCES
40 TinyPtrVector(TinyPtrVector &&RHS) : Val(RHS.Val) {
45 if (VecTy *V = Val.template dyn_cast<VecTy*>())
49 // implicit conversion operator to ArrayRef.
50 operator ArrayRef<EltTy>() const {
52 return ArrayRef<EltTy>();
53 if (Val.template is<EltTy>())
54 return *Val.getAddrOfPtr1();
55 return *Val.template get<VecTy*>();
59 // This vector can be empty if it contains no element, or if it
60 // contains a pointer to an empty vector.
61 if (Val.isNull()) return true;
62 if (VecTy *Vec = Val.template dyn_cast<VecTy*>())
67 unsigned size() const {
70 if (Val.template is<EltTy>())
72 return Val.template get<VecTy*>()->size();
75 typedef const EltTy *const_iterator;
76 typedef EltTy *iterator;
79 if (Val.template is<EltTy>())
80 return Val.getAddrOfPtr1();
82 return Val.template get<VecTy *>()->begin();
86 if (Val.template is<EltTy>())
87 return begin() + (Val.isNull() ? 0 : 1);
89 return Val.template get<VecTy *>()->end();
92 const_iterator begin() const {
93 return (const_iterator)const_cast<TinyPtrVector*>(this)->begin();
96 const_iterator end() const {
97 return (const_iterator)const_cast<TinyPtrVector*>(this)->end();
100 EltTy operator[](unsigned i) const {
101 assert(!Val.isNull() && "can't index into an empty vector");
102 if (EltTy V = Val.template dyn_cast<EltTy>()) {
103 assert(i == 0 && "tinyvector index out of range");
107 assert(i < Val.template get<VecTy*>()->size() &&
108 "tinyvector index out of range");
109 return (*Val.template get<VecTy*>())[i];
112 EltTy front() const {
113 assert(!empty() && "vector empty");
114 if (EltTy V = Val.template dyn_cast<EltTy>())
116 return Val.template get<VecTy*>()->front();
120 assert(!empty() && "vector empty");
121 if (EltTy V = Val.template dyn_cast<EltTy>())
123 return Val.template get<VecTy*>()->back();
126 void push_back(EltTy NewVal) {
127 assert(NewVal != 0 && "Can't add a null value");
129 // If we have nothing, add something.
135 // If we have a single value, convert to a vector.
136 if (EltTy V = Val.template dyn_cast<EltTy>()) {
138 Val.template get<VecTy*>()->push_back(V);
141 // Add the new value, we know we have a vector.
142 Val.template get<VecTy*>()->push_back(NewVal);
146 // If we have a single value, convert to empty.
147 if (Val.template is<EltTy>())
149 else if (VecTy *Vec = Val.template get<VecTy*>())
154 // If we have a single value, convert to empty.
155 if (Val.template is<EltTy>()) {
157 } else if (VecTy *Vec = Val.template dyn_cast<VecTy*>()) {
158 // If we have a vector form, just clear it.
161 // Otherwise, we're already empty.
164 iterator erase(iterator I) {
165 // If we have a single value, convert to empty.
166 if (Val.template is<EltTy>()) {
169 } else if (VecTy *Vec = Val.template dyn_cast<VecTy*>()) {
170 // multiple items in a vector; just do the erase, there is no
171 // benefit to collapsing back to a pointer
172 return Vec->erase(I);
178 void operator=(const TinyPtrVector&); // NOT IMPLEMENTED YET.
179 #if LLVM_USE_RVALUE_REFERENCES
180 void operator=(TinyPtrVector&&); // NOT IMPLEMENTED YET.
183 } // end namespace llvm