MapVector.h 8.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251
  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. /// \file
  15. /// This file implements a map that provides insertion order iteration. The
  16. /// interface is purposefully minimal. The key is assumed to be cheap to copy
  17. /// and 2 copies are kept, one for indexing in a DenseMap, one for iteration in
  18. /// a std::vector.
  19. ///
  20. //===----------------------------------------------------------------------===//
  21. #ifndef LLVM_ADT_MAPVECTOR_H
  22. #define LLVM_ADT_MAPVECTOR_H
  23. #include "llvm/ADT/DenseMap.h"
  24. #include "llvm/ADT/SmallVector.h"
  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 key_type = KeyT;
  46. using value_type = typename VectorType::value_type;
  47. using size_type = typename VectorType::size_type;
  48. using iterator = typename VectorType::iterator;
  49. using const_iterator = typename VectorType::const_iterator;
  50. using reverse_iterator = typename VectorType::reverse_iterator;
  51. using const_reverse_iterator = typename VectorType::const_reverse_iterator;
  52. /// Clear the MapVector and return the underlying vector.
  53. VectorType takeVector() {
  54. Map.clear();
  55. return std::move(Vector);
  56. }
  57. size_type size() const { return Vector.size(); }
  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. iterator begin() { return Vector.begin(); }
  65. const_iterator begin() const { return Vector.begin(); }
  66. iterator end() { return Vector.end(); }
  67. const_iterator end() const { return Vector.end(); }
  68. reverse_iterator rbegin() { return Vector.rbegin(); }
  69. const_reverse_iterator rbegin() const { return Vector.rbegin(); }
  70. reverse_iterator rend() { return Vector.rend(); }
  71. const_reverse_iterator rend() const { return Vector.rend(); }
  72. bool empty() const {
  73. return Vector.empty();
  74. }
  75. std::pair<KeyT, ValueT> &front() { return Vector.front(); }
  76. const std::pair<KeyT, ValueT> &front() const { return Vector.front(); }
  77. std::pair<KeyT, ValueT> &back() { return Vector.back(); }
  78. const std::pair<KeyT, ValueT> &back() const { return Vector.back(); }
  79. void clear() {
  80. Map.clear();
  81. Vector.clear();
  82. }
  83. void swap(MapVector &RHS) {
  84. std::swap(Map, RHS.Map);
  85. std::swap(Vector, RHS.Vector);
  86. }
  87. ValueT &operator[](const KeyT &Key) {
  88. std::pair<KeyT, typename MapType::mapped_type> Pair = std::make_pair(Key, 0);
  89. std::pair<typename MapType::iterator, bool> Result = Map.insert(Pair);
  90. auto &I = Result.first->second;
  91. if (Result.second) {
  92. Vector.push_back(std::make_pair(Key, ValueT()));
  93. I = Vector.size() - 1;
  94. }
  95. return Vector[I].second;
  96. }
  97. // Returns a copy of the value. Only allowed if ValueT is copyable.
  98. ValueT lookup(const KeyT &Key) const {
  99. static_assert(std::is_copy_constructible<ValueT>::value,
  100. "Cannot call lookup() if ValueT is not copyable.");
  101. typename MapType::const_iterator Pos = Map.find(Key);
  102. return Pos == Map.end()? ValueT() : Vector[Pos->second].second;
  103. }
  104. std::pair<iterator, bool> insert(const std::pair<KeyT, ValueT> &KV) {
  105. std::pair<KeyT, typename MapType::mapped_type> Pair = std::make_pair(KV.first, 0);
  106. std::pair<typename MapType::iterator, bool> Result = Map.insert(Pair);
  107. auto &I = Result.first->second;
  108. if (Result.second) {
  109. Vector.push_back(std::make_pair(KV.first, KV.second));
  110. I = Vector.size() - 1;
  111. return std::make_pair(std::prev(end()), true);
  112. }
  113. return std::make_pair(begin() + I, false);
  114. }
  115. std::pair<iterator, bool> insert(std::pair<KeyT, ValueT> &&KV) {
  116. // Copy KV.first into the map, then move it into the vector.
  117. std::pair<KeyT, typename MapType::mapped_type> Pair = std::make_pair(KV.first, 0);
  118. std::pair<typename MapType::iterator, bool> Result = Map.insert(Pair);
  119. auto &I = Result.first->second;
  120. if (Result.second) {
  121. Vector.push_back(std::move(KV));
  122. I = Vector.size() - 1;
  123. return std::make_pair(std::prev(end()), true);
  124. }
  125. return std::make_pair(begin() + I, false);
  126. }
  127. size_type count(const KeyT &Key) const {
  128. typename MapType::const_iterator Pos = Map.find(Key);
  129. return Pos == Map.end()? 0 : 1;
  130. }
  131. iterator find(const KeyT &Key) {
  132. typename MapType::const_iterator Pos = Map.find(Key);
  133. return Pos == Map.end()? Vector.end() :
  134. (Vector.begin() + Pos->second);
  135. }
  136. const_iterator find(const KeyT &Key) const {
  137. typename MapType::const_iterator Pos = Map.find(Key);
  138. return Pos == Map.end()? Vector.end() :
  139. (Vector.begin() + Pos->second);
  140. }
  141. /// Remove the last element from the vector.
  142. void pop_back() {
  143. typename MapType::iterator Pos = Map.find(Vector.back().first);
  144. Map.erase(Pos);
  145. Vector.pop_back();
  146. }
  147. /// Remove the element given by Iterator.
  148. ///
  149. /// Returns an iterator to the element following the one which was removed,
  150. /// which may be end().
  151. ///
  152. /// \note This is a deceivingly expensive operation (linear time). It's
  153. /// usually better to use \a remove_if() if possible.
  154. typename VectorType::iterator erase(typename VectorType::iterator Iterator) {
  155. Map.erase(Iterator->first);
  156. auto Next = Vector.erase(Iterator);
  157. if (Next == Vector.end())
  158. return Next;
  159. // Update indices in the map.
  160. size_t Index = Next - Vector.begin();
  161. for (auto &I : Map) {
  162. assert(I.second != Index && "Index was already erased!");
  163. if (I.second > Index)
  164. --I.second;
  165. }
  166. return Next;
  167. }
  168. /// Remove all elements with the key value Key.
  169. ///
  170. /// Returns the number of elements removed.
  171. size_type erase(const KeyT &Key) {
  172. auto Iterator = find(Key);
  173. if (Iterator == end())
  174. return 0;
  175. erase(Iterator);
  176. return 1;
  177. }
  178. /// Remove the elements that match the predicate.
  179. ///
  180. /// Erase all elements that match \c Pred in a single pass. Takes linear
  181. /// time.
  182. template <class Predicate> void remove_if(Predicate Pred);
  183. };
  184. template <typename KeyT, typename ValueT, typename MapType, typename VectorType>
  185. template <class Function>
  186. void MapVector<KeyT, ValueT, MapType, VectorType>::remove_if(Function Pred) {
  187. auto O = Vector.begin();
  188. for (auto I = O, E = Vector.end(); I != E; ++I) {
  189. if (Pred(*I)) {
  190. // Erase from the map.
  191. Map.erase(I->first);
  192. continue;
  193. }
  194. if (I != O) {
  195. // Move the value and update the index in the map.
  196. *O = std::move(*I);
  197. Map[O->first] = O - Vector.begin();
  198. }
  199. ++O;
  200. }
  201. // Erase trailing entries in the vector.
  202. Vector.erase(O, Vector.end());
  203. }
  204. /// A MapVector that performs no allocations if smaller than a certain
  205. /// size.
  206. template <typename KeyT, typename ValueT, unsigned N>
  207. struct SmallMapVector
  208. : MapVector<KeyT, ValueT, SmallDenseMap<KeyT, unsigned, N>,
  209. SmallVector<std::pair<KeyT, ValueT>, N>> {
  210. };
  211. } // end namespace llvm
  212. #endif // LLVM_ADT_MAPVECTOR_H
  213. #ifdef __GNUC__
  214. #pragma GCC diagnostic pop
  215. #endif