Deleted Added
full compact
TinyPtrVector.h (226633) TinyPtrVector.h (234353)
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