1//===- llvm/ADT/SetVector.h - Set with insert order iteration ---*- C++ -*-===// 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 7//===----------------------------------------------------------------------===// 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. 15/// This file defines SetVector and SmallSetVector, which performs no 16/// allocations if the SetVector has less than a certain number of elements. 18//===----------------------------------------------------------------------===// 20#ifndef LLVM_ADT_SETVECTOR_H 21#define LLVM_ADT_SETVECTOR_H 33/// A vector that has set insertion semantics. 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. 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. 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. 50/// The parameter N specifies the "small" size of the container, which is the 51/// number of elements upto which a linear scan over the Vector will be used 52/// when searching for elements instead of checking Set, due to it being better 53/// for performance. A value of 0 means that this mode of operation is not used, 54/// and is the default value. 55template <
typename T,
typename Vector = SmallVector<T, 0>,
56typename Set = DenseSet<T>,
unsigned N = 0>
58// Much like in SmallPtrSet, this value should not be too high to prevent 59// excessively long linear scans from occuring. 60static_assert(
N <= 32,
"Small size should be less than or equal to 32!");
69usingiterator =
typename vector_type::const_iterator;
75 /// Construct an empty SetVector 78 /// Initialize a SetVector with a range of elements 86 /// Clear the SetVector and return the underlying vector. 89return std::move(vector_);
92 /// Determine if the SetVector is empty or not. 94return vector_.empty();
97 /// Determine the number of elements in the SetVector. 102 /// Get an iterator to the beginning of the SetVector. 104return vector_.begin();
107 /// Get a const_iterator to the beginning of the SetVector. 109return vector_.begin();
112 /// Get an iterator to the end of the SetVector. 117 /// Get a const_iterator to the end of the SetVector. 122 /// Get an reverse_iterator to the end of the SetVector. 124return vector_.rbegin();
127 /// Get a const_reverse_iterator to the end of the SetVector. 129return vector_.rbegin();
132 /// Get a reverse_iterator to the beginning of the SetVector. 134return vector_.rend();
137 /// Get a const_reverse_iterator to the beginning of the SetVector. 139return vector_.rend();
142 /// Return the first element of the SetVector. 144assert(!
empty() &&
"Cannot call front() on empty SetVector!");
145return vector_.front();
148 /// Return the last element of the SetVector. 150assert(!
empty() &&
"Cannot call back() on empty SetVector!");
151return vector_.back();
154 /// Index into the SetVector. 156assert(n < vector_.size() &&
"SetVector access out of range!");
160 /// Insert a new element into the SetVector. 161 /// \returns true if the element was inserted into the SetVector. 163ifconstexpr (canBeSmall())
166 vector_.push_back(
X);
167if (vector_.size() >
N)
174bool result = set_.insert(
X).second;
176 vector_.push_back(
X);
180 /// Insert a range of elements into the SetVector. 183for (; Start !=
End; ++Start)
187 /// Remove an item from the set vector. 189ifconstexpr (canBeSmall())
191typename vector_type::iterator
I =
find(vector_,
X);
192if (
I != vector_.end()) {
200typename vector_type::iterator
I =
find(vector_,
X);
201assert(
I != vector_.end() &&
"Corrupted SetVector instances!");
208 /// Erase a single element from the set vector. 209 /// \returns an iterator pointing to the next element that followed the 210 /// element erased. This is the end of the SetVector if the last element is 213ifconstexpr (canBeSmall())
215return vector_.erase(
I);
218assert(set_.count(V) &&
"Corrupted SetVector instances!");
220return vector_.erase(
I);
223 /// Remove items from the set vector based on a predicate function. 225 /// This is intended to be equivalent to the following code, if we could 229 /// V.erase(remove_if(V, P), V.end()); 232 /// However, SetVector doesn't expose non-const iterators, making any 233 /// algorithm like remove_if impossible to use. 235 /// \returns true if any element is removed. 236template <
typename UnaryPredicate>
238typename vector_type::iterator
I = [
this,
P] {
239ifconstexpr (canBeSmall())
244 TestAndEraseFromSet<UnaryPredicate>(
P, set_));
247if (
I == vector_.end())
249 vector_.erase(
I, vector_.end());
253 /// Check if the SetVector contains the given key. 255ifconstexpr (canBeSmall())
259return set_.find(key) != set_.end();
262 /// Count the number of elements of a given key in the SetVector. 263 /// \returns 0 if the element is not in the SetVector, 1 if it is. 265ifconstexpr (canBeSmall())
269return set_.count(key);
272 /// Completely clear the SetVector 278 /// Remove the last element of the SetVector. 280assert(!
empty() &&
"Cannot remove an element from an empty SetVector!");
292return vector_ == that.vector_;
296return vector_ != that.vector_;
299 /// Compute This := This u S, return whether 'This' changed. 300 /// TODO: We should be able to use set_union from SetOperations.h, but 301 /// SetVector interface is inconsistent with DenseSet. 306for (
typename STy::const_iterator SI = S.begin(), SE = S.end(); SI != SE;
314 /// Compute This := This - B 315 /// TODO: We should be able to use set_subtract from SetOperations.h, but 316 /// SetVector interface is inconsistent with DenseSet. 319for (
typename STy::const_iterator SI = S.begin(), SE = S.end(); SI != SE;
326 vector_.swap(
RHS.vector_);
330 /// A wrapper predicate designed for use with std::remove_if. 332 /// This predicate wraps a predicate suitable for use with std::remove_if to 333 /// call set_.erase(x) on each element which is slated for removal. 334template <
typename UnaryPredicate>
335classTestAndEraseFromSet {
340 TestAndEraseFromSet(UnaryPredicate P,
set_type &set_)
343template <
typename ArgumentT>
344bool operator()(
const ArgumentT &Arg) {
353 [[nodiscard]]
staticconstexprbool canBeSmall() {
returnN != 0; }
355 [[nodiscard]]
bool isSmall()
const{
return set_.empty(); }
358ifconstexpr (canBeSmall())
359for (
constauto &entry : vector_)
367/// A SetVector that performs no allocations if smaller than 369template <
typename T,
unsigned N>
374 /// Initialize a SmallSetVector with a range of elements 381}
// end namespace llvm 385/// Implement std::swap in terms of SetVector swap. 386template <
typename T,
typename V,
typename S,
unsigned N>
392/// Implement std::swap in terms of SmallSetVector swap. 393template<
typename T,
unsigned N>
401#endif// LLVM_ADT_SETVECTOR_H This file defines the DenseSet and SmallDenseSet classes.
static GCMetadataPrinterRegistry::Add< ErlangGCPrinter > X("erlang", "erlang-compatible garbage collector")
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
This file contains some templates that are useful if you are working with the STL at all.
This file defines the SmallVector class.
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
A vector that has set insertion semantics.
const_reverse_iterator rend() const
Get a const_reverse_iterator to the beginning of the SetVector.
ArrayRef< value_type > getArrayRef() const
typename vector_type::const_reverse_iterator reverse_iterator
iterator erase(const_iterator I)
Erase a single element from the set vector.
bool remove(const value_type &X)
Remove an item from the set vector.
bool remove_if(UnaryPredicate P)
Remove items from the set vector based on a predicate function.
size_type size() const
Determine the number of elements in the SetVector.
const value_type & front() const
Return the first element of the SetVector.
bool operator==(const SetVector &that) const
typename vector_type::const_reverse_iterator const_reverse_iterator
const value_type & back() const
Return the last element of the SetVector.
bool set_union(const STy &S)
Compute This := This u S, return whether 'This' changed.
typename Vector::value_type value_type
const_reverse_iterator rbegin() const
Get a const_reverse_iterator to the end of the SetVector.
Vector takeVector()
Clear the SetVector and return the underlying vector.
typename vector_type::const_iterator iterator
iterator end()
Get an iterator to the end of the SetVector.
SetVector()=default
Construct an empty SetVector.
reverse_iterator rbegin()
Get an reverse_iterator to the end of the SetVector.
typename vector_type::const_iterator const_iterator
const_iterator end() const
Get a const_iterator to the end of the SetVector.
void clear()
Completely clear the SetVector.
bool operator!=(const SetVector &that) const
reverse_iterator rend()
Get a reverse_iterator to the beginning of the SetVector.
typename vector_type::size_type size_type
const_iterator begin() const
Get a const_iterator to the beginning of the SetVector.
size_type count(const key_type &key) const
Count the number of elements of a given key in the SetVector.
bool empty() const
Determine if the SetVector is empty or not.
void insert(It Start, It End)
Insert a range of elements into the SetVector.
const value_type & const_reference
iterator begin()
Get an iterator to the beginning of the SetVector.
SetVector(It Start, It End)
Initialize a SetVector with a range of elements.
void swap(SetVector< T, Vector, Set, N > &RHS)
typename Set::key_type key_type
void set_subtract(const STy &S)
Compute This := This - B TODO: We should be able to use set_subtract from SetOperations....
bool insert(const value_type &X)
Insert a new element into the SetVector.
void pop_back()
Remove the last element of the SetVector.
value_type pop_back_val()
const_reference operator[](size_type n) const
Index into the SetVector.
bool contains(const key_type &key) const
Check if the SetVector contains the given key.
A SetVector that performs no allocations if smaller than a certain size.
SmallSetVector(It Start, It End)
Initialize a SmallSetVector with a range of elements.
This is an optimization pass for GlobalISel generic memory operations.
auto find(R &&Range, const T &Val)
Provide wrappers to std::find which take ranges instead of having to pass begin/end explicitly.
auto remove_if(R &&Range, UnaryPredicate P)
Provide wrappers to std::remove_if which take ranges instead of having to pass begin/end explicitly.
OutputIt move(R &&Range, OutputIt Out)
Provide wrappers to std::move which take ranges instead of having to pass begin/end explicitly.
bool is_contained(R &&Range, const E &Element)
Returns true if Element is found in Range.
Implement std::hash so that hash_code can be used in STL containers.
void swap(llvm::BitVector &LHS, llvm::BitVector &RHS)
Implement std::swap in terms of BitVector swap.