[PATCH] D151079: [llvm][ADT] Change isEqual for DenseMapInfo<std::variant<...>>

Kadir Cetinkaya via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Tue May 23 07:53:04 PDT 2023


kadircet updated this revision to Diff 524719.
kadircet marked an inline comment as done.
kadircet added a comment.

- Add a test case for a type with different operator== and isEqual.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D151079/new/

https://reviews.llvm.org/D151079

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,17 @@
     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 +740,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,8 +318,19 @@
   }
 
   static bool isEqual(const Variant &LHS, const Variant &RHS) {
-    return LHS == RHS;
-  }
+    return LHS.index() == RHS.index() && std::visit(EqVisitor{}, LHS, RHS);
+  }
+
+ private:
+  struct EqVisitor {
+    template <typename T, typename U>
+    bool operator()(const T &LHS, const U &RHS) const {
+      return false;
+    }
+    template <typename T> bool operator()(const T &LHS, const T &RHS) const {
+      return DenseMapInfo<T>::isEqual(LHS, RHS);
+    }
+  };
 };
 } // end namespace llvm
 


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D151079.524719.patch
Type: text/x-patch
Size: 2301 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20230523/605fd1da/attachment-0001.bin>


More information about the llvm-commits mailing list