[PATCH] D139240: [llvm] Add support for hashing std::optional

Kazu Hirata via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Fri Dec 2 17:37:16 PST 2022


kazu created this revision.
Herald added a project: All.
kazu requested review of this revision.
Herald added a project: LLVM.
Herald added a subscriber: llvm-commits.

The credit for the hashing code, taken from D138934 <https://reviews.llvm.org/D138934>, goes to Ramkumar
Ramachandra.  The test comes from OptionalTest.cpp and updated for
std::optional.

This is part of an effort to migrate from llvm::Optional to
std::optional:

https://discourse.llvm.org/t/deprecating-llvm-optional-x-hasvalue-getvalue-getvalueor/63716


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D139240

Files:
  llvm/include/llvm/ADT/Hashing.h
  llvm/unittests/ADT/HashingTest.cpp


Index: llvm/unittests/ADT/HashingTest.cpp
===================================================================
--- llvm/unittests/ADT/HashingTest.cpp
+++ llvm/unittests/ADT/HashingTest.cpp
@@ -17,6 +17,7 @@
 #include <deque>
 #include <list>
 #include <map>
+#include <optional>
 #include <vector>
 
 namespace llvm {
@@ -130,6 +131,23 @@
             hash_value(ws.substr(1, ws.size() - 2)));
 }
 
+TEST(HashingTest, HashValueStdOptional) {
+  // Check that std::nullopt, false, and true all hash differently.
+  std::optional<bool> B, B0 = false, B1 = true;
+  EXPECT_NE(hash_value(B0), hash_value(B));
+  EXPECT_NE(hash_value(B1), hash_value(B));
+  EXPECT_NE(hash_value(B1), hash_value(B0));
+
+  // Check that std::nullopt, 0, and 1 all hash differently.
+  std::optional<int> I, I0 = 0, I1 = 1;
+  EXPECT_NE(hash_value(I0), hash_value(I));
+  EXPECT_NE(hash_value(I1), hash_value(I));
+  EXPECT_NE(hash_value(I1), hash_value(I0));
+
+  // Check std::nullopt hash the same way regardless of type.
+  EXPECT_EQ(hash_value(B), hash_value(I));
+}
+
 template <typename T, size_t N> T *begin(T (&arr)[N]) { return arr; }
 template <typename T, size_t N> T *end(T (&arr)[N]) { return arr + N; }
 
Index: llvm/include/llvm/ADT/Hashing.h
===================================================================
--- llvm/include/llvm/ADT/Hashing.h
+++ llvm/include/llvm/ADT/Hashing.h
@@ -51,6 +51,7 @@
 #include <algorithm>
 #include <cassert>
 #include <cstring>
+#include <optional>
 #include <string>
 #include <tuple>
 #include <utility>
@@ -122,6 +123,8 @@
 template <typename T>
 hash_code hash_value(const std::basic_string<T> &arg);
 
+/// Compute a hash_code for a standard string.
+template <typename T> hash_code hash_value(const std::optional<T> &arg);
 
 /// Override the execution seed with a fixed value.
 ///
@@ -662,6 +665,10 @@
   return hash_combine_range(arg.begin(), arg.end());
 }
 
+template <typename T> hash_code hash_value(const std::optional<T> &arg) {
+  return arg ? hash_combine(true, *arg) : hash_value(false);
+}
+
 template <> struct DenseMapInfo<hash_code, void> {
   static inline hash_code getEmptyKey() { return hash_code(-1); }
   static inline hash_code getTombstoneKey() { return hash_code(-2); }


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D139240.479787.patch
Type: text/x-patch
Size: 2228 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20221203/0dd11288/attachment-0001.bin>


More information about the llvm-commits mailing list