[llvm] c3c9312 - [Support] Automatically support `hash_value` when `HashBuilder` support is available.
Alexandre Rames via llvm-commits
llvm-commits at lists.llvm.org
Tue Sep 7 09:56:16 PDT 2021
Author: Alexandre Rames
Date: 2021-09-07T09:56:11-07:00
New Revision: c3c9312f7049e8a9b1bf05db877b4b39df897416
URL: https://github.com/llvm/llvm-project/commit/c3c9312f7049e8a9b1bf05db877b4b39df897416
DIFF: https://github.com/llvm/llvm-project/commit/c3c9312f7049e8a9b1bf05db877b4b39df897416.diff
LOG: [Support] Automatically support `hash_value` when `HashBuilder` support is available.
Use the `HBuilder` interface to provide default implementations of `llvm::hash_value`.
Reviewed By: dexonsmith
Differential Revision: https://reviews.llvm.org/D109024
Added:
Modified:
llvm/include/llvm/Support/HashBuilder.h
llvm/unittests/ADT/HashingTest.cpp
Removed:
################################################################################
diff --git a/llvm/include/llvm/Support/HashBuilder.h b/llvm/include/llvm/Support/HashBuilder.h
index 9ff5acf167298..bf93a0d22da73 100644
--- a/llvm/include/llvm/Support/HashBuilder.h
+++ b/llvm/include/llvm/Support/HashBuilder.h
@@ -16,6 +16,7 @@
#define LLVM_SUPPORT_HASHBUILDER_H
#include "llvm/ADT/ArrayRef.h"
+#include "llvm/ADT/Hashing.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/Support/Endian.h"
@@ -405,6 +406,33 @@ using HashBuilder =
HashBuilderImpl<HasherT, (Endianness == support::endianness::native
? support::endian::system_endianness()
: Endianness)>;
+
+namespace hashbuilder_detail {
+class HashCodeHasher {
+public:
+ HashCodeHasher() : Code(0) {}
+ void update(ArrayRef<uint8_t> Data) {
+ hash_code DataCode = hash_value(Data);
+ Code = hash_combine(Code, DataCode);
+ }
+ hash_code Code;
+};
+
+using HashCodeHashBuilder = HashBuilder<hashbuilder_detail::HashCodeHasher,
+ support::endianness::native>;
+} // namespace hashbuilder_detail
+
+/// Provide a default implementation of `hash_value` when `addHash(const T &)`
+/// is supported.
+template <typename T>
+std::enable_if_t<
+ is_detected<hashbuilder_detail::HashCodeHashBuilder::HasAddHashT, T>::value,
+ hash_code>
+hash_value(const T &Value) {
+ hashbuilder_detail::HashCodeHashBuilder HBuilder;
+ HBuilder.add(Value);
+ return HBuilder.getHasher().Code;
+}
} // end namespace llvm
#endif // LLVM_SUPPORT_HASHBUILDER_H
diff --git a/llvm/unittests/ADT/HashingTest.cpp b/llvm/unittests/ADT/HashingTest.cpp
index d2cda3afdda0f..bb19a569999f2 100644
--- a/llvm/unittests/ADT/HashingTest.cpp
+++ b/llvm/unittests/ADT/HashingTest.cpp
@@ -12,6 +12,7 @@
#include "llvm/ADT/Hashing.h"
#include "llvm/Support/DataTypes.h"
+#include "llvm/Support/HashBuilder.h"
#include "gtest/gtest.h"
#include <deque>
#include <list>
@@ -402,4 +403,36 @@ TEST(HashingTest, HashCombineArgs18) {
#undef CHECK_SAME
}
+struct StructWithHashBuilderSupport {
+ char C;
+ int I;
+ template <typename HasherT, llvm::support::endianness Endianness>
+ friend void addHash(llvm::HashBuilderImpl<HasherT, Endianness> &HBuilder,
+ const StructWithHashBuilderSupport &Value) {
+ HBuilder.add(Value.C, Value.I);
+ }
+};
+
+TEST(HashingTest, HashWithHashBuilder) {
+ StructWithHashBuilderSupport S{'c', 1};
+ EXPECT_NE(static_cast<size_t>(llvm::hash_value(S)), static_cast<size_t>(0));
}
+
+struct StructWithHashBuilderAndHashValueSupport {
+ char C;
+ int I;
+ template <typename HasherT, llvm::support::endianness Endianness>
+ friend void addHash(llvm::HashBuilderImpl<HasherT, Endianness> &HBuilder,
+ const StructWithHashBuilderAndHashValueSupport &Value) {}
+ friend hash_code
+ hash_value(const StructWithHashBuilderAndHashValueSupport &Value) {
+ return 0xbeef;
+ }
+};
+
+TEST(HashingTest, HashBuilderAndHashValue) {
+ StructWithHashBuilderAndHashValueSupport S{'c', 1};
+ EXPECT_EQ(static_cast<size_t>(hash_value(S)), static_cast<size_t>(0xbeef));
+}
+
+} // namespace
More information about the llvm-commits
mailing list