MapVector.h 8.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250
  1. #pragma once
  2. #ifdef __GNUC__
  3. #pragma GCC diagnostic push
  4. #pragma GCC diagnostic ignored "-Wunused-parameter"
  5. #endif
  6. //===- llvm/ADT/MapVector.h - Map w/ deterministic value order --*- C++ -*-===//
  7. //
  8. // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
  9. // See https://llvm.org/LICENSE.txt for license information.
  10. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
  11. //
  12. //===----------------------------------------------------------------------===//
  13. //
  14. // This file implements a map that provides insertion order iteration. The
  15. // interface is purposefully minimal. The key is assumed to be cheap to copy
  16. // and 2 copies are kept, one for indexing in a DenseMap, one for iteration in
  17. // a std::vector.
  18. //
  19. //===----------------------------------------------------------------------===//
  20. #ifndef LLVM_ADT_MAPVECTOR_H
  21. #define LLVM_ADT_MAPVECTOR_H
  22. #include "llvm/ADT/DenseMap.h"
  23. #include "llvm/ADT/SmallVector.h"
  24. #include <algorithm>
  25. #include <cassert>
  26. #include <cstddef>
  27. #include <iterator>
  28. #include <type_traits>
  29. #include <utility>
  30. #include <vector>
  31. namespace llvm {
  32. /// This class implements a map that also provides access to all stored values
  33. /// in a deterministic order. The values are kept in a std::vector and the
  34. /// mapping is done with DenseMap from Keys to indexes in that vector.
  35. template<typename KeyT, typename ValueT,
  36. typename MapType = DenseMap<KeyT, unsigned>,
  37. typename VectorType = std::vector<std::pair<KeyT, ValueT>>>
  38. class MapVector {
  39. MapType Map;
  40. VectorType Vector;
  41. static_assert(
  42. std::is_integral<typename MapType::mapped_type>::value,
  43. "The mapped_type of the specified Map must be an integral type");
  44. public:
  45. using value_type = typename VectorType::value_type;
  46. using size_type = typename VectorType::size_type;
  47. using iterator = typename VectorType::iterator;
  48. using const_iterator = typename VectorType::const_iterator;
  49. using reverse_iterator = typename VectorType::reverse_iterator;
  50. using const_reverse_iterator = typename VectorType::const_reverse_iterator;
  51. /// Clear the MapVector and return the underlying vector.
  52. VectorType takeVector() {
  53. Map.clear();
  54. return std::move(Vector);
  55. }
  56. size_type size() const { return Vector.size(); }
  57. /// Grow the MapVector so that it can contain at least \p NumEntries items
  58. /// before resizing again.
  59. void reserve(size_type NumEntries) {
  60. Map.reserve(NumEntries);
  61. Vector.reserve(NumEntries);
  62. }
  63. iterator begin() { return Vector.begin(); }
  64. const_iterator begin() const { return Vector.begin(); }
  65. iterator end() { return Vector.end(); }
  66. const_iterator end() const { return Vector.end(); }
  67. reverse_iterator rbegin() { return Vector.rbegin(); }
  68. const_reverse_iterator rbegin() const { return Vector.rbegin(); }
  69. reverse_iterator rend() { return Vector.rend(); }
  70. const_reverse_iterator rend() const { return Vector.rend(); }
  71. bool empty() const {
  72. return Vector.empty();
  73. }
  74. std::pair<KeyT, ValueT> &front() { return Vector.front(); }
  75. const std::pair<KeyT, ValueT> &front() const { return Vector.front(); }
  76. std::pair<KeyT, ValueT> &back() { return Vector.back(); }
  77. const std::pair<KeyT, ValueT> &back() const { return Vector.back(); }
  78. void clear() {
  79. Map.clear();
  80. Vector.clear();
  81. }
  82. void swap(MapVector &RHS) {
  83. std::swap(Map, RHS.Map);
  84. std::swap(Vector, RHS.Vector);
  85. }
  86. ValueT &operator[](const KeyT &Key) {
  87. std::pair<KeyT, typename MapType::mapped_type> Pair = std::make_pair(Key, 0);
  88. std::pair<typename MapType::iterator, bool> Result = Map.insert(Pair);
  89. auto &I = Result.first->second;
  90. if (Result.second) {
  91. Vector.push_back(std::make_pair(Key, ValueT()));
  92. I = Vector.size() - 1;
  93. }
  94. return Vector[I].second;
  95. }
  96. // Returns a copy of the value. Only allowed if ValueT is copyable.
  97. ValueT lookup(const KeyT &Key) const {
  98. static_assert(std::is_copy_constructible<ValueT>::value,
  99. "Cannot call lookup() if ValueT is not copyable.");
  100. typename MapType::const_iterator Pos = Map.find(Key);
  101. return Pos == Map.end()? ValueT() : Vector[Pos->second].second;
  102. }
  103. std::pair<iterator, bool> insert(const std::pair<KeyT, ValueT> &KV) {
  104. std::pair<KeyT, typename MapType::mapped_type> Pair = std::make_pair(KV.first, 0);
  105. std::pair<typename MapType::iterator, bool> Result = Map.insert(Pair);
  106. auto &I = Result.first->second;
  107. if (Result.second) {
  108. Vector.push_back(std::make_pair(KV.first, KV.second));
  109. I = Vector.size() - 1;
  110. return std::make_pair(std::prev(end()), true);
  111. }
  112. return std::make_pair(begin() + I, false);
  113. }
  114. std::pair<iterator, bool> insert(std::pair<KeyT, ValueT> &&KV) {
  115. // Copy KV.first into the map, then move it into the vector.
  116. std::pair<KeyT, typename MapType::mapped_type> Pair = std::make_pair(KV.first, 0);
  117. std::pair<typename MapType::iterator, bool> Result = Map.insert(Pair);
  118. auto &I = Result.first->second;
  119. if (Result.second) {
  120. Vector.push_back(std::move(KV));
  121. I = Vector.size() - 1;
  122. return std::make_pair(std::prev(end()), true);
  123. }
  124. return std::make_pair(begin() + I, false);
  125. }
  126. size_type count(const KeyT &Key) const {
  127. typename MapType::const_iterator Pos = Map.find(Key);
  128. return Pos == Map.end()? 0 : 1;
  129. }
  130. iterator find(const KeyT &Key) {
  131. typename MapType::const_iterator Pos = Map.find(Key);
  132. return Pos == Map.end()? Vector.end() :
  133. (Vector.begin() + Pos->second);
  134. }
  135. const_iterator find(const KeyT &Key) const {
  136. typename MapType::const_iterator Pos = Map.find(Key);
  137. return Pos == Map.end()? Vector.end() :
  138. (Vector.begin() + Pos->second);
  139. }
  140. /// Remove the last element from the vector.
  141. void pop_back() {
  142. typename MapType::iterator Pos = Map.find(Vector.back().first);
  143. Map.erase(Pos);
  144. Vector.pop_back();
  145. }
  146. /// Remove the element given by Iterator.
  147. ///
  148. /// Returns an iterator to the element following the one which was removed,
  149. /// which may be end().
  150. ///
  151. /// \note This is a deceivingly expensive operation (linear time). It's
  152. /// usually better to use \a remove_if() if possible.
  153. typename VectorType::iterator erase(typename VectorType::iterator Iterator) {
  154. Map.erase(Iterator->first);
  155. auto Next = Vector.erase(Iterator);
  156. if (Next == Vector.end())
  157. return Next;
  158. // Update indices in the map.
  159. size_t Index = Next - Vector.begin();
  160. for (auto &I : Map) {
  161. assert(I.second != Index && "Index was already erased!");
  162. if (I.second > Index)
  163. --I.second;
  164. }
  165. return Next;
  166. }
  167. /// Remove all elements with the key value Key.
  168. ///
  169. /// Returns the number of elements removed.
  170. size_type erase(const KeyT &Key) {
  171. auto Iterator = find(Key);
  172. if (Iterator == end())
  173. return 0;
  174. erase(Iterator);
  175. return 1;
  176. }
  177. /// Remove the elements that match the predicate.
  178. ///
  179. /// Erase all elements that match \c Pred in a single pass. Takes linear
  180. /// time.
  181. template <class Predicate> void remove_if(Predicate Pred);
  182. };
  183. template <typename KeyT, typename ValueT, typename MapType, typename VectorType>
  184. template <class Function>
  185. void MapVector<KeyT, ValueT, MapType, VectorType>::remove_if(Function Pred) {
  186. auto O = Vector.begin();
  187. for (auto I = O, E = Vector.end(); I != E; ++I) {
  188. if (Pred(*I)) {
  189. // Erase from the map.
  190. Map.erase(I->first);
  191. continue;
  192. }
  193. if (I != O) {
  194. // Move the value and update the index in the map.
  195. *O = std::move(*I);
  196. Map[O->first] = O - Vector.begin();
  197. }
  198. ++O;
  199. }
  200. // Erase trailing entries in the vector.
  201. Vector.erase(O, Vector.end());
  202. }
  203. /// A MapVector that performs no allocations if smaller than a certain
  204. /// size.
  205. template <typename KeyT, typename ValueT, unsigned N>
  206. struct SmallMapVector
  207. : MapVector<KeyT, ValueT, SmallDenseMap<KeyT, unsigned, N>,
  208. SmallVector<std::pair<KeyT, ValueT>, N>> {
  209. };
  210. } // end namespace llvm
  211. #endif // LLVM_ADT_MAPVECTOR_H
  212. #ifdef __GNUC__
  213. #pragma GCC diagnostic pop
  214. #endif