Skip to content

Commit 49b87cd

Browse files
authored
DenseMapInfo: support std::optional<T> (#147851)
1 parent c92d5da commit 49b87cd

File tree

2 files changed

+35
-1
lines changed

2 files changed

+35
-1
lines changed

llvm/include/llvm/ADT/DenseMapInfo.h

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
#include <cassert>
1818
#include <cstddef>
1919
#include <cstdint>
20+
#include <optional>
2021
#include <tuple>
2122
#include <type_traits>
2223
#include <utility>
@@ -320,6 +321,28 @@ struct DenseMapInfo<Enum, std::enable_if_t<std::is_enum_v<Enum>>> {
320321

321322
static bool isEqual(const Enum &LHS, const Enum &RHS) { return LHS == RHS; }
322323
};
324+
325+
template <typename T> struct DenseMapInfo<std::optional<T>> {
326+
using Optional = std::optional<T>;
327+
using Info = DenseMapInfo<T>;
328+
329+
static inline Optional getEmptyKey() { return {Info::getEmptyKey()}; }
330+
331+
static inline Optional getTombstoneKey() { return {Info::getTombstoneKey()}; }
332+
333+
static unsigned getHashValue(const Optional &OptionalVal) {
334+
return detail::combineHashValue(
335+
OptionalVal.has_value(),
336+
Info::getHashValue(OptionalVal.value_or(Info::getEmptyKey())));
337+
}
338+
339+
static bool isEqual(const Optional &LHS, const Optional &RHS) {
340+
if (LHS && RHS) {
341+
return Info::isEqual(LHS.value(), RHS.value());
342+
}
343+
return !LHS && !RHS;
344+
}
345+
};
323346
} // end namespace llvm
324347

325348
#endif // LLVM_ADT_DENSEMAPINFO_H

llvm/unittests/ADT/DenseMapTest.cpp

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
#include "gmock/gmock.h"
1616
#include "gtest/gtest.h"
1717
#include <map>
18+
#include <optional>
1819
#include <set>
1920
#include <utility>
2021
#include <variant>
@@ -86,6 +87,14 @@ struct CtorTesterMapInfo {
8687
CtorTester getTestKey(int i, CtorTester *) { return CtorTester(i); }
8788
CtorTester getTestValue(int i, CtorTester *) { return CtorTester(42 + i); }
8889

90+
std::optional<uint32_t> getTestKey(int i, std::optional<uint32_t> *) {
91+
return i;
92+
}
93+
94+
std::optional<uint32_t> getTestValue(int i, std::optional<uint32_t> *) {
95+
return 42 + i;
96+
}
97+
8998
// Test fixture, with helper functions implemented by forwarding to global
9099
// function overloads selected by component types of the type parameter. This
91100
// allows all of the map implementations to be tested with shared
@@ -117,11 +126,13 @@ typedef ::testing::Types<DenseMap<uint32_t, uint32_t>,
117126
DenseMap<uint32_t *, uint32_t *>,
118127
DenseMap<CtorTester, CtorTester, CtorTesterMapInfo>,
119128
DenseMap<EnumClass, uint32_t>,
129+
DenseMap<std::optional<uint32_t>, uint32_t>,
120130
SmallDenseMap<uint32_t, uint32_t>,
121131
SmallDenseMap<uint32_t *, uint32_t *>,
122132
SmallDenseMap<CtorTester, CtorTester, 4,
123133
CtorTesterMapInfo>,
124-
SmallDenseMap<EnumClass, uint32_t>
134+
SmallDenseMap<EnumClass, uint32_t>,
135+
SmallDenseMap<std::optional<uint32_t>, uint32_t>
125136
> DenseMapTestTypes;
126137
// clang-format on
127138

0 commit comments

Comments
 (0)