Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-src
Path: blob/main/contrib/llvm-project/llvm/lib/Transforms/ObjCARC/BlotMapVector.h
35294 views
1
//===- BlotMapVector.h - A MapVector with the blot operation ----*- C++ -*-===//
2
//
3
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4
// See https://llvm.org/LICENSE.txt for license information.
5
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6
//
7
//===----------------------------------------------------------------------===//
8
9
#ifndef LLVM_LIB_TRANSFORMS_OBJCARC_BLOTMAPVECTOR_H
10
#define LLVM_LIB_TRANSFORMS_OBJCARC_BLOTMAPVECTOR_H
11
12
#include "llvm/ADT/DenseMap.h"
13
#include <cassert>
14
#include <cstddef>
15
#include <utility>
16
#include <vector>
17
18
namespace llvm {
19
20
/// An associative container with fast insertion-order (deterministic)
21
/// iteration over its elements. Plus the special blot operation.
22
template <class KeyT, class ValueT> class BlotMapVector {
23
/// Map keys to indices in Vector.
24
using MapTy = DenseMap<KeyT, size_t>;
25
MapTy Map;
26
27
/// Keys and values.
28
using VectorTy = std::vector<std::pair<KeyT, ValueT>>;
29
VectorTy Vector;
30
31
public:
32
#ifdef EXPENSIVE_CHECKS
33
~BlotMapVector() {
34
assert(Vector.size() >= Map.size()); // May differ due to blotting.
35
for (typename MapTy::const_iterator I = Map.begin(), E = Map.end(); I != E;
36
++I) {
37
assert(I->second < Vector.size());
38
assert(Vector[I->second].first == I->first);
39
}
40
for (typename VectorTy::const_iterator I = Vector.begin(), E = Vector.end();
41
I != E; ++I)
42
assert(!I->first || (Map.count(I->first) &&
43
Map[I->first] == size_t(I - Vector.begin())));
44
}
45
#endif
46
47
using iterator = typename VectorTy::iterator;
48
using const_iterator = typename VectorTy::const_iterator;
49
50
iterator begin() { return Vector.begin(); }
51
iterator end() { return Vector.end(); }
52
const_iterator begin() const { return Vector.begin(); }
53
const_iterator end() const { return Vector.end(); }
54
55
ValueT &operator[](const KeyT &Arg) {
56
std::pair<typename MapTy::iterator, bool> Pair =
57
Map.insert(std::make_pair(Arg, size_t(0)));
58
if (Pair.second) {
59
size_t Num = Vector.size();
60
Pair.first->second = Num;
61
Vector.push_back(std::make_pair(Arg, ValueT()));
62
return Vector[Num].second;
63
}
64
return Vector[Pair.first->second].second;
65
}
66
67
std::pair<iterator, bool> insert(const std::pair<KeyT, ValueT> &InsertPair) {
68
std::pair<typename MapTy::iterator, bool> Pair =
69
Map.insert(std::make_pair(InsertPair.first, size_t(0)));
70
if (Pair.second) {
71
size_t Num = Vector.size();
72
Pair.first->second = Num;
73
Vector.push_back(InsertPair);
74
return std::make_pair(Vector.begin() + Num, true);
75
}
76
return std::make_pair(Vector.begin() + Pair.first->second, false);
77
}
78
79
iterator find(const KeyT &Key) {
80
typename MapTy::iterator It = Map.find(Key);
81
if (It == Map.end())
82
return Vector.end();
83
return Vector.begin() + It->second;
84
}
85
86
const_iterator find(const KeyT &Key) const {
87
typename MapTy::const_iterator It = Map.find(Key);
88
if (It == Map.end())
89
return Vector.end();
90
return Vector.begin() + It->second;
91
}
92
93
/// This is similar to erase, but instead of removing the element from the
94
/// vector, it just zeros out the key in the vector. This leaves iterators
95
/// intact, but clients must be prepared for zeroed-out keys when iterating.
96
void blot(const KeyT &Key) {
97
typename MapTy::iterator It = Map.find(Key);
98
if (It == Map.end())
99
return;
100
Vector[It->second].first = KeyT();
101
Map.erase(It);
102
}
103
104
void clear() {
105
Map.clear();
106
Vector.clear();
107
}
108
109
bool empty() const {
110
assert(Map.empty() == Vector.empty());
111
return Map.empty();
112
}
113
};
114
115
} // end namespace llvm
116
117
#endif // LLVM_LIB_TRANSFORMS_OBJCARC_BLOTMAPVECTOR_H
118
119