LLVM 17.0.0git
SetVector.h
Go to the documentation of this file.
1//===- llvm/ADT/SetVector.h - Set with insert order iteration ---*- C++ -*-===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8///
9/// \file
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
16/// allocations 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 "llvm/ADT/ArrayRef.h"
24#include "llvm/ADT/DenseSet.h"
25#include "llvm/ADT/STLExtras.h"
27#include <cassert>
28#include <iterator>
29#include <vector>
30
31namespace llvm {
32
33/// A vector that has set insertion semantics.
34///
35/// This adapter class provides a way to keep a set of things that also has the
36/// property of a deterministic iteration order. The order of iteration is the
37/// order of insertion.
38///
39/// The key and value types are derived from the Set and Vector types
40/// respectively. This allows the vector-type operations and set-type operations
41/// to have different types. In particular, this is useful when storing pointers
42/// as "Foo *" values but looking them up as "const Foo *" keys.
43///
44/// No constraint is placed on the key and value types, although it is assumed
45/// that value_type can be converted into key_type for insertion. Users must be
46/// aware of any loss of information in this conversion. For example, setting
47/// value_type to float and key_type to int can produce very surprising results,
48/// but it is not explicitly disallowed.
49template <typename T, typename Vector = std::vector<T>,
50 typename Set = DenseSet<T>>
51class SetVector {
52public:
53 using value_type = typename Vector::value_type;
54 using key_type = typename Set::key_type;
56 using const_reference = const value_type &;
57 using set_type = Set;
59 using iterator = typename vector_type::const_iterator;
60 using const_iterator = typename vector_type::const_iterator;
61 using reverse_iterator = typename vector_type::const_reverse_iterator;
62 using const_reverse_iterator = typename vector_type::const_reverse_iterator;
63 using size_type = typename vector_type::size_type;
64
65 /// Construct an empty SetVector
66 SetVector() = default;
67
68 /// Initialize a SetVector with a range of elements
69 template<typename It>
70 SetVector(It Start, It End) {
71 insert(Start, End);
72 }
73
74 ArrayRef<value_type> getArrayRef() const { return vector_; }
75
76 /// Clear the SetVector and return the underlying vector.
78 set_.clear();
79 return std::move(vector_);
80 }
81
82 /// Determine if the SetVector is empty or not.
83 bool empty() const {
84 return vector_.empty();
85 }
86
87 /// Determine the number of elements in the SetVector.
88 size_type size() const {
89 return vector_.size();
90 }
91
92 /// Get an iterator to the beginning of the SetVector.
94 return vector_.begin();
95 }
96
97 /// Get a const_iterator to the beginning of the SetVector.
99 return vector_.begin();
100 }
101
102 /// Get an iterator to the end of the SetVector.
104 return vector_.end();
105 }
106
107 /// Get a const_iterator to the end of the SetVector.
109 return vector_.end();
110 }
111
112 /// Get an reverse_iterator to the end of the SetVector.
114 return vector_.rbegin();
115 }
116
117 /// Get a const_reverse_iterator to the end of the SetVector.
119 return vector_.rbegin();
120 }
121
122 /// Get a reverse_iterator to the beginning of the SetVector.
124 return vector_.rend();
125 }
126
127 /// Get a const_reverse_iterator to the beginning of the SetVector.
129 return vector_.rend();
130 }
131
132 /// Return the first element of the SetVector.
133 const value_type &front() const {
134 assert(!empty() && "Cannot call front() on empty SetVector!");
135 return vector_.front();
136 }
137
138 /// Return the last element of the SetVector.
139 const value_type &back() const {
140 assert(!empty() && "Cannot call back() on empty SetVector!");
141 return vector_.back();
142 }
143
144 /// Index into the SetVector.
146 assert(n < vector_.size() && "SetVector access out of range!");
147 return vector_[n];
148 }
149
150 /// Insert a new element into the SetVector.
151 /// \returns true if the element was inserted into the SetVector.
152 bool insert(const value_type &X) {
153 bool result = set_.insert(X).second;
154 if (result)
155 vector_.push_back(X);
156 return result;
157 }
158
159 /// Insert a range of elements into the SetVector.
160 template<typename It>
161 void insert(It Start, It End) {
162 for (; Start != End; ++Start)
163 if (set_.insert(*Start).second)
164 vector_.push_back(*Start);
165 }
166
167 /// Remove an item from the set vector.
168 bool remove(const value_type& X) {
169 if (set_.erase(X)) {
170 typename vector_type::iterator I = find(vector_, X);
171 assert(I != vector_.end() && "Corrupted SetVector instances!");
172 vector_.erase(I);
173 return true;
174 }
175 return false;
176 }
177
178 /// Erase a single element from the set vector.
179 /// \returns an iterator pointing to the next element that followed the
180 /// element erased. This is the end of the SetVector if the last element is
181 /// erased.
183 const key_type &V = *I;
184 assert(set_.count(V) && "Corrupted SetVector instances!");
185 set_.erase(V);
186 return vector_.erase(I);
187 }
188
189 /// Remove items from the set vector based on a predicate function.
190 ///
191 /// This is intended to be equivalent to the following code, if we could
192 /// write it:
193 ///
194 /// \code
195 /// V.erase(remove_if(V, P), V.end());
196 /// \endcode
197 ///
198 /// However, SetVector doesn't expose non-const iterators, making any
199 /// algorithm like remove_if impossible to use.
200 ///
201 /// \returns true if any element is removed.
202 template <typename UnaryPredicate>
203 bool remove_if(UnaryPredicate P) {
204 typename vector_type::iterator I =
205 llvm::remove_if(vector_, TestAndEraseFromSet<UnaryPredicate>(P, set_));
206 if (I == vector_.end())
207 return false;
208 vector_.erase(I, vector_.end());
209 return true;
210 }
211
212 /// Check if the SetVector contains the given key.
213 bool contains(const key_type &key) const {
214 return set_.find(key) != set_.end();
215 }
216
217 /// Count the number of elements of a given key in the SetVector.
218 /// \returns 0 if the element is not in the SetVector, 1 if it is.
219 size_type count(const key_type &key) const {
220 return set_.count(key);
221 }
222
223 /// Completely clear the SetVector
224 void clear() {
225 set_.clear();
226 vector_.clear();
227 }
228
229 /// Remove the last element of the SetVector.
230 void pop_back() {
231 assert(!empty() && "Cannot remove an element from an empty SetVector!");
232 set_.erase(back());
233 vector_.pop_back();
234 }
235
236 [[nodiscard]] value_type pop_back_val() {
237 value_type Ret = back();
238 pop_back();
239 return Ret;
240 }
241
242 bool operator==(const SetVector &that) const {
243 return vector_ == that.vector_;
244 }
245
246 bool operator!=(const SetVector &that) const {
247 return vector_ != that.vector_;
248 }
249
250 /// Compute This := This u S, return whether 'This' changed.
251 /// TODO: We should be able to use set_union from SetOperations.h, but
252 /// SetVector interface is inconsistent with DenseSet.
253 template <class STy>
254 bool set_union(const STy &S) {
255 bool Changed = false;
256
257 for (typename STy::const_iterator SI = S.begin(), SE = S.end(); SI != SE;
258 ++SI)
259 if (insert(*SI))
260 Changed = true;
261
262 return Changed;
263 }
264
265 /// Compute This := This - B
266 /// TODO: We should be able to use set_subtract from SetOperations.h, but
267 /// SetVector interface is inconsistent with DenseSet.
268 template <class STy>
269 void set_subtract(const STy &S) {
270 for (typename STy::const_iterator SI = S.begin(), SE = S.end(); SI != SE;
271 ++SI)
272 remove(*SI);
273 }
274
276 set_.swap(RHS.set_);
277 vector_.swap(RHS.vector_);
278 }
279
280private:
281 /// A wrapper predicate designed for use with std::remove_if.
282 ///
283 /// This predicate wraps a predicate suitable for use with std::remove_if to
284 /// call set_.erase(x) on each element which is slated for removal.
285 template <typename UnaryPredicate>
286 class TestAndEraseFromSet {
287 UnaryPredicate P;
288 set_type &set_;
289
290 public:
291 TestAndEraseFromSet(UnaryPredicate P, set_type &set_)
292 : P(std::move(P)), set_(set_) {}
293
294 template <typename ArgumentT>
295 bool operator()(const ArgumentT &Arg) {
296 if (P(Arg)) {
297 set_.erase(Arg);
298 return true;
299 }
300 return false;
301 }
302 };
303
304 set_type set_; ///< The set.
305 vector_type vector_; ///< The vector.
306};
307
308/// A SetVector that performs no allocations if smaller than
309/// a certain size.
310template <typename T, unsigned N>
312 : public SetVector<T, SmallVector<T, N>, SmallDenseSet<T, N>> {
313public:
314 SmallSetVector() = default;
315
316 /// Initialize a SmallSetVector with a range of elements
317 template<typename It>
318 SmallSetVector(It Start, It End) {
319 this->insert(Start, End);
320 }
321};
322
323} // end namespace llvm
324
325namespace std {
326
327/// Implement std::swap in terms of SetVector swap.
328template<typename T, typename V, typename S>
329inline void
331 LHS.swap(RHS);
332}
333
334/// Implement std::swap in terms of SmallSetVector swap.
335template<typename T, unsigned N>
336inline void
338 LHS.swap(RHS);
339}
340
341} // end namespace std
342
343#endif // LLVM_ADT_SETVECTOR_H
amdgpu Simplify well known AMD library false FunctionCallee Value * Arg
This file defines the DenseSet and SmallDenseSet classes.
bool End
Definition: ELF_riscv.cpp:464
static GCMetadataPrinterRegistry::Add< ErlangGCPrinter > X("erlang", "erlang-compatible garbage collector")
#define I(x, y, z)
Definition: MD5.cpp:58
#define P(N)
@ SI
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
This file contains some templates that are useful if you are working with the STL at all.
Value * RHS
Value * LHS
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
Definition: ArrayRef.h:41
A vector that has set insertion semantics.
Definition: SetVector.h:51
const_iterator end() const
Get a const_iterator to the end of the SetVector.
Definition: SetVector.h:108
size_type size() const
Determine the number of elements in the SetVector.
Definition: SetVector.h:88
typename vector_type::const_iterator const_iterator
Definition: SetVector.h:60
size_type count(const key_type &key) const
Count the number of elements of a given key in the SetVector.
Definition: SetVector.h:219
value_type & reference
Definition: SetVector.h:55
typename Vector::value_type value_type
Definition: SetVector.h:53
reverse_iterator rend()
Get a reverse_iterator to the beginning of the SetVector.
Definition: SetVector.h:123
iterator erase(const_iterator I)
Erase a single element from the set vector.
Definition: SetVector.h:182
bool contains(const key_type &key) const
Check if the SetVector contains the given key.
Definition: SetVector.h:213
typename Set::key_type key_type
Definition: SetVector.h:54
SetVector()=default
Construct an empty SetVector.
bool remove_if(UnaryPredicate P)
Remove items from the set vector based on a predicate function.
Definition: SetVector.h:203
Vector vector_type
Definition: SetVector.h:58
bool remove(const value_type &X)
Remove an item from the set vector.
Definition: SetVector.h:168
reverse_iterator rbegin()
Get an reverse_iterator to the end of the SetVector.
Definition: SetVector.h:113
const_reference operator[](size_type n) const
Index into the SetVector.
Definition: SetVector.h:145
bool insert(const value_type &X)
Insert a new element into the SetVector.
Definition: SetVector.h:152
const_reverse_iterator rend() const
Get a const_reverse_iterator to the beginning of the SetVector.
Definition: SetVector.h:128
void pop_back()
Remove the last element of the SetVector.
Definition: SetVector.h:230
typename vector_type::const_reverse_iterator const_reverse_iterator
Definition: SetVector.h:62
const value_type & front() const
Return the first element of the SetVector.
Definition: SetVector.h:133
bool operator!=(const SetVector &that) const
Definition: SetVector.h:246
void clear()
Completely clear the SetVector.
Definition: SetVector.h:224
const value_type & const_reference
Definition: SetVector.h:56
const_reverse_iterator rbegin() const
Get a const_reverse_iterator to the end of the SetVector.
Definition: SetVector.h:118
bool set_union(const STy &S)
Compute This := This u S, return whether 'This' changed.
Definition: SetVector.h:254
typename vector_type::size_type size_type
Definition: SetVector.h:63
bool empty() const
Determine if the SetVector is empty or not.
Definition: SetVector.h:83
Vector takeVector()
Clear the SetVector and return the underlying vector.
Definition: SetVector.h:77
typename vector_type::const_iterator iterator
Definition: SetVector.h:59
value_type pop_back_val()
Definition: SetVector.h:236
SetVector(It Start, It End)
Initialize a SetVector with a range of elements.
Definition: SetVector.h:70
const value_type & back() const
Return the last element of the SetVector.
Definition: SetVector.h:139
const_iterator begin() const
Get a const_iterator to the beginning of the SetVector.
Definition: SetVector.h:98
typename vector_type::const_reverse_iterator reverse_iterator
Definition: SetVector.h:61
iterator begin()
Get an iterator to the beginning of the SetVector.
Definition: SetVector.h:93
bool operator==(const SetVector &that) const
Definition: SetVector.h:242
ArrayRef< value_type > getArrayRef() const
Definition: SetVector.h:74
void swap(SetVector< T, Vector, Set > &RHS)
Definition: SetVector.h:275
void insert(It Start, It End)
Insert a range of elements into the SetVector.
Definition: SetVector.h:161
void set_subtract(const STy &S)
Compute This := This - B TODO: We should be able to use set_subtract from SetOperations....
Definition: SetVector.h:269
iterator end()
Get an iterator to the end of the SetVector.
Definition: SetVector.h:103
A SetVector that performs no allocations if smaller than a certain size.
Definition: SetVector.h:312
SmallSetVector(It Start, It End)
Initialize a SmallSetVector with a range of elements.
Definition: SetVector.h:318
SmallSetVector()=default
This is an optimization pass for GlobalISel generic memory operations.
Definition: AddressRanges.h:18
auto find(R &&Range, const T &Val)
Provide wrappers to std::find which take ranges instead of having to pass begin/end explicitly.
Definition: STLExtras.h:1839
auto remove_if(R &&Range, UnaryPredicate P)
Provide wrappers to std::remove_if which take ranges instead of having to pass begin/end explicitly.
Definition: STLExtras.h:1858
OutputIt move(R &&Range, OutputIt Out)
Provide wrappers to std::move which take ranges instead of having to pass begin/end explicitly.
Definition: STLExtras.h:1946
Definition: BitVector.h:858
void swap(llvm::BitVector &LHS, llvm::BitVector &RHS)
Implement std::swap in terms of BitVector swap.
Definition: BitVector.h:860