From 359738b6caedfde27885ea3f4e501e4ae8c377c0 Mon Sep 17 00:00:00 2001 From: Nick Gerleman Date: Mon, 29 Jan 2024 17:39:49 -0800 Subject: [PATCH] Remove redundant `std::hash` enum specializations (#42651) Summary: Pull Request resolved: https://github.com/facebook/react-native/pull/42651 Lots of boilerplate to define hash functions for different enums, so we can use them in `hash_combine`. This should not be needed, and seems like it might have been an artifact of older C++ version of standard library with bugs. https://en.cppreference.com/w/cpp/utility/hash > In addition to the above, the standard library provides specializations for all (scoped and unscoped) enumeration types. These may be (but are not required to be) implemented as std::hash::type>. Also moves `hash_combine` SFINAE to concepts for clarity and better error messages. Changelog: [Internal] Reviewed By: christophpurrer Differential Revision: D53074535 fbshipit-source-id: 5fcb653dbe4aa51aa3d9d96f1511da3b7541270d --- .../renderer/attributedstring/primitives.h | 86 ------------------- .../components/view/AccessibilityPrimitives.h | 16 ---- .../react/renderer/core/LayoutPrimitives.h | 17 ---- .../ReactCommon/react/utils/hash_combine.h | 14 +-- 4 files changed, 8 insertions(+), 125 deletions(-) diff --git a/packages/react-native/ReactCommon/react/renderer/attributedstring/primitives.h b/packages/react-native/ReactCommon/react/renderer/attributedstring/primitives.h index e528eabd9f1..817d487e3bb 100644 --- a/packages/react-native/ReactCommon/react/renderer/attributedstring/primitives.h +++ b/packages/react-native/ReactCommon/react/renderer/attributedstring/primitives.h @@ -120,89 +120,3 @@ enum class HyphenationFrequency { }; } // namespace facebook::react - -namespace std { -template <> -struct hash { - size_t operator()(const facebook::react::FontVariant& v) const { - return hash()(static_cast(v)); - } -}; - -template <> -struct hash { - size_t operator()(const facebook::react::TextAlignment& v) const { - return hash()(static_cast(v)); - } -}; - -template <> -struct hash { - size_t operator()(const facebook::react::FontStyle& v) const { - return hash()(static_cast(v)); - } -}; - -template <> -struct hash { - size_t operator()(const facebook::react::TextDecorationLineType& v) const { - return hash()(static_cast(v)); - } -}; - -template <> -struct hash { - size_t operator()(const facebook::react::WritingDirection& v) const { - return hash()(static_cast(v)); - } -}; - -template <> -struct hash { - size_t operator()(const facebook::react::TextDecorationStyle& v) const { - return hash()(static_cast(v)); - } -}; - -template <> -struct hash { - size_t operator()(const facebook::react::FontWeight& v) const { - return hash()(static_cast(v)); - } -}; - -template <> -struct hash { - size_t operator()(const facebook::react::DynamicTypeRamp& v) const { - return hash()(static_cast(v)); - } -}; - -template <> -struct hash { - size_t operator()(const facebook::react::EllipsizeMode& v) const { - return hash()(static_cast(v)); - } -}; - -template <> -struct hash { - size_t operator()(const facebook::react::TextBreakStrategy& v) const { - return hash()(static_cast(v)); - } -}; - -template <> -struct hash { - size_t operator()(const facebook::react::TextTransform& v) const { - return hash()(static_cast(v)); - } -}; - -template <> -struct hash { - size_t operator()(const facebook::react::HyphenationFrequency& v) const { - return hash()(static_cast(v)); - } -}; -} // namespace std diff --git a/packages/react-native/ReactCommon/react/renderer/components/view/AccessibilityPrimitives.h b/packages/react-native/ReactCommon/react/renderer/components/view/AccessibilityPrimitives.h index 48faeb20762..420a10852af 100644 --- a/packages/react-native/ReactCommon/react/renderer/components/view/AccessibilityPrimitives.h +++ b/packages/react-native/ReactCommon/react/renderer/components/view/AccessibilityPrimitives.h @@ -248,19 +248,3 @@ enum class Role { }; } // namespace facebook::react - -namespace std { -template <> -struct hash { - size_t operator()(const facebook::react::AccessibilityRole& v) const { - return hash()(static_cast(v)); - } -}; - -template <> -struct hash { - size_t operator()(const facebook::react::Role& v) const { - return hash()(static_cast(v)); - } -}; -} // namespace std diff --git a/packages/react-native/ReactCommon/react/renderer/core/LayoutPrimitives.h b/packages/react-native/ReactCommon/react/renderer/core/LayoutPrimitives.h index 45ab223faba..bbe6e548458 100644 --- a/packages/react-native/ReactCommon/react/renderer/core/LayoutPrimitives.h +++ b/packages/react-native/ReactCommon/react/renderer/core/LayoutPrimitives.h @@ -38,20 +38,3 @@ enum class LayoutDirection { }; } // namespace facebook::react - -namespace std { -template <> -struct hash { - size_t operator()(const facebook::react::LayoutDirection& v) const { - return hash()(static_cast(v)); - } -}; - -template <> -struct hash { - size_t operator()(const facebook::react::DisplayType& v) const { - return hash()(static_cast(v)); - } -}; - -} // namespace std diff --git a/packages/react-native/ReactCommon/react/utils/hash_combine.h b/packages/react-native/ReactCommon/react/utils/hash_combine.h index 2cb16d84a9f..dab82ca53aa 100644 --- a/packages/react-native/ReactCommon/react/utils/hash_combine.h +++ b/packages/react-native/ReactCommon/react/utils/hash_combine.h @@ -8,20 +8,22 @@ #pragma once #include +#include namespace facebook::react { -template < - typename T, - typename... Rest, - bool Enabled = !std::is_same::value, - typename = typename std::enable_if::type> +template +concept Hashable = !std::is_same_v && (requires(T a) { + { std::hash{}(a) } -> std::convertible_to; +}); + +template void hash_combine(std::size_t& seed, const T& v, const Rest&... rest) { seed ^= std::hash{}(v) + 0x9e3779b9 + (seed << 6) + (seed >> 2); (hash_combine(seed, rest), ...); } -template +template std::size_t hash_combine(const T& v, const Args&... args) { std::size_t seed = 0; hash_combine(seed, v, args...);