Skip to content

Commit d72b57b

Browse files
authored
DenseMap: support enum class keys (#95972)
Implemented using std::underlying_type.
1 parent 116384a commit d72b57b

File tree

2 files changed

+32
-2
lines changed

2 files changed

+32
-2
lines changed

llvm/include/llvm/ADT/DenseMapInfo.h

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -297,6 +297,24 @@ template <typename... Ts> struct DenseMapInfo<std::tuple<Ts...>> {
297297
}
298298
};
299299

300+
// Provide DenseMapInfo for enum classes.
301+
template <typename Enum>
302+
struct DenseMapInfo<Enum, std::enable_if_t<std::is_enum_v<Enum>>> {
303+
using UnderlyingType = std::underlying_type_t<Enum>;
304+
using Info = DenseMapInfo<UnderlyingType>;
305+
306+
static Enum getEmptyKey() { return static_cast<Enum>(Info::getEmptyKey()); }
307+
308+
static Enum getTombstoneKey() {
309+
return static_cast<Enum>(Info::getTombstoneKey());
310+
}
311+
312+
static unsigned getHashValue(const Enum &Val) {
313+
return Info::getHashValue(static_cast<UnderlyingType>(Val));
314+
}
315+
316+
static bool isEqual(const Enum &LHS, const Enum &RHS) { return LHS == RHS; }
317+
};
300318
} // end namespace llvm
301319

302320
#endif // LLVM_ADT_DENSEMAPINFO_H

llvm/unittests/ADT/DenseMapTest.cpp

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,6 @@
2121
using namespace llvm;
2222

2323
namespace {
24-
2524
uint32_t getTestKey(int i, uint32_t *) { return i; }
2625
uint32_t getTestValue(int i, uint32_t *) { return 42 + i; }
2726

@@ -36,6 +35,14 @@ uint32_t *getTestValue(int i, uint32_t **) {
3635
return &dummy_arr1[i];
3736
}
3837

38+
enum class EnumClass { Val };
39+
40+
EnumClass getTestKey(int i, EnumClass *) {
41+
// We can't possibly support 100 values for the swap test, so just return an
42+
// invalid EnumClass for testing.
43+
return static_cast<EnumClass>(i);
44+
}
45+
3946
/// A test class that tries to check that construction and destruction
4047
/// occur correctly.
4148
class CtorTester {
@@ -104,14 +111,19 @@ template <typename T>
104111
typename T::mapped_type *const DenseMapTest<T>::dummy_value_ptr = nullptr;
105112

106113
// Register these types for testing.
114+
// clang-format off
107115
typedef ::testing::Types<DenseMap<uint32_t, uint32_t>,
108116
DenseMap<uint32_t *, uint32_t *>,
109117
DenseMap<CtorTester, CtorTester, CtorTesterMapInfo>,
118+
DenseMap<EnumClass, uint32_t>,
110119
SmallDenseMap<uint32_t, uint32_t>,
111120
SmallDenseMap<uint32_t *, uint32_t *>,
112121
SmallDenseMap<CtorTester, CtorTester, 4,
113-
CtorTesterMapInfo>
122+
CtorTesterMapInfo>,
123+
SmallDenseMap<EnumClass, uint32_t>
114124
> DenseMapTestTypes;
125+
// clang-format on
126+
115127
TYPED_TEST_SUITE(DenseMapTest, DenseMapTestTypes, );
116128

117129
// Empty map tests

0 commit comments

Comments
 (0)