Skip to content

Commit

Permalink
DenseMap: support enum class keys (llvm#95972)
Browse files Browse the repository at this point in the history
Implemented using std::underlying_type.
  • Loading branch information
artagnon authored Jun 19, 2024
1 parent 116384a commit d72b57b
Show file tree
Hide file tree
Showing 2 changed files with 32 additions and 2 deletions.
18 changes: 18 additions & 0 deletions llvm/include/llvm/ADT/DenseMapInfo.h
Original file line number Diff line number Diff line change
Expand Up @@ -297,6 +297,24 @@ template <typename... Ts> struct DenseMapInfo<std::tuple<Ts...>> {
}
};

// Provide DenseMapInfo for enum classes.
template <typename Enum>
struct DenseMapInfo<Enum, std::enable_if_t<std::is_enum_v<Enum>>> {
using UnderlyingType = std::underlying_type_t<Enum>;
using Info = DenseMapInfo<UnderlyingType>;

static Enum getEmptyKey() { return static_cast<Enum>(Info::getEmptyKey()); }

static Enum getTombstoneKey() {
return static_cast<Enum>(Info::getTombstoneKey());
}

static unsigned getHashValue(const Enum &Val) {
return Info::getHashValue(static_cast<UnderlyingType>(Val));
}

static bool isEqual(const Enum &LHS, const Enum &RHS) { return LHS == RHS; }
};
} // end namespace llvm

#endif // LLVM_ADT_DENSEMAPINFO_H
16 changes: 14 additions & 2 deletions llvm/unittests/ADT/DenseMapTest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,6 @@
using namespace llvm;

namespace {

uint32_t getTestKey(int i, uint32_t *) { return i; }
uint32_t getTestValue(int i, uint32_t *) { return 42 + i; }

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

enum class EnumClass { Val };

EnumClass getTestKey(int i, EnumClass *) {
// We can't possibly support 100 values for the swap test, so just return an
// invalid EnumClass for testing.
return static_cast<EnumClass>(i);
}

/// A test class that tries to check that construction and destruction
/// occur correctly.
class CtorTester {
Expand Down Expand Up @@ -104,14 +111,19 @@ template <typename T>
typename T::mapped_type *const DenseMapTest<T>::dummy_value_ptr = nullptr;

// Register these types for testing.
// clang-format off
typedef ::testing::Types<DenseMap<uint32_t, uint32_t>,
DenseMap<uint32_t *, uint32_t *>,
DenseMap<CtorTester, CtorTester, CtorTesterMapInfo>,
DenseMap<EnumClass, uint32_t>,
SmallDenseMap<uint32_t, uint32_t>,
SmallDenseMap<uint32_t *, uint32_t *>,
SmallDenseMap<CtorTester, CtorTester, 4,
CtorTesterMapInfo>
CtorTesterMapInfo>,
SmallDenseMap<EnumClass, uint32_t>
> DenseMapTestTypes;
// clang-format on

TYPED_TEST_SUITE(DenseMapTest, DenseMapTestTypes, );

// Empty map tests
Expand Down

0 comments on commit d72b57b

Please sign in to comment.