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 20namespace llvm { 21 22/// StringMapEntryBase - Shared base class of StringMapEntry instances. 23class StringMapEntryBase { 24 size_t keyLength; 25 26public: 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. 37template <typename ValueTy> 38class StringMapEntryStorage : public StringMapEntryBase { 39public: 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 56template <> class StringMapEntryStorage<NoneType> : public StringMapEntryBase { 57public: 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. 68template <typename ValueTy> 69class StringMapEntry final : public StringMapEntryStorage<ValueTy> { 70public: 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