blob: ea3aad6f1cb1b61a9238aba6d2583021b3164f1b [file] [log] [blame]
Olivier Deprezf4ef2d02021-04-20 13:36:24 +02001//===- 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