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>,
35 typename VectorType = SmallVector<std::pair<KeyT, ValueT>, 0>>
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.
49 Map.clear();
50 return std::move(Vector);
51 }
52
53 /// Returns an array reference of the underlying vector.
54 ArrayRef<value_type> getArrayRef() const { return Vector; }
55
56 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 iterator begin() { return Vector.begin(); }
66 const_iterator begin() const { return Vector.begin(); }
67 iterator end() { return Vector.end(); }
68 const_iterator end() const { return Vector.end(); }
69
70 reverse_iterator rbegin() { return Vector.rbegin(); }
71 const_reverse_iterator rbegin() const { return Vector.rbegin(); }
72 reverse_iterator rend() { return Vector.rend(); }
73 const_reverse_iterator rend() const { return Vector.rend(); }
74
75 bool empty() const {
76 return Vector.empty();
77 }
78
79 std::pair<KeyT, ValueT> &front() { return Vector.front(); }
80 const std::pair<KeyT, ValueT> &front() const { return Vector.front(); }
81 std::pair<KeyT, ValueT> &back() { return Vector.back(); }
82 const std::pair<KeyT, ValueT> &back() const { return Vector.back(); }
83
84 void clear() {
85 Map.clear();
86 Vector.clear();
87 }
88
90 std::swap(Map, RHS.Map);
91 std::swap(Vector, RHS.Vector);
92 }
93
94 ValueT &operator[](const KeyT &Key) {
95 return try_emplace_impl(Key).first->second;
96 }
97
98 // Returns a copy of the value. Only allowed if ValueT is copyable.
99 ValueT lookup(const KeyT &Key) const {
100 static_assert(std::is_copy_constructible_v<ValueT>,
101 "Cannot call lookup() if ValueT is not copyable.");
102 typename MapType::const_iterator Pos = Map.find(Key);
103 return Pos == Map.end()? ValueT() : Vector[Pos->second].second;
104 }
105
106 template <typename... Ts>
107 std::pair<iterator, bool> try_emplace(const KeyT &Key, Ts &&...Args) {
108 return try_emplace_impl(Key, std::forward<Ts>(Args)...);
109 }
110 template <typename... Ts>
111 std::pair<iterator, bool> try_emplace(KeyT &&Key, Ts &&...Args) {
112 return try_emplace_impl(std::move(Key), std::forward<Ts>(Args)...);
113 }
114
115 std::pair<iterator, bool> insert(const std::pair<KeyT, ValueT> &KV) {
116 return try_emplace_impl(KV.first, KV.second);
117 }
118 std::pair<iterator, bool> insert(std::pair<KeyT, ValueT> &&KV) {
119 return try_emplace_impl(std::move(KV.first), std::move(KV.second));
120 }
121
122 template <typename V>
123 std::pair<iterator, bool> insert_or_assign(const KeyT &Key, V &&Val) {
124 auto Ret = try_emplace(Key, std::forward<V>(Val));
125 if (!Ret.second)
126 Ret.first->second = std::forward<V>(Val);
127 return Ret;
128 }
129 template <typename V>
130 std::pair<iterator, bool> insert_or_assign(KeyT &&Key, V &&Val) {
131 auto Ret = try_emplace(std::move(Key), std::forward<V>(Val));
132 if (!Ret.second)
133 Ret.first->second = std::forward<V>(Val);
134 return Ret;
135 }
136
137 bool contains(const KeyT &Key) const { return Map.find(Key) != Map.end(); }
138
139 size_type count(const KeyT &Key) const { return contains(Key) ? 1 : 0; }
140
141 iterator find(const KeyT &Key) {
142 typename MapType::const_iterator Pos = Map.find(Key);
143 return Pos == Map.end()? Vector.end() :
144 (Vector.begin() + Pos->second);
145 }
146
147 const_iterator find(const KeyT &Key) const {
148 typename MapType::const_iterator Pos = Map.find(Key);
149 return Pos == Map.end()? Vector.end() :
150 (Vector.begin() + Pos->second);
151 }
152
153 /// Remove the last element from the vector.
154 void pop_back() {
155 typename MapType::iterator Pos = Map.find(Vector.back().first);
156 Map.erase(Pos);
157 Vector.pop_back();
158 }
159
160 /// Remove the element given by Iterator.
161 ///
162 /// Returns an iterator to the element following the one which was removed,
163 /// which may be end().
164 ///
165 /// \note This is a deceivingly expensive operation (linear time). It's
166 /// usually better to use \a remove_if() if possible.
167 typename VectorType::iterator erase(typename VectorType::iterator Iterator) {
168 Map.erase(Iterator->first);
169 auto Next = Vector.erase(Iterator);
170 if (Next == Vector.end())
171 return Next;
172
173 // Update indices in the map.
174 size_t Index = Next - Vector.begin();
175 for (auto &I : Map) {
176 assert(I.second != Index && "Index was already erased!");
177 if (I.second > Index)
178 --I.second;
179 }
180 return Next;
181 }
182
183 /// Remove all elements with the key value Key.
184 ///
185 /// Returns the number of elements removed.
186 size_type erase(const KeyT &Key) {
187 auto Iterator = find(Key);
188 if (Iterator == end())
189 return 0;
190 erase(Iterator);
191 return 1;
192 }
193
194 /// Remove the elements that match the predicate.
195 ///
196 /// Erase all elements that match \c Pred in a single pass. Takes linear
197 /// time.
198 template <class Predicate> void remove_if(Predicate Pred);
199
200private:
201 MapType Map;
202 VectorType Vector;
203
204 static_assert(
205 std::is_integral_v<typename MapType::mapped_type>,
206 "The mapped_type of the specified Map must be an integral type");
207
208 template <typename KeyArgT, typename... Ts>
209 std::pair<iterator, bool> try_emplace_impl(KeyArgT &&Key, Ts &&...Args) {
210 auto [It, Inserted] = Map.try_emplace(Key);
211 if (Inserted) {
212 It->second = Vector.size();
213 Vector.emplace_back(std::piecewise_construct,
214 std::forward_as_tuple(std::forward<KeyArgT>(Key)),
215 std::forward_as_tuple(std::forward<Ts>(Args)...));
216 return {std::prev(end()), true};
217 }
218 return {begin() + It->second, false};
219 }
220};
221
222template <typename KeyT, typename ValueT, typename MapType, typename VectorType>
223template <class Function>
225 auto O = Vector.begin();
226 for (auto I = O, E = Vector.end(); I != E; ++I) {
227 if (Pred(*I)) {
228 // Erase from the map.
229 Map.erase(I->first);
230 continue;
231 }
232
233 if (I != O) {
234 // Move the value and update the index in the map.
235 *O = std::move(*I);
236 Map[O->first] = O - Vector.begin();
237 }
238 ++O;
239 }
240 // Erase trailing entries in the vector.
241 Vector.erase(O, Vector.end());
242}
243
244/// A MapVector that performs no allocations if smaller than a certain
245/// size.
246template <typename KeyT, typename ValueT, unsigned N>
248 : MapVector<KeyT, ValueT, SmallDenseMap<KeyT, unsigned, N>,
249 SmallVector<std::pair<KeyT, ValueT>, N>> {
250};
251
252} // end namespace llvm
253
254#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.
uint32_t Index
#define I(x, y, z)
Definition: MD5.cpp:58
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:41
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:111
size_type count(const KeyT &Key) const
Definition: MapVector.h:139
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:154
const_reverse_iterator rbegin() const
Definition: MapVector.h:71
void swap(MapVector &RHS)
Definition: MapVector.h:89
reverse_iterator rend()
Definition: MapVector.h:72
ValueT & operator[](const KeyT &Key)
Definition: MapVector.h:94
const_iterator end() const
Definition: MapVector.h:68
VectorType::iterator erase(typename VectorType::iterator Iterator)
Remove the element given by Iterator.
Definition: MapVector.h:167
std::pair< iterator, bool > insert_or_assign(KeyT &&Key, V &&Val)
Definition: MapVector.h:130
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:82
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:141
void remove_if(Predicate Pred)
Remove the elements that match the predicate.
bool contains(const KeyT &Key) const
Definition: MapVector.h:137
bool empty() const
Definition: MapVector.h:75
const_iterator begin() const
Definition: MapVector.h:66
iterator begin()
Definition: MapVector.h:65
std::pair< iterator, bool > insert_or_assign(const KeyT &Key, V &&Val)
Definition: MapVector.h:123
const_iterator find(const KeyT &Key) const
Definition: MapVector.h:147
std::pair< iterator, bool > try_emplace(const KeyT &Key, Ts &&...Args)
Definition: MapVector.h:107
std::pair< iterator, bool > insert(const std::pair< KeyT, ValueT > &KV)
Definition: MapVector.h:115
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:99
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:186
typename VectorType::const_iterator const_iterator
Definition: MapVector.h:43
std::pair< KeyT, ValueT > & front()
Definition: MapVector.h:79
void clear()
Definition: MapVector.h:84
std::pair< iterator, bool > insert(std::pair< KeyT, ValueT > &&KV)
Definition: MapVector.h:118
const_reverse_iterator rend() const
Definition: MapVector.h:73
reverse_iterator rbegin()
Definition: MapVector.h:70
std::pair< KeyT, ValueT > & back()
Definition: MapVector.h:81
Base class of all SIMD vector types.
Definition: DerivedTypes.h:430
This is an optimization pass for GlobalISel generic memory operations.
Definition: AddressRanges.h:18
void swap(llvm::BitVector &LHS, llvm::BitVector &RHS)
Implement std::swap in terms of BitVector swap.
Definition: BitVector.h:858
A MapVector that performs no allocations if smaller than a certain size.
Definition: MapVector.h:249