1 //===- StringMapEntry.h - String Hash table map interface -------*- 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 // This file defines the StringMapEntry class - it is intended to be a low 10 // dependency implementation detail of StringMap that is more suitable for 11 // inclusion in public headers than StringMap.h itself is. 12 // 13 //===----------------------------------------------------------------------===// 14 15 #ifndef LLVM_ADT_STRINGMAPENTRY_H 16 #define LLVM_ADT_STRINGMAPENTRY_H 17 18 #include "llvm/ADT/StringRef.h" 19 20 namespace llvm { 21 22 /// StringMapEntryBase - Shared base class of StringMapEntry instances. 23 class StringMapEntryBase { 24 size_t keyLength; 25 26 public: 27 explicit StringMapEntryBase(size_t keyLength) : keyLength(keyLength) {} 28 29 size_t getKeyLength() const { return keyLength; } 30 }; 31 32 /// StringMapEntryStorage - Holds the value in a StringMapEntry. 33 /// 34 /// Factored out into a separate base class to make it easier to specialize. 35 /// This is primarily intended to support StringSet, which doesn't need a value 36 /// stored at all. 37 template <typename ValueTy> 38 class StringMapEntryStorage : public StringMapEntryBase { 39 public: 40 ValueTy second; 41 42 explicit StringMapEntryStorage(size_t keyLength) 43 : StringMapEntryBase(keyLength), second() {} 44 template <typename... InitTy> 45 StringMapEntryStorage(size_t keyLength, InitTy &&... initVals) 46 : StringMapEntryBase(keyLength), 47 second(std::forward<InitTy>(initVals)...) {} 48 StringMapEntryStorage(StringMapEntryStorage &e) = delete; 49 50 const ValueTy &getValue() const { return second; } 51 ValueTy &getValue() { return second; } 52 53 void setValue(const ValueTy &V) { second = V; } 54 }; 55 56 template <> class StringMapEntryStorage<NoneType> : public StringMapEntryBase { 57 public: 58 explicit StringMapEntryStorage(size_t keyLength, NoneType none = None) 59 : StringMapEntryBase(keyLength) {} 60 StringMapEntryStorage(StringMapEntryStorage &entry) = delete; 61 62 NoneType getValue() const { return None; } 63 }; 64 65 /// StringMapEntry - This is used to represent one value that is inserted into 66 /// a StringMap. It contains the Value itself and the key: the string length 67 /// and data. 68 template <typename ValueTy> 69 class StringMapEntry final : public StringMapEntryStorage<ValueTy> { 70 public: 71 using StringMapEntryStorage<ValueTy>::StringMapEntryStorage; 72 73 StringRef getKey() const { 74 return StringRef(getKeyData(), this->getKeyLength()); 75 } 76 77 /// getKeyData - Return the start of the string data that is the key for this 78 /// value. The string data is always stored immediately after the 79 /// StringMapEntry object. 80 const char *getKeyData() const { 81 return reinterpret_cast<const char *>(this + 1); 82 } 83 84 StringRef first() const { 85 return StringRef(getKeyData(), this->getKeyLength()); 86 } 87 88 /// Create a StringMapEntry for the specified key construct the value using 89 /// \p InitiVals. 90 template <typename AllocatorTy, typename... InitTy> 91 static StringMapEntry *Create(StringRef key, AllocatorTy &allocator, 92 InitTy &&... initVals) { 93 size_t keyLength = key.size(); 94 95 // Allocate a new item with space for the string at the end and a null 96 // terminator. 97 size_t allocSize = sizeof(StringMapEntry) + keyLength + 1; 98 size_t alignment = alignof(StringMapEntry); 99 100 StringMapEntry *newItem = 101 static_cast<StringMapEntry *>(allocator.Allocate(allocSize, alignment)); 102 assert(newItem && "Unhandled out-of-memory"); 103 104 // Construct the value. 105 new (newItem) StringMapEntry(keyLength, std::forward<InitTy>(initVals)...); 106 107 // Copy the string information. 108 char *strBuffer = const_cast<char *>(newItem->getKeyData()); 109 if (keyLength > 0) 110 memcpy(strBuffer, key.data(), keyLength); 111 strBuffer[keyLength] = 0; // Null terminate for convenience of clients. 112 return newItem; 113 } 114 115 /// GetStringMapEntryFromKeyData - Given key data that is known to be embedded 116 /// into a StringMapEntry, return the StringMapEntry itself. 117 static StringMapEntry &GetStringMapEntryFromKeyData(const char *keyData) { 118 char *ptr = const_cast<char *>(keyData) - sizeof(StringMapEntry<ValueTy>); 119 return *reinterpret_cast<StringMapEntry *>(ptr); 120 } 121 122 /// Destroy - Destroy this StringMapEntry, releasing memory back to the 123 /// specified allocator. 124 template <typename AllocatorTy> void Destroy(AllocatorTy &allocator) { 125 // Free memory referenced by the item. 126 size_t AllocSize = sizeof(StringMapEntry) + this->getKeyLength() + 1; 127 this->~StringMapEntry(); 128 allocator.Deallocate(static_cast<void *>(this), AllocSize, 129 alignof(StringMapEntry)); 130 } 131 }; 132 133 } // end namespace llvm 134 135 #endif // LLVM_ADT_STRINGMAPENTRY_H 136