14
14
#define SWIFT_BASIC_BLOTMAPVECTOR_H
15
15
16
16
#include " llvm/ADT/DenseMap.h"
17
+ #include " swift/Basic/LLVM.h"
17
18
#include " swift/Basic/Range.h"
18
19
#include < vector>
19
20
20
21
namespace swift {
21
- // / \brief An associative container with fast insertion-order (deterministic)
22
- // / iteration over its elements. Plus the special blot operation.
23
- template <typename KeyT, typename ValueT,
24
- typename MapTy=llvm::DenseMap<KeyT, size_t >,
25
- typename VectorTy=std::vector<std::pair<KeyT, ValueT>>>
26
- class BlotMapVector {
22
+
23
+ template <typename KeyT, typename ValueT>
24
+ bool compareKeyAgainstDefaultKey (const std::pair<KeyT, ValueT> &Pair) {
25
+ return Pair.first == KeyT ();
26
+ }
27
+
28
+ // / \brief An associative container with fast insertion-order (deterministic)
29
+ // / iteration over its elements. Plus the special blot operation.
30
+ template <typename KeyT, typename ValueT,
31
+ typename MapTy = llvm::DenseMap<KeyT, size_t >,
32
+ typename VectorTy = std::vector<Optional<std::pair<KeyT, ValueT>>>>
33
+ class BlotMapVector {
27
34
// / Map keys to indices in Vector.
28
35
MapTy Map;
29
36
30
37
// / Keys and values.
31
38
VectorTy Vector;
32
39
33
40
public:
34
- typedef typename VectorTy::iterator iterator;
35
- typedef typename VectorTy::const_iterator const_iterator;
41
+ using iterator = typename VectorTy::iterator;
42
+ using const_iterator = typename VectorTy::const_iterator;
43
+ using key_type = KeyT;
44
+ using mapped_type = ValueT;
45
+
36
46
iterator begin () { return Vector.begin (); }
37
47
iterator end () { return Vector.end (); }
38
48
const_iterator begin () const { return Vector.begin (); }
@@ -42,38 +52,20 @@ template<typename KeyT, typename ValueT,
42
52
return swift::make_range (begin (), end ());
43
53
}
44
54
45
- #ifdef XDEBUG
46
- ~BlotMapVector () {
47
- assert (Vector.size () >= Map.size ()); // May differ due to blotting.
48
- for (typename MapTy::const_iterator I = Map.begin (), E = Map.end ();
49
- I != E; ++I) {
50
- assert (I->second < Vector.size ());
51
- assert (Vector[I->second ].first == I->first );
52
- }
53
- for (typename VectorTy::const_iterator I = Vector.begin (),
54
- E = Vector.end (); I != E; ++I)
55
- assert (!I->first ||
56
- (Map.count (I->first ) &&
57
- Map[I->first ] == size_t (I - Vector.begin ())));
58
- }
59
- #endif
60
-
61
55
ValueT &operator [](const KeyT &Arg) {
62
- std::pair<typename MapTy::iterator, bool > Pair =
63
- Map.insert (std::make_pair (Arg, size_t (0 )));
56
+ auto Pair = Map.insert (std::make_pair (Arg, size_t (0 )));
64
57
if (Pair.second ) {
65
58
size_t Num = Vector.size ();
66
59
Pair.first ->second = Num;
67
- Vector.push_back (std::make_pair (Arg, ValueT ()));
68
- return Vector[Num].second ;
60
+ Vector.push_back ({ std::make_pair (Arg, ValueT ())} );
61
+ return (* Vector[Num]) .second ;
69
62
}
70
- return Vector[Pair.first ->second ].second ;
63
+ return Vector[Pair.first ->second ].getValue (). second ;
71
64
}
72
65
73
66
std::pair<iterator, bool >
74
67
insert (const std::pair<KeyT, ValueT> &InsertPair) {
75
- std::pair<typename MapTy::iterator, bool > Pair =
76
- Map.insert (std::make_pair (InsertPair.first , size_t (0 )));
68
+ auto Pair = Map.insert (std::make_pair (InsertPair.first , size_t (0 )));
77
69
if (Pair.second ) {
78
70
size_t Num = Vector.size ();
79
71
Pair.first ->second = Num;
@@ -86,35 +78,63 @@ template<typename KeyT, typename ValueT,
86
78
iterator find (const KeyT &Key) {
87
79
typename MapTy::iterator It = Map.find (Key);
88
80
if (It == Map.end ()) return Vector.end ();
89
- return Vector.begin () + It->second ;
81
+ auto Iter = Vector.begin () + It->second ;
82
+ if (!Iter->hasValue ())
83
+ return Vector.end ();
84
+ return Iter;
90
85
}
91
86
92
87
const_iterator find (const KeyT &Key) const {
93
- typename MapTy::const_iterator It = Map.find (Key);
94
- if (It == Map.end ()) return Vector.end ();
95
- return Vector.begin () + It->second ;
88
+ return const_cast <BlotMapVector &>(*this )->find (Key);
96
89
}
97
90
91
+ // / This is similar to erase, but instead of removing the element from the
92
+ // / vector, it just zeros out the key in the vector. This leaves iterators
93
+ // / intact, but clients must be prepared for zeroed-out keys when iterating.
94
+ void erase (const KeyT &Key) { blot (Key); }
95
+
96
+ // / This is similar to erase, but instead of removing the element from the
97
+ // / vector, it just zeros out the key in the vector. This leaves iterators
98
+ // / intact, but clients must be prepared for zeroed-out keys when iterating.
99
+ void erase (iterator I) { erase ((*I)->first ); }
100
+
98
101
// / This is similar to erase, but instead of removing the element from the
99
102
// / vector, it just zeros out the key in the vector. This leaves iterators
100
103
// / intact, but clients must be prepared for zeroed-out keys when iterating.
101
104
void blot (const KeyT &Key) {
102
105
typename MapTy::iterator It = Map.find (Key);
103
106
if (It == Map.end ()) return ;
104
- Vector[It->second ]. first = KeyT () ;
107
+ Vector[It->second ] = None ;
105
108
Map.erase (It);
106
109
}
107
110
108
111
void clear () {
109
112
Map.clear ();
110
113
Vector.clear ();
111
114
}
115
+
116
+ unsigned size () const { return Map.size (); }
117
+
118
+ ValueT lookup (const KeyT &Val) const {
119
+ auto Iter = Map.find (Val);
120
+ if (Iter == Map.end ())
121
+ return ValueT ();
122
+ auto &P = Vector[Iter->second ];
123
+ if (!P.hasValue ())
124
+ return ValueT ();
125
+ return P->second ;
126
+ }
127
+
128
+ size_t count (const KeyT &Val) const { return Map.count (Val); }
129
+
130
+ bool empty () const { return Map.empty (); }
112
131
};
113
132
114
- template <typename KeyT, typename ValueT, unsigned N,
115
- typename MapT=llvm::SmallDenseMap<KeyT, size_t , N>,
116
- typename VectorT=llvm::SmallVector<std::pair<KeyT, ValueT>, N>>
117
- class SmallBlotMapVector : public BlotMapVector <KeyT, ValueT, MapT, VectorT> {
133
+ template <typename KeyT, typename ValueT, unsigned N,
134
+ typename MapT = llvm::SmallDenseMap<KeyT, size_t , N>,
135
+ typename VectorT =
136
+ llvm::SmallVector<Optional<std::pair<KeyT, ValueT>>, N>>
137
+ class SmallBlotMapVector : public BlotMapVector <KeyT, ValueT, MapT, VectorT> {
118
138
public:
119
139
SmallBlotMapVector () {}
120
140
};
0 commit comments