/src/hermes/external/llvh/include/llvh/ADT/SetVector.h
Line | Count | Source |
1 | | //===- llvm/ADT/SetVector.h - Set with insert order iteration ---*- 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 | | // This file implements a set that has insertion order iteration |
11 | | // characteristics. This is useful for keeping a set of things that need to be |
12 | | // visited later but in a deterministic order (insertion order). The interface |
13 | | // is purposefully minimal. |
14 | | // |
15 | | // This file defines SetVector and SmallSetVector, which performs no allocations |
16 | | // if the SetVector has less than a certain number of elements. |
17 | | // |
18 | | //===----------------------------------------------------------------------===// |
19 | | |
20 | | #ifndef LLVM_ADT_SETVECTOR_H |
21 | | #define LLVM_ADT_SETVECTOR_H |
22 | | |
23 | | #include "llvh/ADT/ArrayRef.h" |
24 | | #include "llvh/ADT/DenseSet.h" |
25 | | #include "llvh/ADT/STLExtras.h" |
26 | | #include "llvh/Support/Compiler.h" |
27 | | #include <algorithm> |
28 | | #include <cassert> |
29 | | #include <iterator> |
30 | | #include <vector> |
31 | | |
32 | | namespace llvh { |
33 | | |
34 | | /// A vector that has set insertion semantics. |
35 | | /// |
36 | | /// This adapter class provides a way to keep a set of things that also has the |
37 | | /// property of a deterministic iteration order. The order of iteration is the |
38 | | /// order of insertion. |
39 | | template <typename T, typename Vector = std::vector<T>, |
40 | | typename Set = DenseSet<T>> |
41 | | class SetVector { |
42 | | public: |
43 | | using value_type = T; |
44 | | using key_type = T; |
45 | | using reference = T&; |
46 | | using const_reference = const T&; |
47 | | using set_type = Set; |
48 | | using vector_type = Vector; |
49 | | using iterator = typename vector_type::const_iterator; |
50 | | using const_iterator = typename vector_type::const_iterator; |
51 | | using reverse_iterator = typename vector_type::const_reverse_iterator; |
52 | | using const_reverse_iterator = typename vector_type::const_reverse_iterator; |
53 | | using size_type = typename vector_type::size_type; |
54 | | |
55 | | /// Construct an empty SetVector |
56 | 154 | SetVector() = default; llvh::SetVector<hermes::ScopeDesc*, std::__1::vector<hermes::ScopeDesc*, std::__1::allocator<hermes::ScopeDesc*> >, llvh::DenseSet<hermes::ScopeDesc*, llvh::DenseMapInfo<hermes::ScopeDesc*> > >::SetVector() Line | Count | Source | 56 | 147 | SetVector() = default; |
llvh::SetVector<hermes::Instruction*, llvh::SmallVector<hermes::Instruction*, 16u>, llvh::SmallDenseSet<hermes::Instruction*, 16u, llvh::DenseMapInfo<hermes::Instruction*> > >::SetVector() Line | Count | Source | 56 | 7 | SetVector() = default; |
Unexecuted instantiation: llvh::SetVector<hermes::Literal*, std::__1::vector<hermes::Literal*, std::__1::allocator<hermes::Literal*> >, llvh::DenseSet<hermes::Literal*, llvh::DenseMapInfo<hermes::Literal*> > >::SetVector() Unexecuted instantiation: llvh::SetVector<hermes::Function*, std::__1::vector<hermes::Function*, std::__1::allocator<hermes::Function*> >, llvh::DenseSet<hermes::Function*, llvh::DenseMapInfo<hermes::Function*> > >::SetVector() Unexecuted instantiation: llvh::SetVector<hermes::UniqueString*, std::__1::vector<hermes::UniqueString*, std::__1::allocator<hermes::UniqueString*> >, llvh::DenseSet<hermes::UniqueString*, llvh::DenseMapInfo<hermes::UniqueString*> > >::SetVector() |
57 | | |
58 | | /// Initialize a SetVector with a range of elements |
59 | | template<typename It> |
60 | | SetVector(It Start, It End) { |
61 | | insert(Start, End); |
62 | | } |
63 | | |
64 | | ArrayRef<T> getArrayRef() const { return vector_; } |
65 | | |
66 | | /// Clear the SetVector and return the underlying vector. |
67 | | Vector takeVector() { |
68 | | set_.clear(); |
69 | | return std::move(vector_); |
70 | | } |
71 | | |
72 | | /// Determine if the SetVector is empty or not. |
73 | 0 | bool empty() const { |
74 | 0 | return vector_.empty(); |
75 | 0 | } |
76 | | |
77 | | /// Determine the number of elements in the SetVector. |
78 | 23.1k | size_type size() const { |
79 | 23.1k | return vector_.size(); |
80 | 23.1k | } llvh::SetVector<hermes::ScopeDesc*, std::__1::vector<hermes::ScopeDesc*, std::__1::allocator<hermes::ScopeDesc*> >, llvh::DenseSet<hermes::ScopeDesc*, llvh::DenseMapInfo<hermes::ScopeDesc*> > >::size() const Line | Count | Source | 78 | 23.1k | size_type size() const { | 79 | 23.1k | return vector_.size(); | 80 | 23.1k | } |
Unexecuted instantiation: llvh::SetVector<hermes::Literal*, std::__1::vector<hermes::Literal*, std::__1::allocator<hermes::Literal*> >, llvh::DenseSet<hermes::Literal*, llvh::DenseMapInfo<hermes::Literal*> > >::size() const |
81 | | |
82 | | /// Get an iterator to the beginning of the SetVector. |
83 | 14 | iterator begin() { |
84 | 14 | return vector_.begin(); |
85 | 14 | } llvh::SetVector<hermes::Instruction*, llvh::SmallVector<hermes::Instruction*, 16u>, llvh::SmallDenseSet<hermes::Instruction*, 16u, llvh::DenseMapInfo<hermes::Instruction*> > >::begin() Line | Count | Source | 83 | 14 | iterator begin() { | 84 | 14 | return vector_.begin(); | 85 | 14 | } |
Unexecuted instantiation: llvh::SetVector<hermes::Literal*, std::__1::vector<hermes::Literal*, std::__1::allocator<hermes::Literal*> >, llvh::DenseSet<hermes::Literal*, llvh::DenseMapInfo<hermes::Literal*> > >::begin() Unexecuted instantiation: llvh::SetVector<hermes::UniqueString*, std::__1::vector<hermes::UniqueString*, std::__1::allocator<hermes::UniqueString*> >, llvh::DenseSet<hermes::UniqueString*, llvh::DenseMapInfo<hermes::UniqueString*> > >::begin() |
86 | | |
87 | | /// Get a const_iterator to the beginning of the SetVector. |
88 | | const_iterator begin() const { |
89 | | return vector_.begin(); |
90 | | } |
91 | | |
92 | | /// Get an iterator to the end of the SetVector. |
93 | 14 | iterator end() { |
94 | 14 | return vector_.end(); |
95 | 14 | } llvh::SetVector<hermes::Instruction*, llvh::SmallVector<hermes::Instruction*, 16u>, llvh::SmallDenseSet<hermes::Instruction*, 16u, llvh::DenseMapInfo<hermes::Instruction*> > >::end() Line | Count | Source | 93 | 14 | iterator end() { | 94 | 14 | return vector_.end(); | 95 | 14 | } |
Unexecuted instantiation: llvh::SetVector<hermes::Literal*, std::__1::vector<hermes::Literal*, std::__1::allocator<hermes::Literal*> >, llvh::DenseSet<hermes::Literal*, llvh::DenseMapInfo<hermes::Literal*> > >::end() Unexecuted instantiation: llvh::SetVector<hermes::UniqueString*, std::__1::vector<hermes::UniqueString*, std::__1::allocator<hermes::UniqueString*> >, llvh::DenseSet<hermes::UniqueString*, llvh::DenseMapInfo<hermes::UniqueString*> > >::end() |
96 | | |
97 | | /// Get a const_iterator to the end of the SetVector. |
98 | | const_iterator end() const { |
99 | | return vector_.end(); |
100 | | } |
101 | | |
102 | | /// Get an reverse_iterator to the end of the SetVector. |
103 | | reverse_iterator rbegin() { |
104 | | return vector_.rbegin(); |
105 | | } |
106 | | |
107 | | /// Get a const_reverse_iterator to the end of the SetVector. |
108 | | const_reverse_iterator rbegin() const { |
109 | | return vector_.rbegin(); |
110 | | } |
111 | | |
112 | | /// Get a reverse_iterator to the beginning of the SetVector. |
113 | | reverse_iterator rend() { |
114 | | return vector_.rend(); |
115 | | } |
116 | | |
117 | | /// Get a const_reverse_iterator to the beginning of the SetVector. |
118 | | const_reverse_iterator rend() const { |
119 | | return vector_.rend(); |
120 | | } |
121 | | |
122 | | /// Return the first element of the SetVector. |
123 | | const T &front() const { |
124 | | assert(!empty() && "Cannot call front() on empty SetVector!"); |
125 | | return vector_.front(); |
126 | | } |
127 | | |
128 | | /// Return the last element of the SetVector. |
129 | 0 | const T &back() const { |
130 | 0 | assert(!empty() && "Cannot call back() on empty SetVector!"); |
131 | 0 | return vector_.back(); |
132 | 0 | } |
133 | | |
134 | | /// Index into the SetVector. |
135 | 46.2k | const_reference operator[](size_type n) const { |
136 | 46.2k | assert(n < vector_.size() && "SetVector access out of range!"); |
137 | 46.2k | return vector_[n]; |
138 | 46.2k | } |
139 | | |
140 | | /// Insert a new element into the SetVector. |
141 | | /// \returns true if the element was inserted into the SetVector. |
142 | 1.60M | bool insert(const value_type &X) { |
143 | 1.60M | bool result = set_.insert(X).second; |
144 | 1.60M | if (result) |
145 | 46.3k | vector_.push_back(X); |
146 | 1.60M | return result; |
147 | 1.60M | } llvh::SetVector<hermes::ScopeDesc*, std::__1::vector<hermes::ScopeDesc*, std::__1::allocator<hermes::ScopeDesc*> >, llvh::DenseSet<hermes::ScopeDesc*, llvh::DenseMapInfo<hermes::ScopeDesc*> > >::insert(hermes::ScopeDesc* const&) Line | Count | Source | 142 | 1.60M | bool insert(const value_type &X) { | 143 | 1.60M | bool result = set_.insert(X).second; | 144 | 1.60M | if (result) | 145 | 46.3k | vector_.push_back(X); | 146 | 1.60M | return result; | 147 | 1.60M | } |
Unexecuted instantiation: llvh::SetVector<hermes::Literal*, std::__1::vector<hermes::Literal*, std::__1::allocator<hermes::Literal*> >, llvh::DenseSet<hermes::Literal*, llvh::DenseMapInfo<hermes::Literal*> > >::insert(hermes::Literal* const&) Unexecuted instantiation: llvh::SetVector<hermes::Function*, std::__1::vector<hermes::Function*, std::__1::allocator<hermes::Function*> >, llvh::DenseSet<hermes::Function*, llvh::DenseMapInfo<hermes::Function*> > >::insert(hermes::Function* const&) Unexecuted instantiation: llvh::SetVector<hermes::UniqueString*, std::__1::vector<hermes::UniqueString*, std::__1::allocator<hermes::UniqueString*> >, llvh::DenseSet<hermes::UniqueString*, llvh::DenseMapInfo<hermes::UniqueString*> > >::insert(hermes::UniqueString* const&) |
148 | | |
149 | | /// Insert a range of elements into the SetVector. |
150 | | template<typename It> |
151 | 14 | void insert(It Start, It End) { |
152 | 41 | for (; Start != End; ++Start) |
153 | 27 | if (set_.insert(*Start).second) |
154 | 27 | vector_.push_back(*Start); |
155 | 14 | } void llvh::SetVector<hermes::Instruction*, llvh::SmallVector<hermes::Instruction*, 16u>, llvh::SmallDenseSet<hermes::Instruction*, 16u, llvh::DenseMapInfo<hermes::Instruction*> > >::insert<hermes::Instruction* const*>(hermes::Instruction* const*, hermes::Instruction* const*) Line | Count | Source | 151 | 14 | void insert(It Start, It End) { | 152 | 41 | for (; Start != End; ++Start) | 153 | 27 | if (set_.insert(*Start).second) | 154 | 27 | vector_.push_back(*Start); | 155 | 14 | } |
Unexecuted instantiation: void llvh::SetVector<hermes::Function*, std::__1::vector<hermes::Function*, std::__1::allocator<hermes::Function*> >, llvh::DenseSet<hermes::Function*, llvh::DenseMapInfo<hermes::Function*> > >::insert<llvh::SmallPtrSetIterator<hermes::Function*> >(llvh::SmallPtrSetIterator<hermes::Function*>, llvh::SmallPtrSetIterator<hermes::Function*>) |
156 | | |
157 | | /// Remove an item from the set vector. |
158 | | bool remove(const value_type& X) { |
159 | | if (set_.erase(X)) { |
160 | | typename vector_type::iterator I = find(vector_, X); |
161 | | assert(I != vector_.end() && "Corrupted SetVector instances!"); |
162 | | vector_.erase(I); |
163 | | return true; |
164 | | } |
165 | | return false; |
166 | | } |
167 | | |
168 | | /// Erase a single element from the set vector. |
169 | | /// \returns an iterator pointing to the next element that followed the |
170 | | /// element erased. This is the end of the SetVector if the last element is |
171 | | /// erased. |
172 | | iterator erase(iterator I) { |
173 | | const key_type &V = *I; |
174 | | assert(set_.count(V) && "Corrupted SetVector instances!"); |
175 | | set_.erase(V); |
176 | | |
177 | | // FIXME: No need to use the non-const iterator when built with |
178 | | // std:vector.erase(const_iterator) as defined in C++11. This is for |
179 | | // compatibility with non-standard libstdc++ up to 4.8 (fixed in 4.9). |
180 | | auto NI = vector_.begin(); |
181 | | std::advance(NI, std::distance<iterator>(NI, I)); |
182 | | |
183 | | return vector_.erase(NI); |
184 | | } |
185 | | |
186 | | /// Remove items from the set vector based on a predicate function. |
187 | | /// |
188 | | /// This is intended to be equivalent to the following code, if we could |
189 | | /// write it: |
190 | | /// |
191 | | /// \code |
192 | | /// V.erase(remove_if(V, P), V.end()); |
193 | | /// \endcode |
194 | | /// |
195 | | /// However, SetVector doesn't expose non-const iterators, making any |
196 | | /// algorithm like remove_if impossible to use. |
197 | | /// |
198 | | /// \returns true if any element is removed. |
199 | | template <typename UnaryPredicate> |
200 | | bool remove_if(UnaryPredicate P) { |
201 | | typename vector_type::iterator I = |
202 | | llvh::remove_if(vector_, TestAndEraseFromSet<UnaryPredicate>(P, set_)); |
203 | | if (I == vector_.end()) |
204 | | return false; |
205 | | vector_.erase(I, vector_.end()); |
206 | | return true; |
207 | | } |
208 | | |
209 | | /// Count the number of elements of a given key in the SetVector. |
210 | | /// \returns 0 if the element is not in the SetVector, 1 if it is. |
211 | | size_type count(const key_type &key) const { |
212 | | return set_.count(key); |
213 | | } |
214 | | |
215 | | /// Completely clear the SetVector |
216 | 23.1k | void clear() { |
217 | 23.1k | set_.clear(); |
218 | 23.1k | vector_.clear(); |
219 | 23.1k | } llvh::SetVector<hermes::ScopeDesc*, std::__1::vector<hermes::ScopeDesc*, std::__1::allocator<hermes::ScopeDesc*> >, llvh::DenseSet<hermes::ScopeDesc*, llvh::DenseMapInfo<hermes::ScopeDesc*> > >::clear() Line | Count | Source | 216 | 23.1k | void clear() { | 217 | 23.1k | set_.clear(); | 218 | 23.1k | vector_.clear(); | 219 | 23.1k | } |
llvh::SetVector<hermes::Instruction*, llvh::SmallVector<hermes::Instruction*, 16u>, llvh::SmallDenseSet<hermes::Instruction*, 16u, llvh::DenseMapInfo<hermes::Instruction*> > >::clear() Line | Count | Source | 216 | 7 | void clear() { | 217 | 7 | set_.clear(); | 218 | 7 | vector_.clear(); | 219 | 7 | } |
|
220 | | |
221 | | /// Remove the last element of the SetVector. |
222 | 0 | void pop_back() { |
223 | 0 | assert(!empty() && "Cannot remove an element from an empty SetVector!"); |
224 | 0 | set_.erase(back()); |
225 | 0 | vector_.pop_back(); |
226 | 0 | } |
227 | | |
228 | | LLVM_NODISCARD T pop_back_val() { |
229 | | T Ret = back(); |
230 | | pop_back(); |
231 | | return Ret; |
232 | | } |
233 | | |
234 | | bool operator==(const SetVector &that) const { |
235 | | return vector_ == that.vector_; |
236 | | } |
237 | | |
238 | | bool operator!=(const SetVector &that) const { |
239 | | return vector_ != that.vector_; |
240 | | } |
241 | | |
242 | | /// Compute This := This u S, return whether 'This' changed. |
243 | | /// TODO: We should be able to use set_union from SetOperations.h, but |
244 | | /// SetVector interface is inconsistent with DenseSet. |
245 | | template <class STy> |
246 | | bool set_union(const STy &S) { |
247 | | bool Changed = false; |
248 | | |
249 | | for (typename STy::const_iterator SI = S.begin(), SE = S.end(); SI != SE; |
250 | | ++SI) |
251 | | if (insert(*SI)) |
252 | | Changed = true; |
253 | | |
254 | | return Changed; |
255 | | } |
256 | | |
257 | | /// Compute This := This - B |
258 | | /// TODO: We should be able to use set_subtract from SetOperations.h, but |
259 | | /// SetVector interface is inconsistent with DenseSet. |
260 | | template <class STy> |
261 | | void set_subtract(const STy &S) { |
262 | | for (typename STy::const_iterator SI = S.begin(), SE = S.end(); SI != SE; |
263 | | ++SI) |
264 | | remove(*SI); |
265 | | } |
266 | | |
267 | | private: |
268 | | /// A wrapper predicate designed for use with std::remove_if. |
269 | | /// |
270 | | /// This predicate wraps a predicate suitable for use with std::remove_if to |
271 | | /// call set_.erase(x) on each element which is slated for removal. |
272 | | template <typename UnaryPredicate> |
273 | | class TestAndEraseFromSet { |
274 | | UnaryPredicate P; |
275 | | set_type &set_; |
276 | | |
277 | | public: |
278 | | TestAndEraseFromSet(UnaryPredicate P, set_type &set_) |
279 | | : P(std::move(P)), set_(set_) {} |
280 | | |
281 | | template <typename ArgumentT> |
282 | | bool operator()(const ArgumentT &Arg) { |
283 | | if (P(Arg)) { |
284 | | set_.erase(Arg); |
285 | | return true; |
286 | | } |
287 | | return false; |
288 | | } |
289 | | }; |
290 | | |
291 | | set_type set_; ///< The set. |
292 | | vector_type vector_; ///< The vector. |
293 | | }; |
294 | | |
295 | | /// A SetVector that performs no allocations if smaller than |
296 | | /// a certain size. |
297 | | template <typename T, unsigned N> |
298 | | class SmallSetVector |
299 | | : public SetVector<T, SmallVector<T, N>, SmallDenseSet<T, N>> { |
300 | | public: |
301 | 7 | SmallSetVector() = default; |
302 | | |
303 | | /// Initialize a SmallSetVector with a range of elements |
304 | | template<typename It> |
305 | | SmallSetVector(It Start, It End) { |
306 | | this->insert(Start, End); |
307 | | } |
308 | | }; |
309 | | |
310 | | } // end namespace llvh |
311 | | |
312 | | #endif // LLVM_ADT_SETVECTOR_H |