From 64bc3dba6c652096970b899df6ce98fb6413a2f0 Mon Sep 17 00:00:00 2001 From: neargye Date: Mon, 12 Jun 2023 17:43:57 +0400 Subject: [PATCH] add MAGIC_ENUM_ENABLE_HASH_SWITCH --- include/magic_enum.hpp | 49 ++++++----------------------------- include/magic_enum_switch.hpp | 6 ++--- 2 files changed, 11 insertions(+), 44 deletions(-) diff --git a/include/magic_enum.hpp b/include/magic_enum.hpp index b629d33..cab56b6 100644 --- a/include/magic_enum.hpp +++ b/include/magic_enum.hpp @@ -864,10 +864,7 @@ struct underlying_type {}; template struct underlying_type : std::underlying_type> {}; -#if defined(MAGIC_ENUM_ENABLE_HASH) - -template -inline constexpr bool has_hash = true; +#if defined(MAGIC_ENUM_ENABLE_HASH) || defined(MAGIC_ENUM_ENABLE_HASH_SWITCH) template struct constexpr_hash_t; @@ -1032,13 +1029,13 @@ constexpr bool has_duplicate() noexcept { if constexpr (std::is_invocable_r_v>) { \ return detail::invoke_r(std::forward(lambda), std::integral_constant{}); \ } else if constexpr (std::is_invocable_v>) { \ - assert(false && "magic_enum::detail::constexpr_switch wrong result type."); \ + MAGIC_ENUM_ASSERT(false && "magic_enum::detail::constexpr_switch wrong result type."); \ } \ } else if constexpr (CallValue == case_call_t::value) { \ if constexpr (std::is_invocable_r_v>) { \ return detail::invoke_r(std::forward(lambda), enum_constant{}); \ } else if constexpr (std::is_invocable_r_v>) { \ - assert(false && "magic_enum::detail::constexpr_switch wrong result type."); \ + MAGIC_ENUM_ASSERT(false && "magic_enum::detail::constexpr_switch wrong result type."); \ } \ } \ break; \ @@ -1076,34 +1073,8 @@ constexpr decltype(auto) constexpr_switch( #undef MAGIC_ENUM_CASE -#else -template -inline constexpr bool has_hash = false; #endif -template -constexpr auto for_each(F&& f, std::index_sequence) { - constexpr bool has_void_return = (std::is_void_v[I]>>> || ...); - constexpr bool all_same_return = (std::is_same_v[0]>>, std::invoke_result_t[I]>>> && ...); - - if constexpr (has_void_return) { - (f(enum_constant[I]>{}), ...); - } else if constexpr (all_same_return) { - return std::array{f(enum_constant[I]>{})...}; - } else { - return std::tuple{f(enum_constant[I]>{})...}; - } -} - -template -constexpr bool all_invocable(std::index_sequence) { - if constexpr (count_v == 0) { - return false; - } else { - return (std::is_invocable_v[I]>> && ...); - } -} - } // namespace magic_enum::detail // Checks is magic_enum supported compiler. @@ -1335,25 +1306,21 @@ template , typename Bi if constexpr (detail::count_v == 0) { static_cast(value); return {}; // Empty enum. - } else { - if constexpr (detail::is_default_predicate() && detail::has_hash) { #if defined(MAGIC_ENUM_ENABLE_HASH) + } else if constexpr (detail::is_default_predicate()) { return detail::constexpr_switch<&detail::names_v, detail::case_call_t::index>( [](std::size_t i) { return optional{detail::values_v[i]}; }, value, detail::default_result_type_lambda>, [&p](string_view lhs, string_view rhs) { return detail::cmp_equal(lhs, rhs, p); }); -#else - static_assert(detail::always_false_v, "magic_enum::enum_cast invalid."); #endif } else { - for (std::size_t i = 0; i < detail::count_v; ++i) { - if (detail::cmp_equal(value, detail::names_v[i], p)) { - return enum_value(i); - } + for (std::size_t i = 0; i < detail::count_v; ++i) { + if (detail::cmp_equal(value, detail::names_v[i], p)) { + return enum_value(i); } - return {}; // Invalid value or out of range. } + return {}; // Invalid value or out of range. } } diff --git a/include/magic_enum_switch.hpp b/include/magic_enum_switch.hpp index 4d6c9ad..1d0aa33 100644 --- a/include/magic_enum_switch.hpp +++ b/include/magic_enum_switch.hpp @@ -93,7 +93,7 @@ constexpr auto result_type() noexcept { template , typename R = typename decltype(result_type())::type> using result_t = std::enable_if_t && !std::is_same_v, R>; -#if !defined(MAGIC_ENUM_ENABLE_HASH) +#if !defined(MAGIC_ENUM_ENABLE_HASH) && !defined(MAGIC_ENUM_ENABLE_HASH_SWITCH) template inline constexpr auto default_result_type_lambda = []() noexcept(std::is_nothrow_default_constructible_v) { return T{}; }; @@ -147,7 +147,7 @@ constexpr decltype(auto) enum_switch(F&& f, E value) { using D = std::decay_t; static_assert(std::is_enum_v, "magic_enum::enum_switch requires enum type."); -#if defined(MAGIC_ENUM_ENABLE_HASH) +#if defined(MAGIC_ENUM_ENABLE_HASH) || defined(MAGIC_ENUM_ENABLE_HASH_SWITCH) return detail::constexpr_switch<&detail::values_v, detail::case_call_t::value>( std::forward(f), value, @@ -170,7 +170,7 @@ constexpr decltype(auto) enum_switch(F&& f, E value, Result&& result) { using D = std::decay_t; static_assert(std::is_enum_v, "magic_enum::enum_switch requires enum type."); -#if defined(MAGIC_ENUM_ENABLE_HASH) +#if defined(MAGIC_ENUM_ENABLE_HASH) || defined(MAGIC_ENUM_ENABLE_HASH_SWITCH) return detail::constexpr_switch<&detail::values_v, detail::case_call_t::value>( std::forward(f), value,