File indexing completed on 2026-05-10 08:43:10
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016 #ifndef LLVM_ADT_STRINGMAPENTRY_H
0017 #define LLVM_ADT_STRINGMAPENTRY_H
0018
0019 #include "llvm/ADT/StringRef.h"
0020 #include <utility>
0021
0022 namespace llvm {
0023
0024
0025 class StringMapEntryBase {
0026 size_t keyLength;
0027
0028 public:
0029 explicit StringMapEntryBase(size_t keyLength) : keyLength(keyLength) {}
0030
0031 size_t getKeyLength() const { return keyLength; }
0032
0033 protected:
0034
0035
0036
0037 template <typename AllocatorTy>
0038 static void *allocateWithKey(size_t EntrySize, size_t EntryAlign,
0039 StringRef Key, AllocatorTy &Allocator);
0040 };
0041
0042
0043 template <typename AllocatorTy>
0044 void *StringMapEntryBase::allocateWithKey(size_t EntrySize, size_t EntryAlign,
0045 StringRef Key,
0046 AllocatorTy &Allocator) {
0047 size_t KeyLength = Key.size();
0048
0049
0050
0051 size_t AllocSize = EntrySize + KeyLength + 1;
0052 void *Allocation = Allocator.Allocate(AllocSize, EntryAlign);
0053 assert(Allocation && "Unhandled out-of-memory");
0054
0055
0056 char *Buffer = reinterpret_cast<char *>(Allocation) + EntrySize;
0057 if (KeyLength > 0)
0058 ::memcpy(Buffer, Key.data(), KeyLength);
0059 Buffer[KeyLength] = 0;
0060 return Allocation;
0061 }
0062
0063
0064
0065
0066
0067
0068 template <typename ValueTy>
0069 class StringMapEntryStorage : public StringMapEntryBase {
0070 public:
0071 ValueTy second;
0072
0073 explicit StringMapEntryStorage(size_t keyLength)
0074 : StringMapEntryBase(keyLength), second() {}
0075 template <typename... InitTy>
0076 StringMapEntryStorage(size_t keyLength, InitTy &&...initVals)
0077 : StringMapEntryBase(keyLength),
0078 second(std::forward<InitTy>(initVals)...) {}
0079 StringMapEntryStorage(StringMapEntryStorage &e) = delete;
0080
0081 const ValueTy &getValue() const { return second; }
0082 ValueTy &getValue() { return second; }
0083
0084 void setValue(const ValueTy &V) { second = V; }
0085 };
0086
0087 template <>
0088 class StringMapEntryStorage<std::nullopt_t> : public StringMapEntryBase {
0089 public:
0090 explicit StringMapEntryStorage(size_t keyLength,
0091 std::nullopt_t = std::nullopt)
0092 : StringMapEntryBase(keyLength) {}
0093 StringMapEntryStorage(StringMapEntryStorage &entry) = delete;
0094
0095 std::nullopt_t getValue() const { return std::nullopt; }
0096 };
0097
0098
0099
0100
0101 template <typename ValueTy>
0102 class StringMapEntry final : public StringMapEntryStorage<ValueTy> {
0103 public:
0104 using StringMapEntryStorage<ValueTy>::StringMapEntryStorage;
0105
0106 using ValueType = ValueTy;
0107
0108 StringRef getKey() const {
0109 return StringRef(getKeyData(), this->getKeyLength());
0110 }
0111
0112
0113
0114
0115 const char *getKeyData() const {
0116 return reinterpret_cast<const char *>(this + 1);
0117 }
0118
0119 StringRef first() const { return getKey(); }
0120
0121
0122
0123 template <typename AllocatorTy, typename... InitTy>
0124 static StringMapEntry *create(StringRef key, AllocatorTy &allocator,
0125 InitTy &&...initVals) {
0126 return new (StringMapEntryBase::allocateWithKey(
0127 sizeof(StringMapEntry), alignof(StringMapEntry), key, allocator))
0128 StringMapEntry(key.size(), std::forward<InitTy>(initVals)...);
0129 }
0130
0131
0132
0133 static StringMapEntry &GetStringMapEntryFromKeyData(const char *keyData) {
0134 char *ptr = const_cast<char *>(keyData) - sizeof(StringMapEntry<ValueTy>);
0135 return *reinterpret_cast<StringMapEntry *>(ptr);
0136 }
0137
0138
0139
0140 template <typename AllocatorTy> void Destroy(AllocatorTy &allocator) {
0141
0142 size_t AllocSize = sizeof(StringMapEntry) + this->getKeyLength() + 1;
0143 this->~StringMapEntry();
0144 allocator.Deallocate(static_cast<void *>(this), AllocSize,
0145 alignof(StringMapEntry));
0146 }
0147 };
0148
0149
0150
0151 template <std::size_t Index, typename ValueTy>
0152 decltype(auto) get(StringMapEntry<ValueTy> &E) {
0153 static_assert(Index < 2);
0154 if constexpr (Index == 0)
0155 return E.getKey();
0156 else
0157 return E.getValue();
0158 }
0159
0160 template <std::size_t Index, typename ValueTy>
0161 decltype(auto) get(const StringMapEntry<ValueTy> &E) {
0162 static_assert(Index < 2);
0163 if constexpr (Index == 0)
0164 return E.getKey();
0165 else
0166 return E.getValue();
0167 }
0168
0169 }
0170
0171 template <typename ValueTy>
0172 struct std::tuple_size<llvm::StringMapEntry<ValueTy>>
0173 : std::integral_constant<std::size_t, 2> {};
0174
0175 template <std::size_t Index, typename ValueTy>
0176 struct std::tuple_element<Index, llvm::StringMapEntry<ValueTy>>
0177 : std::tuple_element<Index, std::pair<llvm::StringRef, ValueTy>> {};
0178
0179 #endif