]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/llvm/lib/Transforms/ObjCARC/BlotMapVector.h
Merge clang 7.0.1 and several follow-up changes
[FreeBSD/FreeBSD.git] / contrib / llvm / lib / Transforms / ObjCARC / BlotMapVector.h
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
10 #ifndef LLVM_LIB_TRANSFORMS_OBJCARC_BLOTMAPVECTOR_H
11 #define LLVM_LIB_TRANSFORMS_OBJCARC_BLOTMAPVECTOR_H
12
13 #include "llvm/ADT/DenseMap.h"
14 #include <cassert>
15 #include <cstddef>
16 #include <utility>
17 #include <vector>
18
19 namespace llvm {
20
21 /// An associative container with fast insertion-order (deterministic)
22 /// iteration over its elements. Plus the special blot operation.
23 template <class KeyT, class ValueT> class BlotMapVector {
24   /// Map keys to indices in Vector.
25   using MapTy = DenseMap<KeyT, size_t>;
26   MapTy Map;
27
28   /// Keys and values.
29   using VectorTy = std::vector<std::pair<KeyT, ValueT>>;
30   VectorTy Vector;
31
32 public:
33 #ifdef EXPENSIVE_CHECKS
34   ~BlotMapVector() {
35     assert(Vector.size() >= Map.size()); // May differ due to blotting.
36     for (typename MapTy::const_iterator I = Map.begin(), E = Map.end(); I != E;
37          ++I) {
38       assert(I->second < Vector.size());
39       assert(Vector[I->second].first == I->first);
40     }
41     for (typename VectorTy::const_iterator I = Vector.begin(), E = Vector.end();
42          I != E; ++I)
43       assert(!I->first || (Map.count(I->first) &&
44                            Map[I->first] == size_t(I - Vector.begin())));
45   }
46 #endif
47
48   using iterator = typename VectorTy::iterator;
49   using const_iterator = typename VectorTy::const_iterator;
50
51   iterator begin() { return Vector.begin(); }
52   iterator end() { return Vector.end(); }
53   const_iterator begin() const { return Vector.begin(); }
54   const_iterator end() const { return Vector.end(); }
55
56   ValueT &operator[](const KeyT &Arg) {
57     std::pair<typename MapTy::iterator, bool> Pair =
58         Map.insert(std::make_pair(Arg, size_t(0)));
59     if (Pair.second) {
60       size_t Num = Vector.size();
61       Pair.first->second = Num;
62       Vector.push_back(std::make_pair(Arg, ValueT()));
63       return Vector[Num].second;
64     }
65     return Vector[Pair.first->second].second;
66   }
67
68   std::pair<iterator, bool> insert(const std::pair<KeyT, ValueT> &InsertPair) {
69     std::pair<typename MapTy::iterator, bool> Pair =
70         Map.insert(std::make_pair(InsertPair.first, size_t(0)));
71     if (Pair.second) {
72       size_t Num = Vector.size();
73       Pair.first->second = Num;
74       Vector.push_back(InsertPair);
75       return std::make_pair(Vector.begin() + Num, true);
76     }
77     return std::make_pair(Vector.begin() + Pair.first->second, false);
78   }
79
80   iterator find(const KeyT &Key) {
81     typename MapTy::iterator It = Map.find(Key);
82     if (It == Map.end())
83       return Vector.end();
84     return Vector.begin() + It->second;
85   }
86
87   const_iterator find(const KeyT &Key) const {
88     typename MapTy::const_iterator It = Map.find(Key);
89     if (It == Map.end())
90       return Vector.end();
91     return Vector.begin() + It->second;
92   }
93
94   /// This is similar to erase, but instead of removing the element from the
95   /// vector, it just zeros out the key in the vector. This leaves iterators
96   /// intact, but clients must be prepared for zeroed-out keys when iterating.
97   void blot(const KeyT &Key) {
98     typename MapTy::iterator It = Map.find(Key);
99     if (It == Map.end())
100       return;
101     Vector[It->second].first = KeyT();
102     Map.erase(It);
103   }
104
105   void clear() {
106     Map.clear();
107     Vector.clear();
108   }
109
110   bool empty() const {
111     assert(Map.empty() == Vector.empty());
112     return Map.empty();
113   }
114 };
115
116 } // end namespace llvm
117
118 #endif // LLVM_LIB_TRANSFORMS_OBJCARC_BLOTMAPVECTOR_H