diff --git a/include/nameof.hpp b/include/nameof.hpp index 69e3795..29b48a4 100644 --- a/include/nameof.hpp +++ b/include/nameof.hpp @@ -287,7 +287,7 @@ class [[nodiscard]] cstring<0> { constexpr explicit cstring(string_view) noexcept {} - constexpr cstring() = delete; + constexpr cstring() = default; constexpr cstring(const cstring&) = default; @@ -542,9 +542,8 @@ inline constexpr bool is_enum_v = std::is_enum_v && std::is_same_v constexpr auto n() noexcept { static_assert(is_enum_v, "nameof::detail::n requires enum type."); - [[maybe_unused]] constexpr auto custom_name = customize::enum_name(V); - if constexpr (custom_name.empty() && nameof_enum_supported::value) { + if constexpr (nameof_enum_supported::value) { #if defined(__clang__) || defined(__GNUC__) constexpr auto name = pretty_name({__PRETTY_FUNCTION__, sizeof(__PRETTY_FUNCTION__) - 2}); #elif defined(_MSC_VER) @@ -553,26 +552,43 @@ constexpr auto n() noexcept { constexpr auto name = string_view{}; #endif return cstring{name}; + } else { + return cstring<0>{}; + } +} + +template +constexpr auto enum_name() noexcept { + static_assert(is_enum_v, "nameof::detail::n requires enum type."); + [[maybe_unused]] constexpr auto custom_name = customize::enum_name(V); + + if constexpr (custom_name.empty()) { + return n(); } else { return cstring{custom_name}; } } template -inline constexpr auto enum_name_v = n(); - -template -constexpr bool valid() noexcept { - static_assert(is_enum_v, "nameof::detail::is_valid requires enum type."); - - return n(V)>().size() != 0; -} - -template -struct is_valid : std::false_type {}; +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, "nameof::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_name = customize::enum_name(v); + if constexpr (custom_name.empty()) { + return n().size() != 0; + } else { + return name.size() != 0; + } +#else + return enum_name(V)>().size() != 0; +#endif +} template > constexpr U ualue(std::size_t i) noexcept { @@ -653,7 +669,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, "nameof::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) { @@ -974,10 +990,9 @@ constexpr auto get_member_name() noexcept { template inline constexpr auto member_name_v = get_member_name(); - #else template -inline constexpr auto member_name_v = cstring<0>{string_view{}}; +inline constexpr auto member_name_v = cstring<0>{}; #endif } // namespace nameof::detail