BlotMapVector.h 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108
  1. //===- BlotMapVector.h - A MapVector with the blot operation -*- C++ -*----===//
  2. //
  3. // The LLVM Compiler Infrastructure
  4. //
  5. // This file is distributed under the University of Illinois Open Source
  6. // License. See LICENSE.TXT for details.
  7. //
  8. //===----------------------------------------------------------------------===//
  9. #include "llvm/ADT/DenseMap.h"
  10. #include <vector>
  11. #include <algorithm>
  12. namespace llvm {
  13. /// \brief An associative container with fast insertion-order (deterministic)
  14. /// iteration over its elements. Plus the special blot operation.
  15. template <class KeyT, class ValueT> class BlotMapVector {
  16. /// Map keys to indices in Vector.
  17. typedef DenseMap<KeyT, size_t> MapTy;
  18. MapTy Map;
  19. typedef std::vector<std::pair<KeyT, ValueT>> VectorTy;
  20. /// Keys and values.
  21. VectorTy Vector;
  22. public:
  23. typedef typename VectorTy::iterator iterator;
  24. typedef typename VectorTy::const_iterator const_iterator;
  25. iterator begin() { return Vector.begin(); }
  26. iterator end() { return Vector.end(); }
  27. const_iterator begin() const { return Vector.begin(); }
  28. const_iterator end() const { return Vector.end(); }
  29. #ifdef XDEBUG
  30. ~BlotMapVector() {
  31. assert(Vector.size() >= Map.size()); // May differ due to blotting.
  32. for (typename MapTy::const_iterator I = Map.begin(), E = Map.end(); I != E;
  33. ++I) {
  34. assert(I->second < Vector.size());
  35. assert(Vector[I->second].first == I->first);
  36. }
  37. for (typename VectorTy::const_iterator I = Vector.begin(), E = Vector.end();
  38. I != E; ++I)
  39. assert(!I->first || (Map.count(I->first) &&
  40. Map[I->first] == size_t(I - Vector.begin())));
  41. }
  42. #endif
  43. ValueT &operator[](const KeyT &Arg) {
  44. std::pair<typename MapTy::iterator, bool> Pair =
  45. Map.insert(std::make_pair(Arg, size_t(0)));
  46. if (Pair.second) {
  47. size_t Num = Vector.size();
  48. Pair.first->second = Num;
  49. Vector.push_back(std::make_pair(Arg, ValueT()));
  50. return Vector[Num].second;
  51. }
  52. return Vector[Pair.first->second].second;
  53. }
  54. std::pair<iterator, bool> insert(const std::pair<KeyT, ValueT> &InsertPair) {
  55. std::pair<typename MapTy::iterator, bool> Pair =
  56. Map.insert(std::make_pair(InsertPair.first, size_t(0)));
  57. if (Pair.second) {
  58. size_t Num = Vector.size();
  59. Pair.first->second = Num;
  60. Vector.push_back(InsertPair);
  61. return std::make_pair(Vector.begin() + Num, true);
  62. }
  63. return std::make_pair(Vector.begin() + Pair.first->second, false);
  64. }
  65. iterator find(const KeyT &Key) {
  66. typename MapTy::iterator It = Map.find(Key);
  67. if (It == Map.end())
  68. return Vector.end();
  69. return Vector.begin() + It->second;
  70. }
  71. const_iterator find(const KeyT &Key) const {
  72. typename MapTy::const_iterator It = Map.find(Key);
  73. if (It == Map.end())
  74. return Vector.end();
  75. return Vector.begin() + It->second;
  76. }
  77. /// This is similar to erase, but instead of removing the element from the
  78. /// vector, it just zeros out the key in the vector. This leaves iterators
  79. /// intact, but clients must be prepared for zeroed-out keys when iterating.
  80. void blot(const KeyT &Key) {
  81. typename MapTy::iterator It = Map.find(Key);
  82. if (It == Map.end())
  83. return;
  84. Vector[It->second].first = KeyT();
  85. Map.erase(It);
  86. }
  87. void clear() {
  88. Map.clear();
  89. Vector.clear();
  90. }
  91. bool empty() const {
  92. assert(Map.empty() == Vector.empty());
  93. return Map.empty();
  94. }
  95. };
  96. } //