1 //===- BlotMapVector.h - A MapVector with the blot operation -*- C++ -*----===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 #include "llvm/ADT/DenseMap.h"
15 /// \brief An associative container with fast insertion-order (deterministic)
16 /// iteration over its elements. Plus the special blot operation.
17 template <class KeyT
, class ValueT
> class BlotMapVector
{
18 /// Map keys to indices in Vector.
19 typedef DenseMap
<KeyT
, size_t> MapTy
;
22 typedef std::vector
<std::pair
<KeyT
, ValueT
>> VectorTy
;
27 typedef typename
VectorTy::iterator iterator
;
28 typedef typename
VectorTy::const_iterator const_iterator
;
29 iterator
begin() { return Vector
.begin(); }
30 iterator
end() { return Vector
.end(); }
31 const_iterator
begin() const { return Vector
.begin(); }
32 const_iterator
end() const { return Vector
.end(); }
34 #ifdef EXPENSIVE_CHECKS
36 assert(Vector
.size() >= Map
.size()); // May differ due to blotting.
37 for (typename
MapTy::const_iterator I
= Map
.begin(), E
= Map
.end(); I
!= E
;
39 assert(I
->second
< Vector
.size());
40 assert(Vector
[I
->second
].first
== I
->first
);
42 for (typename
VectorTy::const_iterator I
= Vector
.begin(), E
= Vector
.end();
44 assert(!I
->first
|| (Map
.count(I
->first
) &&
45 Map
[I
->first
] == size_t(I
- Vector
.begin())));
49 ValueT
&operator[](const KeyT
&Arg
) {
50 std::pair
<typename
MapTy::iterator
, bool> Pair
=
51 Map
.insert(std::make_pair(Arg
, size_t(0)));
53 size_t Num
= Vector
.size();
54 Pair
.first
->second
= Num
;
55 Vector
.push_back(std::make_pair(Arg
, ValueT()));
56 return Vector
[Num
].second
;
58 return Vector
[Pair
.first
->second
].second
;
61 std::pair
<iterator
, bool> insert(const std::pair
<KeyT
, ValueT
> &InsertPair
) {
62 std::pair
<typename
MapTy::iterator
, bool> Pair
=
63 Map
.insert(std::make_pair(InsertPair
.first
, size_t(0)));
65 size_t Num
= Vector
.size();
66 Pair
.first
->second
= Num
;
67 Vector
.push_back(InsertPair
);
68 return std::make_pair(Vector
.begin() + Num
, true);
70 return std::make_pair(Vector
.begin() + Pair
.first
->second
, false);
73 iterator
find(const KeyT
&Key
) {
74 typename
MapTy::iterator It
= Map
.find(Key
);
77 return Vector
.begin() + It
->second
;
80 const_iterator
find(const KeyT
&Key
) const {
81 typename
MapTy::const_iterator It
= Map
.find(Key
);
84 return Vector
.begin() + It
->second
;
87 /// This is similar to erase, but instead of removing the element from the
88 /// vector, it just zeros out the key in the vector. This leaves iterators
89 /// intact, but clients must be prepared for zeroed-out keys when iterating.
90 void blot(const KeyT
&Key
) {
91 typename
MapTy::iterator It
= Map
.find(Key
);
94 Vector
[It
->second
].first
= KeyT();
104 assert(Map
.empty() == Vector
.empty());