diff --git a/include/magic_enum.hpp b/include/magic_enum.hpp index 1555f3e..56b1331 100644 --- a/include/magic_enum.hpp +++ b/include/magic_enum.hpp @@ -383,13 +383,7 @@ template constexpr auto n() noexcept { static_assert(is_enum_v, "magic_enum::detail::n requires enum type."); - [[maybe_unused]] constexpr auto custom = customize::enum_type_name(); - static_assert(std::is_same_v, customize::customize_t>, "magic_enum::customize requires customize_t type."); - if constexpr (custom.index() == 0) { - constexpr auto name = std::get(custom); - static_assert(!name.empty(), "magic_enum::customize requires not empty string."); - return static_string{name}; - } else if constexpr (custom.index() == 1 && supported::value) { + if constexpr (supported::value) { #if defined(__clang__) || defined(__GNUC__) constexpr auto name = pretty_name({__PRETTY_FUNCTION__, sizeof(__PRETTY_FUNCTION__) - 2}); #elif defined(_MSC_VER) @@ -404,19 +398,28 @@ constexpr auto n() noexcept { } template -inline constexpr auto type_name_v = n(); +constexpr auto type_name() noexcept { + static_assert(is_enum_v, "magic_enum::detail::n requires enum type."); + + [[maybe_unused]] constexpr auto custom = customize::enum_type_name(); + static_assert(std::is_same_v, customize::customize_t>, "magic_enum::customize requires customize_t type."); + if constexpr (std::is_same_v, customize::customize_t> && custom.index() == 0) { + constexpr auto name = std::get(custom); + static_assert(!name.empty(), "magic_enum::customize requires not empty string."); + return static_string{name}; + } else { + return n(); + } +} + +template +inline constexpr auto type_name_v = type_name(); template constexpr auto n() noexcept { static_assert(is_enum_v, "magic_enum::detail::n requires enum type."); - [[maybe_unused]] constexpr auto custom = customize::enum_name(V); - static_assert(std::is_same_v, customize::customize_t>, "magic_enum::customize requires customize_t type."); - if constexpr (custom.index() == 0) { - constexpr auto name = std::get(custom); - static_assert(!name.empty(), "magic_enum::customize requires not empty string."); - return static_string{name}; - } else if constexpr (custom.index() == 1 && supported::value) { + if constexpr (supported::value) { #if defined(__clang__) || defined(__GNUC__) constexpr auto name = pretty_name({__PRETTY_FUNCTION__, sizeof(__PRETTY_FUNCTION__) - 2}); #elif defined(_MSC_VER) @@ -431,20 +434,43 @@ constexpr auto n() noexcept { } template -inline constexpr auto enum_name_v = n(); +constexpr auto enum_name() noexcept { + static_assert(is_enum_v, "magic_enum::detail::n requires enum type."); -template -constexpr bool valid() noexcept { - static_assert(is_enum_v, "magic_enum::detail::is_valid requires enum type."); - - return n(V)>().size() != 0; + [[maybe_unused]] constexpr auto custom = customize::enum_name(V); + static_assert(std::is_same_v, customize::customize_t>, "magic_enum::customize requires customize_t type."); + if constexpr (std::is_same_v, customize::customize_t> && custom.index() == 0) { + constexpr auto name = std::get(custom); + static_assert(!name.empty(), "magic_enum::customize requires not empty string."); + return static_string{name}; + } else { + return n(); + } } -template -struct is_valid : std::false_type {}; +template +inline constexpr auto enum_name_v = enum_name(); template -struct is_valid(V)>())>> : std::bool_constant(V)>()> {}; +constexpr bool is_valid() noexcept { + static_assert(is_enum_v, "magic_enum::detail::is_valid requires enum type."); + +#if defined(__clang__) && __clang_major__ >= 16 + // https://reviews.llvm.org/D130058, https://reviews.llvm.org/D131307 + constexpr E v = __builtin_bit_cast(E, V); + [[maybe_unused]] constexpr auto custom = customize::enum_name(v); + static_assert(std::is_same_v, customize::customize_t>, "magic_enum::customize requires customize_t type."); + if constexpr (std::is_same_v, customize::customize_t> && custom.index() == 0) { + static_assert(!name.empty(), "magic_enum::customize requires not empty string."); + constexpr auto name = std::get(custom); + return name.size() != 0; + } else { + return n().size() != 0; + } +#else + return enum_name(V)>().size() != 0; +#endif +} template > constexpr U ualue(std::size_t i) noexcept { @@ -525,7 +551,7 @@ constexpr std::size_t values_count(const bool (&valid)[N]) noexcept { template constexpr auto values(std::index_sequence) noexcept { static_assert(is_enum_v, "magic_enum::detail::values requires enum type."); - constexpr bool valid[sizeof...(I)] = {is_valid(I)>::value...}; + constexpr bool valid[sizeof...(I)] = {is_valid(I)>()...}; constexpr std::size_t count = values_count(valid); if constexpr (count > 0) {