[tint] Simplify custom hash-code implementations
Instead of requiring a tint::Hasher<T> specialization, look for a
HashCode() method on T. This is far easier to implement than having to
drop out of the current namespace and into the `::tint` namespace.
Change-Id: Idee33a61332be740379e4f6fff356be388dd5565
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/152401
Reviewed-by: Antonio Maiorano <amaiorano@google.com>
Auto-Submit: Ben Clayton <bclayton@google.com>
Kokoro: Kokoro <noreply+kokoro@google.com>
Commit-Queue: Ben Clayton <bclayton@google.com>
diff --git a/src/tint/utils/math/hash.h b/src/tint/utils/math/hash.h
index 2fe6fee..38d9c92 100644
--- a/src/tint/utils/math/hash.h
+++ b/src/tint/utils/math/hash.h
@@ -60,6 +60,15 @@
}
};
+template <typename T, typename = void>
+struct HasHashCodeMember : std::false_type {};
+
+template <typename T>
+struct HasHashCodeMember<
+ T,
+ std::enable_if_t<std::is_member_function_pointer_v<decltype(&T::HashCode)>>> : std::true_type {
+};
+
} // namespace detail
/// Forward declarations (see below)
@@ -72,11 +81,20 @@
/// A STL-compatible hasher that does a more thorough job than most implementations of std::hash.
/// Hasher has been optimized for a better quality hash at the expense of increased computation
/// costs.
+/// Hasher is specialized for various core Tint data types. The default implementation will use a
+/// `size_t HashCode()` method on the `T` type, and will fallback to `std::hash<T>` if
+/// `T::HashCode` is missing.
template <typename T>
struct Hasher {
/// @param value the value to hash
/// @returns a hash of the value
- size_t operator()(const T& value) const { return std::hash<T>()(value); }
+ size_t operator()(const T& value) const {
+ if constexpr (detail::HasHashCodeMember<T>::value) {
+ return value.HashCode();
+ } else {
+ return std::hash<T>()(value);
+ }
+ }
};
/// Hasher specialization for pointers