diff options
author | River Riddle <riddleriver@gmail.com> | 2021-11-16 17:59:45 +0000 |
---|---|---|
committer | River Riddle <riddleriver@gmail.com> | 2021-11-16 18:54:14 +0000 |
commit | 4c484f11d355e4293f7b245a9330f0a1e89630ac (patch) | |
tree | 0e34c61206cb8a6560b4fcd208295b32059f9ea4 /llvm/unittests/ADT/DenseMapTest.cpp | |
parent | c6b9b702a049ba96294f174983016e8b3e11afb0 (diff) | |
download | llvm-4c484f11d355e4293f7b245a9330f0a1e89630ac.zip llvm-4c484f11d355e4293f7b245a9330f0a1e89630ac.tar.gz llvm-4c484f11d355e4293f7b245a9330f0a1e89630ac.tar.bz2 |
[llvm] Add a SFINAE template parameter to DenseMapInfo
This allows for using SFINAE partial specialization for DenseMapInfo.
In MLIR, this is particularly useful as it will allow for defining partial
specializations that support all Attribute, Op, and Type classes without
needing to specialize DenseMapInfo for each individual class.
Differential Revision: https://reviews.llvm.org/D113641
Diffstat (limited to 'llvm/unittests/ADT/DenseMapTest.cpp')
-rw-r--r-- | llvm/unittests/ADT/DenseMapTest.cpp | 43 |
1 files changed, 43 insertions, 0 deletions
diff --git a/llvm/unittests/ADT/DenseMapTest.cpp b/llvm/unittests/ADT/DenseMapTest.cpp index 352270a..4dd314c 100644 --- a/llvm/unittests/ADT/DenseMapTest.cpp +++ b/llvm/unittests/ADT/DenseMapTest.cpp @@ -655,4 +655,47 @@ TEST(DenseMapCustomTest, OpaquePointerKey) { EXPECT_EQ(Map.find(K2), Map.end()); EXPECT_EQ(Map.find(K3), Map.end()); } +} // namespace + +namespace { +struct A { + A(int value) : value(value) {} + int value; +}; +struct B : public A { + using A::A; +}; +} // namespace + +namespace llvm { +template <typename T> +struct DenseMapInfo<T, std::enable_if_t<std::is_base_of<A, T>::value>> { + static inline T getEmptyKey() { return {static_cast<int>(~0)}; } + static inline T getTombstoneKey() { return {static_cast<int>(~0U - 1)}; } + static unsigned getHashValue(const T &Val) { return Val.value; } + static bool isEqual(const T &LHS, const T &RHS) { + return LHS.value == RHS.value; + } +}; +} // namespace llvm + +namespace { +TEST(DenseMapCustomTest, SFINAEMapInfo) { + // Test that we can use a pointer to an incomplete type as a DenseMap key. + // This is an important build time optimization, since many classes have + // DenseMap members. + DenseMap<B, int> Map; + B Keys[3] = {{0}, {1}, {2}}; + Map.insert({Keys[0], 1}); + Map.insert({Keys[1], 2}); + Map.insert({Keys[2], 3}); + EXPECT_EQ(Map.count(Keys[0]), 1u); + EXPECT_EQ(Map[Keys[0]], 1); + EXPECT_EQ(Map[Keys[1]], 2); + EXPECT_EQ(Map[Keys[2]], 3); + Map.clear(); + EXPECT_EQ(Map.find(Keys[0]), Map.end()); + EXPECT_EQ(Map.find(Keys[1]), Map.end()); + EXPECT_EQ(Map.find(Keys[2]), Map.end()); } +} // namespace |