-
Notifications
You must be signed in to change notification settings - Fork 11k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Refactor StringMap.h, splitting StringMapEntry out to its own header.
Summary: StringMapEntry.h can have lower dependencies, than StringMap.h, which is useful for public headers that want to expose inline methods on StringMapEntry<> but don't need to expose all of StringMap.h. One example of this is mlir's Identifier.h, another example is the existing LLVM StringPool.h. StringPool also could use a cleanup, I'll deal with that in a follow-on patch. Reviewers: rriddle Subscribers: hiraditya, dexonsmith, llvm-commits Tags: #llvm Differential Revision: https://reviews.llvm.org/D77963
- Loading branch information
Showing
3 changed files
with
179 additions
and
154 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,152 @@ | ||
//===- StringMapEntry.h - String Hash table map interface -------*- C++ -*-===// | ||
// | ||
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. | ||
// See https://llvm.org/LICENSE.txt for license information. | ||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception | ||
// | ||
//===----------------------------------------------------------------------===// | ||
// | ||
// This file defines the StringMapEntry class - it is intended to be a low | ||
// dependency implementation detail of StringMap that is more suitable for | ||
// inclusion in public headers than StringMap.h itself is. | ||
// | ||
//===----------------------------------------------------------------------===// | ||
|
||
#ifndef LLVM_ADT_STRINGMAPENTRY_H | ||
#define LLVM_ADT_STRINGMAPENTRY_H | ||
|
||
#include "llvm/ADT/StringRef.h" | ||
#include "llvm/Support/AllocatorBase.h" | ||
|
||
namespace llvm { | ||
|
||
/// StringMapEntryBase - Shared base class of StringMapEntry instances. | ||
class StringMapEntryBase { | ||
size_t keyLength; | ||
|
||
public: | ||
explicit StringMapEntryBase(size_t keyLength) : keyLength(keyLength) {} | ||
|
||
size_t getKeyLength() const { return keyLength; } | ||
}; | ||
|
||
/// StringMapEntryStorage - Holds the value in a StringMapEntry. | ||
/// | ||
/// Factored out into a separate base class to make it easier to specialize. | ||
/// This is primarily intended to support StringSet, which doesn't need a value | ||
/// stored at all. | ||
template <typename ValueTy> | ||
class StringMapEntryStorage : public StringMapEntryBase { | ||
public: | ||
ValueTy second; | ||
|
||
explicit StringMapEntryStorage(size_t keyLength) | ||
: StringMapEntryBase(keyLength), second() {} | ||
template <typename... InitTy> | ||
StringMapEntryStorage(size_t keyLength, InitTy &&... initVals) | ||
: StringMapEntryBase(keyLength), | ||
second(std::forward<InitTy>(initVals)...) {} | ||
StringMapEntryStorage(StringMapEntryStorage &e) = delete; | ||
|
||
const ValueTy &getValue() const { return second; } | ||
ValueTy &getValue() { return second; } | ||
|
||
void setValue(const ValueTy &V) { second = V; } | ||
}; | ||
|
||
template <> class StringMapEntryStorage<NoneType> : public StringMapEntryBase { | ||
public: | ||
explicit StringMapEntryStorage(size_t keyLength, NoneType none = None) | ||
: StringMapEntryBase(keyLength) {} | ||
StringMapEntryStorage(StringMapEntryStorage &entry) = delete; | ||
|
||
NoneType getValue() const { return None; } | ||
}; | ||
|
||
/// StringMapEntry - This is used to represent one value that is inserted into | ||
/// a StringMap. It contains the Value itself and the key: the string length | ||
/// and data. | ||
template <typename ValueTy> | ||
class StringMapEntry final : public StringMapEntryStorage<ValueTy> { | ||
public: | ||
using StringMapEntryStorage<ValueTy>::StringMapEntryStorage; | ||
|
||
StringRef getKey() const { | ||
return StringRef(getKeyData(), this->getKeyLength()); | ||
} | ||
|
||
/// getKeyData - Return the start of the string data that is the key for this | ||
/// value. The string data is always stored immediately after the | ||
/// StringMapEntry object. | ||
const char *getKeyData() const { | ||
return reinterpret_cast<const char *>(this + 1); | ||
} | ||
|
||
StringRef first() const { | ||
return StringRef(getKeyData(), this->getKeyLength()); | ||
} | ||
|
||
/// Create a StringMapEntry for the specified key construct the value using | ||
/// \p InitiVals. | ||
template <typename AllocatorTy, typename... InitTy> | ||
static StringMapEntry *Create(StringRef key, AllocatorTy &allocator, | ||
InitTy &&... initVals) { | ||
size_t keyLength = key.size(); | ||
|
||
// Allocate a new item with space for the string at the end and a null | ||
// terminator. | ||
size_t allocSize = sizeof(StringMapEntry) + keyLength + 1; | ||
size_t alignment = alignof(StringMapEntry); | ||
|
||
StringMapEntry *newItem = | ||
static_cast<StringMapEntry *>(allocator.Allocate(allocSize, alignment)); | ||
assert(newItem && "Unhandled out-of-memory"); | ||
|
||
// Construct the value. | ||
new (newItem) StringMapEntry(keyLength, std::forward<InitTy>(initVals)...); | ||
|
||
// Copy the string information. | ||
char *strBuffer = const_cast<char *>(newItem->getKeyData()); | ||
if (keyLength > 0) | ||
memcpy(strBuffer, key.data(), keyLength); | ||
strBuffer[keyLength] = 0; // Null terminate for convenience of clients. | ||
return newItem; | ||
} | ||
|
||
/// Create - Create a StringMapEntry with normal malloc/free. | ||
template <typename... InitType> | ||
static StringMapEntry *Create(StringRef key, InitType &&... initVal) { | ||
MallocAllocator allocator; | ||
return Create(key, allocator, std::forward<InitType>(initVal)...); | ||
} | ||
|
||
static StringMapEntry *Create(StringRef key) { | ||
return Create(key, ValueTy()); | ||
} | ||
|
||
/// GetStringMapEntryFromKeyData - Given key data that is known to be embedded | ||
/// into a StringMapEntry, return the StringMapEntry itself. | ||
static StringMapEntry &GetStringMapEntryFromKeyData(const char *keyData) { | ||
char *ptr = const_cast<char *>(keyData) - sizeof(StringMapEntry<ValueTy>); | ||
return *reinterpret_cast<StringMapEntry *>(ptr); | ||
} | ||
|
||
/// Destroy - Destroy this StringMapEntry, releasing memory back to the | ||
/// specified allocator. | ||
template <typename AllocatorTy> void Destroy(AllocatorTy &allocator) { | ||
// Free memory referenced by the item. | ||
size_t AllocSize = sizeof(StringMapEntry) + this->getKeyLength() + 1; | ||
this->~StringMapEntry(); | ||
allocator.Deallocate(static_cast<void *>(this), AllocSize); | ||
} | ||
|
||
/// Destroy this object, releasing memory back to the malloc allocator. | ||
void Destroy() { | ||
MallocAllocator allocator; | ||
Destroy(allocator); | ||
} | ||
}; | ||
|
||
} // end namespace llvm | ||
|
||
#endif // LLVM_ADT_STRINGMAPENTRY_H |
Oops, something went wrong.