LLVM 22.0.0git
MapVector.h
Go to the documentation of this file.
1//===- llvm/ADT/MapVector.h - Map w/ deterministic value order --*- 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 map that provides insertion order iteration. The
11/// interface is purposefully minimal. The key is assumed to be cheap to copy
12/// and 2 copies are kept, one for indexing in a DenseMap, one for iteration in
13/// a SmallVector.
14///
15//===----------------------------------------------------------------------===//
16
17#ifndef LLVM_ADT_MAPVECTOR_H
18#define LLVM_ADT_MAPVECTOR_H
19
20#include "llvm/ADT/DenseMap.h"
22#include <cassert>
23#include <cstddef>
24#include <iterator>
25#include <type_traits>
26#include <utility>
27
28namespace llvm {
29
30/// This class implements a map that also provides access to all stored values
31/// in a deterministic order. The values are kept in a SmallVector<*, 0> and the
32/// mapping is done with DenseMap from Keys to indexes in that vector.
33template <typename KeyT, typename ValueT,
34 typename MapType = DenseMap<KeyT, unsigned>,
36class MapVector {
37public:
38 using key_type = KeyT;
39 using value_type = typename VectorType::value_type;
40 using size_type = typename VectorType::size_type;
41
42 using iterator = typename VectorType::iterator;
43 using const_iterator = typename VectorType::const_iterator;
44 using reverse_iterator = typename VectorType::reverse_iterator;
45 using const_reverse_iterator = typename VectorType::const_reverse_iterator;
46
47 /// Clear the MapVector and return the underlying vector.
48 [[nodiscard]] VectorType takeVector() {
49 Map.clear();
50 return std::move(Vector);
51 }
52
53 /// Returns an array reference of the underlying vector.
54 [[nodiscard]] ArrayRef<value_type> getArrayRef() const { return Vector; }
55
56 [[nodiscard]] size_type size() const { return Vector.size(); }
57
58 /// Grow the MapVector so that it can contain at least \p NumEntries items
59 /// before resizing again.
60 void reserve(size_type NumEntries) {
61 Map.reserve(NumEntries);
62 Vector.reserve(NumEntries);
63 }
64
65 [[nodiscard]] iterator begin() { return Vector.begin(); }
66 [[nodiscard]] const_iterator begin() const { return Vector.begin(); }
67 [[nodiscard]] iterator end() { return Vector.end(); }
68 [[nodiscard]] const_iterator end() const { return Vector.end(); }
69
70 [[nodiscard]] reverse_iterator rbegin() { return Vector.rbegin(); }
71 [[nodiscard]] const_reverse_iterator rbegin() const {
72 return Vector.rbegin();
73 }
74 [[nodiscard]] reverse_iterator rend() { return Vector.rend(); }
75 [[nodiscard]] const_reverse_iterator rend() const { return Vector.rend(); }
76
77 [[nodiscard]] bool empty() const { return Vector.empty(); }
78
79 [[nodiscard]] std::pair<KeyT, ValueT> &front() { return Vector.front(); }
80 [[nodiscard]] const std::pair<KeyT, ValueT> &front() const {
81 return Vector.front();
82 }
83 [[nodiscard]] std::pair<KeyT, ValueT> &back() { return Vector.back(); }
84 [[nodiscard]] const std::pair<KeyT, ValueT> &back() const {
85 return Vector.back();
86 }
87
88 void clear() {
89 Map.clear();
90 Vector.clear();
91 }
92
94 std::swap(Map, RHS.Map);
95 std::swap(Vector, RHS.Vector);
96 }
97
98 ValueT &operator[](const KeyT &Key) {
99 return try_emplace_impl(Key).first->second;
100 }
101
102 // Returns a copy of the value. Only allowed if ValueT is copyable.
103 [[nodiscard]] ValueT lookup(const KeyT &Key) const {
104 static_assert(std::is_copy_constructible_v<ValueT>,
105 "Cannot call lookup() if ValueT is not copyable.");
106 typename MapType::const_iterator Pos = Map.find(Key);
107 return Pos == Map.end()? ValueT() : Vector[Pos->second].second;
108 }
109
110 template <typename... Ts>
111 std::pair<iterator, bool> try_emplace(const KeyT &Key, Ts &&...Args) {
112 return try_emplace_impl(Key, std::forward<Ts>(Args)...);
113 }
114 template <typename... Ts>
115 std::pair<iterator, bool> try_emplace(KeyT &&Key, Ts &&...Args) {
116 return try_emplace_impl(std::move(Key), std::forward<Ts>(Args)...);
117 }
118
119 std::pair<iterator, bool> insert(const std::pair<KeyT, ValueT> &KV) {
120 return try_emplace_impl(KV.first, KV.second);
121 }
122 std::pair<iterator, bool> insert(std::pair<KeyT, ValueT> &&KV) {
123 return try_emplace_impl(std::move(KV.first), std::move(KV.second));
124 }
125
126 template <typename V>
127 std::pair<iterator, bool> insert_or_assign(const KeyT &Key, V &&Val) {
128 auto Ret = try_emplace(Key, std::forward<V>(Val));
129 if (!Ret.second)
130 Ret.first->second = std::forward<V>(Val);
131 return Ret;
132 }
133 template <typename V>
134 std::pair<iterator, bool> insert_or_assign(KeyT &&Key, V &&Val) {
135 auto Ret = try_emplace(std::move(Key), std::forward<V>(Val));
136 if (!Ret.second)
137 Ret.first->second = std::forward<V>(Val);
138 return Ret;
139 }
140
141 [[nodiscard]] bool contains(const KeyT &Key) const {
142 return Map.find(Key) != Map.end();
143 }
144
145 [[nodiscard]] size_type count(const KeyT &Key) const {
146 return contains(Key) ? 1 : 0;
147 }
148
149 [[nodiscard]] iterator find(const KeyT &Key) {
150 typename MapType::const_iterator Pos = Map.find(Key);
151 return Pos == Map.end() ? Vector.end() : (Vector.begin() + Pos->second);
152 }
153
154 [[nodiscard]] const_iterator find(const KeyT &Key) const {
155 typename MapType::const_iterator Pos = Map.find(Key);
156 return Pos == Map.end() ? Vector.end() : (Vector.begin() + Pos->second);
157 }
158
159 /// at - Return the entry for the specified key, or abort if no such
160 /// entry exists.
161 [[nodiscard]] ValueT &at(const KeyT &Key) {
162 auto Pos = Map.find(Key);
163 assert(Pos != Map.end() && "MapVector::at failed due to a missing key");
164 return Vector[Pos->second].second;
165 }
166
167 /// at - Return the entry for the specified key, or abort if no such
168 /// entry exists.
169 [[nodiscard]] const ValueT &at(const KeyT &Key) const {
170 auto Pos = Map.find(Key);
171 assert(Pos != Map.end() && "MapVector::at failed due to a missing key");
172 return Vector[Pos->second].second;
173 }
174
175 /// Remove the last element from the vector.
176 void pop_back() {
177 typename MapType::iterator Pos = Map.find(Vector.back().first);
178 Map.erase(Pos);
179 Vector.pop_back();
180 }
181
182 /// Remove the element given by Iterator.
183 ///
184 /// Returns an iterator to the element following the one which was removed,
185 /// which may be end().
186 ///
187 /// \note This is a deceivingly expensive operation (linear time). It's
188 /// usually better to use \a remove_if() if possible.
189 typename VectorType::iterator erase(typename VectorType::iterator Iterator) {
190 Map.erase(Iterator->first);
191 auto Next = Vector.erase(Iterator);
192 if (Next == Vector.end())
193 return Next;
194
195 // Update indices in the map.
196 size_t Index = Next - Vector.begin();
197 for (auto &I : Map) {
198 assert(I.second != Index && "Index was already erased!");
199 if (I.second > Index)
200 --I.second;
201 }
202 return Next;
203 }
204
205 /// Remove all elements with the key value Key.
206 ///
207 /// Returns the number of elements removed.
209 auto Iterator = find(Key);
210 if (Iterator == end())
211 return 0;
212 erase(Iterator);
213 return 1;
214 }
215
216 /// Remove the elements that match the predicate.
217 ///
218 /// Erase all elements that match \c Pred in a single pass. Takes linear
219 /// time.
220 template <class Predicate> void remove_if(Predicate Pred);
221
222private:
223 MapType Map;
224 VectorType Vector;
225
226 static_assert(
227 std::is_integral_v<typename MapType::mapped_type>,
228 "The mapped_type of the specified Map must be an integral type");
229
230 template <typename KeyArgT, typename... Ts>
231 std::pair<iterator, bool> try_emplace_impl(KeyArgT &&Key, Ts &&...Args) {
232 auto [It, Inserted] = Map.try_emplace(Key);
233 if (Inserted) {
234 It->second = Vector.size();
235 Vector.emplace_back(std::piecewise_construct,
236 std::forward_as_tuple(std::forward<KeyArgT>(Key)),
237 std::forward_as_tuple(std::forward<Ts>(Args)...));
238 return {std::prev(end()), true};
239 }
240 return {begin() + It->second, false};
241 }
242};
243
244template <typename KeyT, typename ValueT, typename MapType, typename VectorType>
245template <class Function>
247 auto O = Vector.begin();
248 for (auto I = O, E = Vector.end(); I != E; ++I) {
249 if (Pred(*I)) {
250 // Erase from the map.
251 Map.erase(I->first);
252 continue;
253 }
254
255 if (I != O) {
256 // Move the value and update the index in the map.
257 *O = std::move(*I);
258 Map[O->first] = O - Vector.begin();
259 }
260 ++O;
261 }
262 // Erase trailing entries in the vector.
263 Vector.erase(O, Vector.end());
264}
265
266/// A MapVector that performs no allocations if smaller than a certain
267/// size.
268template <typename KeyT, typename ValueT, unsigned N>
270 : MapVector<KeyT, ValueT, SmallDenseMap<KeyT, unsigned, N>,
271 SmallVector<std::pair<KeyT, ValueT>, N>> {
272};
273
274} // end namespace llvm
275
276#endif // LLVM_ADT_MAPVECTOR_H
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
This file defines the DenseMap class.
#define I(x, y, z)
Definition MD5.cpp:57
This file defines the SmallVector class.
Value * RHS
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
Definition ArrayRef.h:40
This class implements a map that also provides access to all stored values in a deterministic order.
Definition MapVector.h:36
std::pair< iterator, bool > try_emplace(KeyT &&Key, Ts &&...Args)
Definition MapVector.h:115
size_type count(const KeyT &Key) const
Definition MapVector.h:145
typename VectorType::iterator iterator
Definition MapVector.h:42
iterator end()
Definition MapVector.h:67
void pop_back()
Remove the last element from the vector.
Definition MapVector.h:176
const_reverse_iterator rbegin() const
Definition MapVector.h:71
void swap(MapVector &RHS)
Definition MapVector.h:93
reverse_iterator rend()
Definition MapVector.h:74
ValueT & operator[](const KeyT &Key)
Definition MapVector.h:98
const_iterator end() const
Definition MapVector.h:68
const ValueT & at(const KeyT &Key) const
at - Return the entry for the specified key, or abort if no such entry exists.
Definition MapVector.h:169
VectorType::iterator erase(typename VectorType::iterator Iterator)
Remove the element given by Iterator.
Definition MapVector.h:189
std::pair< iterator, bool > insert_or_assign(KeyT &&Key, V &&Val)
Definition MapVector.h:134
VectorType takeVector()
Clear the MapVector and return the underlying vector.
Definition MapVector.h:48
typename VectorType::size_type size_type
Definition MapVector.h:40
const std::pair< KeyT, ValueT > & back() const
Definition MapVector.h:84
const std::pair< KeyT, ValueT > & front() const
Definition MapVector.h:80
typename VectorType::const_reverse_iterator const_reverse_iterator
Definition MapVector.h:45
typename VectorType::value_type value_type
Definition MapVector.h:39
iterator find(const KeyT &Key)
Definition MapVector.h:149
void remove_if(Predicate Pred)
Remove the elements that match the predicate.
bool contains(const KeyT &Key) const
Definition MapVector.h:141
bool empty() const
Definition MapVector.h:77
const_iterator begin() const
Definition MapVector.h:66
iterator begin()
Definition MapVector.h:65
ValueT & at(const KeyT &Key)
at - Return the entry for the specified key, or abort if no such entry exists.
Definition MapVector.h:161
std::pair< iterator, bool > insert_or_assign(const KeyT &Key, V &&Val)
Definition MapVector.h:127
const_iterator find(const KeyT &Key) const
Definition MapVector.h:154
std::pair< iterator, bool > try_emplace(const KeyT &Key, Ts &&...Args)
Definition MapVector.h:111
std::pair< iterator, bool > insert(const std::pair< KeyT, ValueT > &KV)
Definition MapVector.h:119
ArrayRef< value_type > getArrayRef() const
Returns an array reference of the underlying vector.
Definition MapVector.h:54
ValueT lookup(const KeyT &Key) const
Definition MapVector.h:103
void reserve(size_type NumEntries)
Grow the MapVector so that it can contain at least NumEntries items before resizing again.
Definition MapVector.h:60
typename VectorType::reverse_iterator reverse_iterator
Definition MapVector.h:44
size_type size() const
Definition MapVector.h:56
size_type erase(const KeyT &Key)
Remove all elements with the key value Key.
Definition MapVector.h:208
typename VectorType::const_iterator const_iterator
Definition MapVector.h:43
std::pair< KeyT, ValueT > & front()
Definition MapVector.h:79
std::pair< iterator, bool > insert(std::pair< KeyT, ValueT > &&KV)
Definition MapVector.h:122
const_reverse_iterator rend() const
Definition MapVector.h:75
reverse_iterator rbegin()
Definition MapVector.h:70
std::pair< KeyT, ValueT > & back()
Definition MapVector.h:83
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
Base class of all SIMD vector types.
This is an optimization pass for GlobalISel generic memory operations.
LLVM_ATTRIBUTE_VISIBILITY_DEFAULT AnalysisKey InnerAnalysisManagerProxy< AnalysisManagerT, IRUnitT, ExtraArgTs... >::Key
FunctionAddr VTableAddr Next
Definition InstrProf.h:141
void swap(llvm::BitVector &LHS, llvm::BitVector &RHS)
Implement std::swap in terms of BitVector swap.
Definition BitVector.h:869
A MapVector that performs no allocations if smaller than a certain size.
Definition MapVector.h:271