[PATCH] D151557: [ADT] Fix DenseMapInfo<variant>::isEqual to delegate to DenseMapInfo, not ==
Sam McCall via Phabricator via llvm-commits
llvm-commits at lists.llvm.org
Tue Jun 6 09:37:01 PDT 2023
This revision was landed with ongoing or failed builds.
This revision was automatically updated to reflect the committed changes.
sammccall marked an inline comment as done.
Closed by commit rG9e932e08a830: [ADT] Fix DenseMapInfo<variant>::isEqual to delegate to DenseMapInfo, not == (authored by sammccall).
Repository:
rG LLVM Github Monorepo
CHANGES SINCE LAST ACTION
https://reviews.llvm.org/D151557/new/
https://reviews.llvm.org/D151557
Files:
llvm/include/llvm/ADT/DenseMapInfo.h
llvm/unittests/ADT/DenseMapTest.cpp
Index: llvm/unittests/ADT/DenseMapTest.cpp
===================================================================
--- llvm/unittests/ADT/DenseMapTest.cpp
+++ llvm/unittests/ADT/DenseMapTest.cpp
@@ -690,6 +690,10 @@
struct B : public A {
using A::A;
};
+
+struct AlwaysEqType {
+ bool operator==(const AlwaysEqType &RHS) const { return true; }
+};
} // namespace
namespace llvm {
@@ -702,6 +706,16 @@
return LHS.value == RHS.value;
}
};
+
+template <> struct DenseMapInfo<AlwaysEqType> {
+ using T = AlwaysEqType;
+ static inline T getEmptyKey() { return {}; }
+ static inline T getTombstoneKey() { return {}; }
+ static unsigned getHashValue(const T &Val) { return 0; }
+ static bool isEqual(const T &LHS, const T &RHS) {
+ return false;
+ }
+};
} // namespace llvm
namespace {
@@ -725,16 +739,20 @@
}
TEST(DenseMapCustomTest, VariantSupport) {
- using variant = std::variant<int, int>;
+ using variant = std::variant<int, int, AlwaysEqType>;
DenseMap<variant, int> Map;
variant Keys[] = {
variant(std::in_place_index<0>, 1),
variant(std::in_place_index<1>, 1),
+ variant(std::in_place_index<2>),
};
Map.try_emplace(Keys[0], 0);
Map.try_emplace(Keys[1], 1);
EXPECT_THAT(Map, testing::SizeIs(2));
EXPECT_NE(DenseMapInfo<variant>::getHashValue(Keys[0]),
DenseMapInfo<variant>::getHashValue(Keys[1]));
+ // Check that isEqual dispatches to isEqual of underlying type, and not to
+ // operator==.
+ EXPECT_FALSE(DenseMapInfo<variant>::isEqual(Keys[2], Keys[2]));
}
} // namespace
Index: llvm/include/llvm/ADT/DenseMapInfo.h
===================================================================
--- llvm/include/llvm/ADT/DenseMapInfo.h
+++ llvm/include/llvm/ADT/DenseMapInfo.h
@@ -318,7 +318,22 @@
}
static bool isEqual(const Variant &LHS, const Variant &RHS) {
- return LHS == RHS;
+ if (LHS.index() != RHS.index())
+ return false;
+ if (LHS.valueless_by_exception())
+ return true;
+ // We want to dispatch to DenseMapInfo<T>::isEqual(LHS.get(I), RHS.get(I))
+ // We know the types are the same, but std::visit(V, LHS, RHS) doesn't.
+ // We erase the type held in LHS to void*, and dispatch over RHS.
+ const void *ErasedLHS =
+ std::visit([](const auto &LHS) -> const void * { return &LHS; }, LHS);
+ return std::visit(
+ [&](const auto &RHS) -> bool {
+ using T = std::remove_cv_t<std::remove_reference_t<decltype(RHS)>>;
+ return DenseMapInfo<T>::isEqual(*static_cast<const T *>(ErasedLHS),
+ RHS);
+ },
+ RHS);
}
};
} // end namespace llvm
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D151557.528906.patch
Type: text/x-patch
Size: 2666 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20230606/7cfd3295/attachment.bin>
More information about the llvm-commits
mailing list