diff --git a/include/nameof.hpp b/include/nameof.hpp index 3a5fa08..4fd1c26 100644 --- a/include/nameof.hpp +++ b/include/nameof.hpp @@ -119,30 +119,13 @@ template } template -[[nodiscard]] constexpr decltype(auto) enum_strings_impl(std::integer_sequence) noexcept { +[[nodiscard]] constexpr decltype(auto) enum_names_impl(std::integer_sequence) noexcept { static_assert(std::is_enum_v, "nameof::detail::enum_strings_impl requires enum type."); constexpr std::array names{{enum_name_impl(I + O)>()...}}; return names; } -template > -[[nodiscard]] constexpr std::string_view nameof_enum_impl(int value) noexcept { - static_assert(std::is_enum_v, "nameof::detail::nameof_enum_impl requires enum type."); - static_assert(enum_range::max > enum_range::min, "nameof::enum_range requires max > min."); - constexpr int max = enum_range::max < (std::numeric_limits::max)() ? enum_range::max : (std::numeric_limits::max)(); - constexpr int min = enum_range::min > (std::numeric_limits::min)() ? enum_range::min : (std::numeric_limits::min)(); - constexpr auto range = std::make_integer_sequence{}; - constexpr auto names = enum_strings_impl(range); - const int i = value - min; - - if (i >= 0 && static_cast(i) < names.size()) { - return names[i]; - } else { - return {}; // Value out of range. - } -} - template struct check final { using type = void; @@ -153,6 +136,7 @@ using check_t = typename check::type; template [[nodiscard]] constexpr std::string_view nameof_impl(std::string_view name, bool with_template_suffix) noexcept { + static_assert(std::is_void_v, "nameof::detail::nameof_impl requires void type."); if (name.length() >= 1 && (name.front() == '"' || name.front() == '\'')) { return {}; // Narrow multibyte string literal. } else if (name.length() >= 2 && name[0] == 'R' && (name[1] == '"' || name[1] == '\'')) { @@ -231,17 +215,28 @@ template template [[nodiscard]] constexpr std::string_view nameof_raw_impl(std::string_view name) noexcept { + static_assert(std::is_void_v, "nameof::detail::nameof_raw_impl requires void type."); return name; } } // namespace nameof::detail // Obtains simple (unqualified) string enum name of enum variable. -template , typename = std::enable_if_t>> +template , typename U = std::underlying_type_t, typename = std::enable_if_t>> [[nodiscard]] constexpr std::string_view nameof_enum(E value) noexcept { static_assert(std::is_enum_v, "nameof::nameof_enum requires enum type."); + static_assert(enum_range::max > enum_range::min, "nameof::enum_range requires max > min."); + constexpr int max = enum_range::max < (std::numeric_limits::max)() ? enum_range::max : (std::numeric_limits::max)(); + constexpr int min = enum_range::min > (std::numeric_limits::min)() ? enum_range::min : (std::numeric_limits::min)(); + constexpr auto range = std::make_integer_sequence{}; + constexpr auto names = detail::enum_names_impl(range); + const int i = static_cast(value) - min; - return detail::nameof_enum_impl(static_cast(value)); + if (i >= 0 && static_cast(i) < names.size()) { + return names[i]; + } else { + return {}; // Value out of range. + } } // Obtains string name of type.