WPILibC++  2020.3.2-60-g3011ebe
StringMap.h
1 //===- StringMap.h - String Hash table map interface ------------*- 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 // This file defines the StringMap class.
11 //
12 //===----------------------------------------------------------------------===//
13 
14 #ifndef WPIUTIL_WPI_STRINGMAP_H
15 #define WPIUTIL_WPI_STRINGMAP_H
16 
17 #include "wpi/SmallVector.h"
18 #include "wpi/StringRef.h"
19 #include "wpi/iterator.h"
20 #include "wpi/iterator_range.h"
21 #include "wpi/MemAlloc.h"
22 #include "wpi/PointerLikeTypeTraits.h"
23 #include "wpi/ErrorHandling.h"
24 #include "wpi/deprecated.h"
25 #include <algorithm>
26 #include <cassert>
27 #include <cstdint>
28 #include <cstdlib>
29 #include <cstring>
30 #include <initializer_list>
31 #include <iterator>
32 #include <utility>
33 
34 namespace wpi {
35 
36 template<typename ValueTy> class StringMapConstIterator;
37 template<typename ValueTy> class StringMapIterator;
38 template<typename ValueTy> class StringMapKeyIterator;
39 template<typename ValueTy> class StringMapEntry;
40 
43  size_t StrLen;
44 
45 public:
46  explicit StringMapEntryBase(size_t Len) : StrLen(Len) {}
47 
48  size_t getKeyLength() const { return StrLen; }
49 };
50 
54 protected:
55  // Array of NumBuckets pointers to entries, null pointers are holes.
56  // TheTable[NumBuckets] contains a sentinel value for easy iteration. Followed
57  // by an array of the actual hash values as unsigned integers.
58  StringMapEntryBase **TheTable = nullptr;
59  unsigned NumBuckets = 0;
60  unsigned NumItems = 0;
61  unsigned NumTombstones = 0;
62  unsigned ItemSize;
63 
64 protected:
65  explicit StringMapImpl(unsigned itemSize)
66  : ItemSize(itemSize) {}
67  StringMapImpl(StringMapImpl &&RHS) noexcept
68  : TheTable(RHS.TheTable), NumBuckets(RHS.NumBuckets),
69  NumItems(RHS.NumItems), NumTombstones(RHS.NumTombstones),
70  ItemSize(RHS.ItemSize) {
71  RHS.TheTable = nullptr;
72  RHS.NumBuckets = 0;
73  RHS.NumItems = 0;
74  RHS.NumTombstones = 0;
75  }
76 
77  StringMapImpl(unsigned InitSize, unsigned ItemSize);
78  unsigned RehashTable(unsigned BucketNo = 0);
79 
85  unsigned LookupBucketFor(StringRef Key);
86 
90  int FindKey(StringRef Key) const;
91 
95 
99 
102  void init(unsigned Size);
103 
104 public:
105  static StringMapEntryBase *getTombstoneVal() {
106  uintptr_t Val = static_cast<uintptr_t>(-1);
107  Val <<= PointerLikeTypeTraits<StringMapEntryBase *>::NumLowBitsAvailable;
108  return reinterpret_cast<StringMapEntryBase *>(Val);
109  }
110 
111  unsigned getNumBuckets() const { return NumBuckets; }
112  unsigned getNumItems() const { return NumItems; }
113 
114  bool empty() const { return NumItems == 0; }
115  unsigned size() const { return NumItems; }
116 
117  void swap(StringMapImpl &Other) {
118  std::swap(TheTable, Other.TheTable);
119  std::swap(NumBuckets, Other.NumBuckets);
120  std::swap(NumItems, Other.NumItems);
121  std::swap(NumTombstones, Other.NumTombstones);
122  }
123 };
124 
128 template<typename ValueTy>
129 class StringMapEntry : public StringMapEntryBase {
130 public:
131  ValueTy second;
132 
133  explicit StringMapEntry(size_t strLen)
134  : StringMapEntryBase(strLen), second() {}
135  template <typename... InitTy>
136  StringMapEntry(size_t strLen, InitTy &&... InitVals)
137  : StringMapEntryBase(strLen), second(std::forward<InitTy>(InitVals)...) {}
138  StringMapEntry(StringMapEntry &E) = delete;
139 
140  StringRef getKey() const {
141  return StringRef(getKeyData(), getKeyLength());
142  }
143 
144  const ValueTy &getValue() const { return second; }
145  ValueTy &getValue() { return second; }
146 
147  void setValue(const ValueTy &V) { second = V; }
148 
152  const char *getKeyData() const {return reinterpret_cast<const char*>(this+1);}
153 
154  StringRef first() const { return StringRef(getKeyData(), getKeyLength()); }
155 
158  template <typename... InitTy>
159  static StringMapEntry *Create(StringRef Key, InitTy &&... InitVals) {
160  size_t KeyLength = Key.size();
161 
162  // Allocate a new item with space for the string at the end and a null
163  // terminator.
164  size_t AllocSize = sizeof(StringMapEntry) + KeyLength + 1;
165 
166  StringMapEntry *NewItem =
167  static_cast<StringMapEntry*>(safe_malloc(AllocSize));
168 
169  // Construct the value.
170  new (NewItem) StringMapEntry(KeyLength, std::forward<InitTy>(InitVals)...);
171 
172  // Copy the string information.
173  char *StrBuffer = const_cast<char*>(NewItem->getKeyData());
174  if (KeyLength > 0)
175  memcpy(StrBuffer, Key.data(), KeyLength);
176  StrBuffer[KeyLength] = 0; // Null terminate for convenience of clients.
177  return NewItem;
178  }
179 
180  static StringMapEntry *Create(StringRef Key) {
181  return Create(Key, ValueTy());
182  }
183 
186  static StringMapEntry &GetStringMapEntryFromKeyData(const char *KeyData) {
187  char *Ptr = const_cast<char*>(KeyData) - sizeof(StringMapEntry<ValueTy>);
188  return *reinterpret_cast<StringMapEntry*>(Ptr);
189  }
190 
193  void Destroy() {
194  // Free memory referenced by the item.
195  this->~StringMapEntry();
196  std::free(static_cast<void *>(this));
197  }
198 };
199 
200 
205 template<typename ValueTy>
206 class StringMap : public StringMapImpl {
207 public:
209 
210  StringMap() : StringMapImpl(static_cast<unsigned>(sizeof(MapEntryTy))) {}
211 
212  explicit StringMap(unsigned InitialSize)
213  : StringMapImpl(InitialSize, static_cast<unsigned>(sizeof(MapEntryTy))) {}
214 
215  StringMap(std::initializer_list<std::pair<StringRef, ValueTy>> List)
216  : StringMapImpl(List.size(), static_cast<unsigned>(sizeof(MapEntryTy))) {
217  for (const auto &P : List) {
218  insert(P);
219  }
220  }
221 
222  StringMap(StringMap &&RHS)
223  : StringMapImpl(std::move(RHS)) {}
224 
225  StringMap(const StringMap &RHS) :
226  StringMapImpl(static_cast<unsigned>(sizeof(MapEntryTy))) {
227  if (RHS.empty())
228  return;
229 
230  // Allocate TheTable of the same size as RHS's TheTable, and set the
231  // sentinel appropriately (and NumBuckets).
232  init(RHS.NumBuckets);
233  unsigned *HashTable = (unsigned *)(TheTable + NumBuckets + 1),
234  *RHSHashTable = (unsigned *)(RHS.TheTable + NumBuckets + 1);
235 
236  NumItems = RHS.NumItems;
237  NumTombstones = RHS.NumTombstones;
238  for (unsigned I = 0, E = NumBuckets; I != E; ++I) {
239  StringMapEntryBase *Bucket = RHS.TheTable[I];
240  if (!Bucket || Bucket == getTombstoneVal()) {
241  TheTable[I] = Bucket;
242  continue;
243  }
244 
245  TheTable[I] = MapEntryTy::Create(
246  static_cast<MapEntryTy *>(Bucket)->getKey(),
247  static_cast<MapEntryTy *>(Bucket)->getValue());
248  HashTable[I] = RHSHashTable[I];
249  }
250 
251  // Note that here we've copied everything from the RHS into this object,
252  // tombstones included. We could, instead, have re-probed for each key to
253  // instantiate this new object without any tombstone buckets. The
254  // assumption here is that items are rarely deleted from most StringMaps,
255  // and so tombstones are rare, so the cost of re-probing for all inputs is
256  // not worthwhile.
257  }
258 
259  StringMap &operator=(StringMap RHS) {
260  StringMapImpl::swap(RHS);
261  return *this;
262  }
263 
264  ~StringMap() {
265  // Delete all the elements in the map, but don't reset the elements
266  // to default values. This is a copy of clear(), but avoids unnecessary
267  // work not required in the destructor.
268  if (!empty()) {
269  for (unsigned I = 0, E = NumBuckets; I != E; ++I) {
270  StringMapEntryBase *Bucket = TheTable[I];
271  if (Bucket && Bucket != getTombstoneVal()) {
272  static_cast<MapEntryTy*>(Bucket)->Destroy();
273  }
274  }
275  }
276  free(TheTable);
277  }
278 
279  using key_type = const char*;
280  using mapped_type = ValueTy;
282  using size_type = size_t;
283 
286 
287  iterator begin() {
288  return iterator(TheTable, NumBuckets == 0);
289  }
290  iterator end() {
291  return iterator(TheTable+NumBuckets, true);
292  }
293  const_iterator begin() const {
294  return const_iterator(TheTable, NumBuckets == 0);
295  }
296  const_iterator end() const {
297  return const_iterator(TheTable+NumBuckets, true);
298  }
299 
303  }
304 
305  iterator find(StringRef Key) {
306  int Bucket = FindKey(Key);
307  if (Bucket == -1) return end();
308  return iterator(TheTable+Bucket, true);
309  }
310 
311  const_iterator find(StringRef Key) const {
312  int Bucket = FindKey(Key);
313  if (Bucket == -1) return end();
314  return const_iterator(TheTable+Bucket, true);
315  }
316 
319  ValueTy lookup(StringRef Key) const {
320  const_iterator it = find(Key);
321  if (it != end())
322  return it->second;
323  return ValueTy();
324  }
325 
328  ValueTy &operator[](StringRef Key) { return try_emplace(Key).first->second; }
329 
331  size_type count(StringRef Key) const {
332  return find(Key) == end() ? 0 : 1;
333  }
334 
338  bool insert(MapEntryTy *KeyValue) {
339  unsigned BucketNo = LookupBucketFor(KeyValue->getKey());
340  StringMapEntryBase *&Bucket = TheTable[BucketNo];
341  if (Bucket && Bucket != getTombstoneVal())
342  return false; // Already exists in map.
343 
344  if (Bucket == getTombstoneVal())
345  --NumTombstones;
346  Bucket = KeyValue;
347  ++NumItems;
348  assert(NumItems + NumTombstones <= NumBuckets);
349 
350  RehashTable();
351  return true;
352  }
353 
358  std::pair<iterator, bool> insert(std::pair<StringRef, ValueTy> KV) {
359  return try_emplace(KV.first, std::move(KV.second));
360  }
361 
366  template <typename... ArgsTy>
367  std::pair<iterator, bool> try_emplace(StringRef Key, ArgsTy &&... Args) {
368  unsigned BucketNo = LookupBucketFor(Key);
369  StringMapEntryBase *&Bucket = TheTable[BucketNo];
370  if (Bucket && Bucket != getTombstoneVal())
371  return std::make_pair(iterator(TheTable + BucketNo, false),
372  false); // Already exists in map.
373 
374  if (Bucket == getTombstoneVal())
375  --NumTombstones;
376  Bucket = MapEntryTy::Create(Key, std::forward<ArgsTy>(Args)...);
377  ++NumItems;
378  assert(NumItems + NumTombstones <= NumBuckets);
379 
380  BucketNo = RehashTable(BucketNo);
381  return std::make_pair(iterator(TheTable + BucketNo, false), true);
382  }
383 
384  // clear - Empties out the StringMap
385  void clear() {
386  if (empty()) return;
387 
388  // Zap all values, resetting the keys back to non-present (not tombstone),
389  // which is safe because we're removing all elements.
390  for (unsigned I = 0, E = NumBuckets; I != E; ++I) {
391  StringMapEntryBase *&Bucket = TheTable[I];
392  if (Bucket && Bucket != getTombstoneVal()) {
393  static_cast<MapEntryTy*>(Bucket)->Destroy();
394  }
395  Bucket = nullptr;
396  }
397 
398  NumItems = 0;
399  NumTombstones = 0;
400  }
401 
404  void remove(MapEntryTy *KeyValue) {
405  RemoveKey(KeyValue);
406  }
407 
408  void erase(iterator I) {
409  MapEntryTy &V = *I;
410  remove(&V);
411  V.Destroy();
412  }
413 
414  bool erase(StringRef Key) {
415  iterator I = find(Key);
416  if (I == end()) return false;
417  erase(I);
418  return true;
419  }
420 };
421 
422 template <typename DerivedTy, typename ValueTy>
424  : public iterator_facade_base<DerivedTy, std::forward_iterator_tag,
425  ValueTy> {
426 protected:
427  StringMapEntryBase **Ptr = nullptr;
428 
429 public:
430  StringMapIterBase() = default;
431 
432  explicit StringMapIterBase(StringMapEntryBase **Bucket,
433  bool NoAdvance = false)
434  : Ptr(Bucket) {
435  if (!NoAdvance) AdvancePastEmptyBuckets();
436  }
437 
438  DerivedTy &operator=(const DerivedTy &Other) {
439  Ptr = Other.Ptr;
440  return static_cast<DerivedTy &>(*this);
441  }
442 
443  bool operator==(const DerivedTy &RHS) const { return Ptr == RHS.Ptr; }
444 
445  DerivedTy &operator++() { // Preincrement
446  ++Ptr;
447  AdvancePastEmptyBuckets();
448  return static_cast<DerivedTy &>(*this);
449  }
450 
451  DerivedTy operator++(int) { // Post-increment
452  DerivedTy Tmp(Ptr);
453  ++*this;
454  return Tmp;
455  }
456 
457  DerivedTy &operator--() { // Predecrement
458  --Ptr;
459  ReversePastEmptyBuckets();
460  return static_cast<DerivedTy &>(*this);
461  }
462 
463  DerivedTy operator--(int) { // Post-decrement
464  DerivedTy Tmp(Ptr);
465  --*this;
466  return Tmp;
467  }
468 
469 private:
470  void AdvancePastEmptyBuckets() {
471  while (*Ptr == nullptr || *Ptr == StringMapImpl::getTombstoneVal())
472  ++Ptr;
473  }
474  void ReversePastEmptyBuckets() {
475  while (*Ptr == nullptr || *Ptr == StringMapImpl::getTombstoneVal())
476  --Ptr;
477  }
478 };
479 
480 template <typename ValueTy>
482  : public StringMapIterBase<StringMapConstIterator<ValueTy>,
483  const StringMapEntry<ValueTy>> {
486 
487 public:
488  using value_type = const StringMapEntry<ValueTy>;
489 
490  StringMapConstIterator() = default;
491  explicit StringMapConstIterator(StringMapEntryBase **Bucket,
492  bool NoAdvance = false)
493  : base(Bucket, NoAdvance) {}
494 
495  value_type &operator*() const {
496  return *static_cast<value_type *>(*this->Ptr);
497  }
498 };
499 
500 template <typename ValueTy>
501 class StringMapIterator : public StringMapIterBase<StringMapIterator<ValueTy>,
502  StringMapEntry<ValueTy>> {
503  using base =
504  StringMapIterBase<StringMapIterator<ValueTy>, StringMapEntry<ValueTy>>;
505 
506 public:
507  using value_type = StringMapEntry<ValueTy>;
508 
509  StringMapIterator() = default;
510  explicit StringMapIterator(StringMapEntryBase **Bucket,
511  bool NoAdvance = false)
512  : base(Bucket, NoAdvance) {}
513 
514  value_type &operator*() const {
515  return *static_cast<value_type *>(*this->Ptr);
516  }
517 
518  operator StringMapConstIterator<ValueTy>() const {
519  return StringMapConstIterator<ValueTy>(this->Ptr, true);
520  }
521 };
522 
523 template <typename ValueTy>
524 class StringMapKeyIterator
525  : public iterator_adaptor_base<StringMapKeyIterator<ValueTy>,
526  StringMapConstIterator<ValueTy>,
527  std::forward_iterator_tag, StringRef> {
528  using base = iterator_adaptor_base<StringMapKeyIterator<ValueTy>,
529  StringMapConstIterator<ValueTy>,
530  std::forward_iterator_tag, StringRef>;
531 
532 public:
533  StringMapKeyIterator() = default;
534  explicit StringMapKeyIterator(StringMapConstIterator<ValueTy> Iter)
535  : base(std::move(Iter)) {}
536 
537  StringRef &operator*() {
538  Key = this->wrapped()->getKey();
539  return Key;
540  }
541 
542 private:
543  StringRef Key;
544 };
545 
546 template <typename ValueTy>
547 bool operator==(const StringMap<ValueTy>& lhs, const StringMap<ValueTy>& rhs) {
548  // same instance?
549  if (&lhs == &rhs) return true;
550 
551  // first check that sizes are identical
552  if (lhs.size() != rhs.size()) return false;
553 
554  // copy into vectors and sort by key
555  SmallVector<StringMapConstIterator<ValueTy>, 16> lhs_items;
556  lhs_items.reserve(lhs.size());
557  for (auto i = lhs.begin(), end = lhs.end(); i != end; ++i)
558  lhs_items.push_back(i);
559  std::sort(lhs_items.begin(), lhs_items.end(),
560  [](const StringMapConstIterator<ValueTy>& a,
561  const StringMapConstIterator<ValueTy>& b) {
562  return a->getKey() < b->getKey();
563  });
564 
565  SmallVector<StringMapConstIterator<ValueTy>, 16> rhs_items;
566  rhs_items.reserve(rhs.size());
567  for (auto i = rhs.begin(), end = rhs.end(); i != end; ++i)
568  rhs_items.push_back(i);
569  std::sort(rhs_items.begin(), rhs_items.end(),
570  [](const StringMapConstIterator<ValueTy>& a,
571  const StringMapConstIterator<ValueTy>& b) {
572  return a->getKey() < b->getKey();
573  });
574 
575  // compare vector keys and values
576  for (auto a = lhs_items.begin(), b = rhs_items.begin(),
577  aend = lhs_items.end(), bend = rhs_items.end();
578  a != aend && b != bend; ++a, ++b) {
579  if ((*a)->first() != (*b)->first() || (*a)->second != (*b)->second)
580  return false;
581  }
582  return true;
583 }
584 
585 template <typename ValueTy>
586 inline bool operator!=(const StringMap<ValueTy>& lhs,
587  const StringMap<ValueTy>& rhs) {
588  return !(lhs == rhs);
589 }
590 
591 template <typename ValueTy>
592 bool operator<(const StringMap<ValueTy>& lhs, const StringMap<ValueTy>& rhs) {
593  // same instance?
594  if (&lhs == &rhs) return false;
595 
596  // copy into vectors and sort by key
597  SmallVector<StringRef, 16> lhs_keys;
598  lhs_keys.reserve(lhs.size());
599  for (auto i = lhs.begin(), end = lhs.end(); i != end; ++i)
600  lhs_keys.push_back(i->getKey());
601  std::sort(lhs_keys.begin(), lhs_keys.end());
602 
603  SmallVector<StringRef, 16> rhs_keys;
604  rhs_keys.reserve(rhs.size());
605  for (auto i = rhs.begin(), end = rhs.end(); i != end; ++i)
606  rhs_keys.push_back(i->getKey());
607  std::sort(rhs_keys.begin(), rhs_keys.end());
608 
609  // use std::vector comparison
610  return lhs_keys < rhs_keys;
611 }
612 
613 template <typename ValueTy>
614 inline bool operator<=(const StringMap<ValueTy>& lhs,
615  const StringMap<ValueTy>& rhs) {
616  return !(rhs < lhs);
617 }
618 
619 template <typename ValueTy>
620 inline bool operator>(const StringMap<ValueTy>& lhs,
621  const StringMap<ValueTy>& rhs) {
622  return !(lhs <= rhs);
623 }
624 
625 template <typename ValueTy>
626 inline bool operator>=(const StringMap<ValueTy>& lhs,
627  const StringMap<ValueTy>& rhs) {
628  return !(lhs < rhs);
629 }
630 
631 } // end namespace wpi
632 
633 #endif // LLVM_ADT_STRINGMAP_H
wpi::StringMapImpl
StringMapImpl - This is the base class of StringMap that is shared among all of its instantiations.
Definition: StringMap.h:53
wpi::operator!=
bool operator!=(const DenseMapBase< DerivedT, KeyT, ValueT, KeyInfoT, BucketT > &LHS, const DenseMapBase< DerivedT, KeyT, ValueT, KeyInfoT, BucketT > &RHS)
Inequality comparison for DenseMap.
Definition: DenseMap.h:659
wpi::StringMap::insert
bool insert(MapEntryTy *KeyValue)
insert - Insert the specified key/value pair into the map.
Definition: StringMap.h:338
wpi::StringMapEntry::Destroy
void Destroy()
Destroy - Destroy this StringMapEntry, releasing memory back to the specified allocator.
Definition: StringMap.h:193
wpi::StringMapEntryBase
StringMapEntryBase - Shared base class of StringMapEntry instances.
Definition: StringMap.h:42
wpi::StringMapImpl::LookupBucketFor
unsigned LookupBucketFor(StringRef Key)
LookupBucketFor - Look up the bucket that the specified string should end up in.
wpi::StringRef::size
LLVM_NODISCARD LLVM_ATTRIBUTE_ALWAYS_INLINE size_t size() const noexcept
size - Get the string size.
Definition: StringRef.h:138
wpi::StringMap::lookup
ValueTy lookup(StringRef Key) const
lookup - Return the entry for the specified key, or a default constructed value if no such entry exis...
Definition: StringMap.h:319
wpi::StringMapImpl::FindKey
int FindKey(StringRef Key) const
FindKey - Look up the bucket that contains the specified key.
wpi::iterator_range
A range adaptor for a pair of iterators.
Definition: iterator_range.h:32
wpi::sys::path::const_iterator::end
friend const_iterator end(StringRef path)
Get end iterator over path.
wpi::StringMap::operator[]
ValueTy & operator[](StringRef Key)
Lookup the ValueTy for the Key, or create a default constructed value if the key is not in the map.
Definition: StringMap.h:328
MemAlloc.h
wpi
WPILib C++ utilities (wpiutil) namespace.
Definition: Endian.h:31
wpi::make_range
iterator_range< T > make_range(T x, T y)
Convenience function for iterating over sub-ranges.
Definition: iterator_range.h:54
wpi::StringMap::count
size_type count(StringRef Key) const
count - Return 1 if the element is in the map, 0 otherwise.
Definition: StringMap.h:331
wpi::StringRef
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:49
iterator_range.h
wpi::iterator_facade_base
CRTP base class which implements the entire standard iterator facade in terms of a minimal subset of ...
Definition: iterator.h:68
wpi::StringMapEntry
StringMapEntry - This is used to represent one value that is inserted into a StringMap.
Definition: StringMap.h:39
wpi::StringMapKeyIterator
Definition: StringMap.h:38
wpi::StringMap::try_emplace
std::pair< iterator, bool > try_emplace(StringRef Key, ArgsTy &&... Args)
Emplace a new element for the specified key into the map if the key isn't already in the map.
Definition: StringMap.h:367
wpi::StringMap
StringMap - This is an unconventional map that is specialized for handling keys that are "strings",...
Definition: StringMap.h:206
wpi::StringMapEntry::Create
static StringMapEntry * Create(StringRef Key, InitTy &&... InitVals)
Create a StringMapEntry for the specified key construct the value using InitiVals.
Definition: StringMap.h:159
wpi::StringMapConstIterator
Definition: StringMap.h:36
wpi::StringRef::data
LLVM_NODISCARD const LLVM_ATTRIBUTE_ALWAYS_INLINE char * data() const noexcept
data - Get a pointer to the start of the string (which may not be null terminated).
Definition: StringRef.h:128
wpi::StringMapIterator
Definition: StringMap.h:37
wpi::StringMap::insert
std::pair< iterator, bool > insert(std::pair< StringRef, ValueTy > KV)
insert - Inserts the specified key/value pair into the map if the key isn't already in the map.
Definition: StringMap.h:358
wpi::StringMap::remove
void remove(MapEntryTy *KeyValue)
remove - Remove the specified key/value pair from the map, but do not erase it.
Definition: StringMap.h:404
wpi::StringMapEntry::GetStringMapEntryFromKeyData
static StringMapEntry & GetStringMapEntryFromKeyData(const char *KeyData)
GetStringMapEntryFromKeyData - Given key data that is known to be embedded into a StringMapEntry,...
Definition: StringMap.h:186
wpi::StringMapEntry::getKeyData
const char * getKeyData() const
getKeyData - Return the start of the string data that is the key for this value.
Definition: StringMap.h:152
wpi::StringMapIterBase
Definition: StringMap.h:423
wpi::StringMapImpl::init
void init(unsigned Size)
Allocate the table with the specified number of buckets and otherwise setup the map as empty.
wpi::StringMapImpl::RemoveKey
void RemoveKey(StringMapEntryBase *V)
RemoveKey - Remove the specified StringMapEntry from the table, but do not delete it.