File indexing completed on 2026-05-10 08:42:46
0001
0002
0003
0004
0005
0006
0007
0008
0009 #ifndef LLDB_CORE_UNIQUECSTRINGMAP_H
0010 #define LLDB_CORE_UNIQUECSTRINGMAP_H
0011
0012 #include <algorithm>
0013 #include <vector>
0014
0015 #include "lldb/Utility/ConstString.h"
0016 #include "lldb/Utility/RegularExpression.h"
0017
0018 namespace lldb_private {
0019
0020
0021
0022
0023
0024
0025
0026 template <typename T> class UniqueCStringMap {
0027 public:
0028 struct Entry {
0029 Entry(ConstString cstr, const T &v) : cstring(cstr), value(v) {}
0030
0031 ConstString cstring;
0032 T value;
0033 };
0034
0035 typedef std::vector<Entry> collection;
0036 typedef typename collection::iterator iterator;
0037 typedef typename collection::const_iterator const_iterator;
0038
0039
0040
0041
0042 void Append(ConstString unique_cstr, const T &value) {
0043 m_map.push_back(typename UniqueCStringMap<T>::Entry(unique_cstr, value));
0044 }
0045
0046 void Append(const Entry &e) { m_map.push_back(e); }
0047
0048 void Clear() { m_map.clear(); }
0049
0050
0051
0052
0053
0054 bool GetValueAtIndex(uint32_t idx, T &value) const {
0055 if (idx < m_map.size()) {
0056 value = m_map[idx].value;
0057 return true;
0058 }
0059 return false;
0060 }
0061
0062 ConstString GetCStringAtIndexUnchecked(uint32_t idx) const {
0063 return m_map[idx].cstring;
0064 }
0065
0066
0067
0068 T GetValueAtIndexUnchecked(uint32_t idx) const { return m_map[idx].value; }
0069
0070
0071
0072 const T &GetValueRefAtIndexUnchecked(uint32_t idx) const {
0073 return m_map[idx].value;
0074 }
0075
0076 ConstString GetCStringAtIndex(uint32_t idx) const {
0077 return ((idx < m_map.size()) ? m_map[idx].cstring : ConstString());
0078 }
0079
0080
0081
0082
0083
0084
0085
0086 T Find(ConstString unique_cstr, T fail_value) const {
0087 auto pos = llvm::lower_bound(m_map, unique_cstr, Compare());
0088 if (pos != m_map.end() && pos->cstring == unique_cstr)
0089 return pos->value;
0090 return fail_value;
0091 }
0092
0093
0094
0095
0096
0097
0098 const Entry *FindFirstValueForName(ConstString unique_cstr) const {
0099 auto pos = llvm::lower_bound(m_map, unique_cstr, Compare());
0100 if (pos != m_map.end() && pos->cstring == unique_cstr)
0101 return &(*pos);
0102 return nullptr;
0103 }
0104
0105
0106
0107
0108
0109
0110
0111 const Entry *FindNextValueForName(const Entry *entry_ptr) const {
0112 if (!m_map.empty()) {
0113 const Entry *first_entry = &m_map[0];
0114 const Entry *after_last_entry = first_entry + m_map.size();
0115 const Entry *next_entry = entry_ptr + 1;
0116 if (first_entry <= next_entry && next_entry < after_last_entry) {
0117 if (next_entry->cstring == entry_ptr->cstring)
0118 return next_entry;
0119 }
0120 }
0121 return nullptr;
0122 }
0123
0124 size_t GetValues(ConstString unique_cstr, std::vector<T> &values) const {
0125 const size_t start_size = values.size();
0126
0127 for (const Entry &entry : llvm::make_range(std::equal_range(
0128 m_map.begin(), m_map.end(), unique_cstr, Compare())))
0129 values.push_back(entry.value);
0130
0131 return values.size() - start_size;
0132 }
0133
0134 size_t GetValues(const RegularExpression ®ex,
0135 std::vector<T> &values) const {
0136 const size_t start_size = values.size();
0137
0138 const_iterator pos, end = m_map.end();
0139 for (pos = m_map.begin(); pos != end; ++pos) {
0140 if (regex.Execute(pos->cstring.GetCString()))
0141 values.push_back(pos->value);
0142 }
0143
0144 return values.size() - start_size;
0145 }
0146
0147
0148 size_t GetSize() const { return m_map.size(); }
0149
0150
0151 bool IsEmpty() const { return m_map.empty(); }
0152
0153
0154
0155
0156
0157 void Reserve(size_t n) { m_map.reserve(n); }
0158
0159
0160
0161
0162
0163
0164
0165
0166
0167
0168 void Sort() {
0169 Sort([](const T &, const T &) { return false; });
0170 }
0171
0172
0173
0174 template <typename TCompare> void Sort(TCompare tc) {
0175 Compare c;
0176 llvm::sort(m_map, [&](const Entry &lhs, const Entry &rhs) -> bool {
0177 int result = c.ThreeWay(lhs.cstring, rhs.cstring);
0178 if (result == 0)
0179 return tc(lhs.value, rhs.value);
0180 return result < 0;
0181 });
0182 }
0183
0184
0185
0186
0187
0188
0189 void SizeToFit() {
0190 if (m_map.size() < m_map.capacity()) {
0191 collection temp(m_map.begin(), m_map.end());
0192 m_map.swap(temp);
0193 }
0194 }
0195
0196 iterator begin() { return m_map.begin(); }
0197 iterator end() { return m_map.end(); }
0198 const_iterator begin() const { return m_map.begin(); }
0199 const_iterator end() const { return m_map.end(); }
0200
0201
0202 llvm::iterator_range<const_iterator>
0203 equal_range(ConstString unique_cstr) const {
0204 return llvm::make_range(
0205 std::equal_range(m_map.begin(), m_map.end(), unique_cstr, Compare()));
0206 };
0207
0208 protected:
0209 struct Compare {
0210 bool operator()(const Entry &lhs, const Entry &rhs) {
0211 return operator()(lhs.cstring, rhs.cstring);
0212 }
0213
0214 bool operator()(const Entry &lhs, ConstString rhs) {
0215 return operator()(lhs.cstring, rhs);
0216 }
0217
0218 bool operator()(ConstString lhs, const Entry &rhs) {
0219 return operator()(lhs, rhs.cstring);
0220 }
0221
0222 bool operator()(ConstString lhs, ConstString rhs) {
0223 return ThreeWay(lhs, rhs) < 0;
0224 }
0225
0226
0227
0228
0229 int ThreeWay(ConstString lhs, ConstString rhs) {
0230 auto lhsint = uintptr_t(lhs.GetCString());
0231 auto rhsint = uintptr_t(rhs.GetCString());
0232 if (lhsint < rhsint)
0233 return -1;
0234 if (lhsint > rhsint)
0235 return 1;
0236 return 0;
0237 }
0238 };
0239
0240 collection m_map;
0241 };
0242
0243 }
0244
0245 #endif