[PATCH] D156005: Use `getHashValue` in `SetVector::insert` and `SetVector::contains`

Evan Wilde via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Sat Jul 22 15:54:12 PDT 2023


etcwilde updated this revision to Diff 543233.
etcwilde edited the summary of this revision.
etcwilde added a comment.

Adding test that fails to build with current implementation that used to build with original SetVector `insert` and `contains` implementation.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D156005

Files:
  llvm/include/llvm/ADT/SetVector.h
  llvm/unittests/ADT/SetVectorTest.cpp


Index: llvm/unittests/ADT/SetVectorTest.cpp
===================================================================
--- llvm/unittests/ADT/SetVectorTest.cpp
+++ llvm/unittests/ADT/SetVectorTest.cpp
@@ -86,3 +86,36 @@
   EXPECT_FALSE(S.contains(&j));
   EXPECT_FALSE(S.contains((const int *)&j));
 }
+
+struct NonEquatableType {
+  int Value;
+  bool operator==(const NonEquatableType &) const = delete;
+
+  NonEquatableType(int Value): Value(Value) {}
+};
+
+namespace llvm {
+template <> struct DenseMapInfo<NonEquatableType> {
+  static inline NonEquatableType getEmptyKey() { return NonEquatableType(-1); }
+  static inline NonEquatableType getTombstoneKey() {
+    return NonEquatableType(-2);
+  }
+  static unsigned getHashValue(const NonEquatableType &Val) {
+    return Val.Value;
+  }
+
+  static bool isEqual(const NonEquatableType &LHS,
+                      const NonEquatableType &RHS) {
+    return LHS.Value == RHS.Value;
+  }
+};
+} // namespace llvm
+
+TEST(SmallSetVector, InsertNonEquatableType) {
+  SmallSetVector<NonEquatableType, 2> S;
+  S.insert(NonEquatableType(1));
+  S.insert(NonEquatableType(2));
+  S.insert(NonEquatableType(3));
+  EXPECT_TRUE(S.contains(NonEquatableType(2)));
+  EXPECT_FALSE(S.insert(NonEquatableType(3)));
+}
Index: llvm/include/llvm/ADT/SetVector.h
===================================================================
--- llvm/include/llvm/ADT/SetVector.h
+++ llvm/include/llvm/ADT/SetVector.h
@@ -56,7 +56,7 @@
           typename Set = DenseSet<T>, unsigned N = 0>
 class SetVector {
   // Much like in SmallPtrSet, this value should not be too high to prevent
-  // excessively long linear scans from occuring.
+  // excessively long linear scans from occurring.
   static_assert(N <= 32, "Small size should be less than or equal to 32!");
 
 public:
@@ -162,7 +162,10 @@
   bool insert(const value_type &X) {
     if constexpr (canBeSmall())
       if (isSmall()) {
-        if (llvm::find(vector_, X) == vector_.end()) {
+        auto comparator = [&X](const value_type &element) -> bool {
+          return llvm::DenseMapInfo<value_type>::isEqual(X, element);
+        };
+        if (llvm::find_if(vector_, comparator) == vector_.end()) {
           vector_.push_back(X);
           if (vector_.size() > N)
             makeBig();
@@ -253,8 +256,12 @@
   /// Check if the SetVector contains the given key.
   bool contains(const key_type &key) const {
     if constexpr (canBeSmall())
-      if (isSmall())
-        return is_contained(vector_, key);
+      if (isSmall()) {
+        auto comparator = [&key](const value_type &element) -> bool {
+          return llvm::DenseMapInfo<value_type>::isEqual(key, element);
+        };
+        return llvm::find_if(vector_, comparator) != vector_.end();
+      }
 
     return set_.find(key) != set_.end();
   }
@@ -262,11 +269,7 @@
   /// Count the number of elements of a given key in the SetVector.
   /// \returns 0 if the element is not in the SetVector, 1 if it is.
   size_type count(const key_type &key) const {
-    if constexpr (canBeSmall())
-      if (isSmall())
-        return is_contained(vector_, key);
-
-    return set_.count(key);
+    return contains(key);
   }
 
   /// Completely clear the SetVector


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D156005.543233.patch
Type: text/x-patch
Size: 3225 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20230722/87e1852b/attachment.bin>


More information about the llvm-commits mailing list