From 59411bf519444e8f7460d868cdf4bb254718d544 Mon Sep 17 00:00:00 2001 From: neargye Date: Tue, 26 Jul 2022 18:17:36 +0400 Subject: [PATCH] add nameof_enum_or --- include/nameof.hpp | 23 ++++++++++++++++++----- test/test.cpp | 28 ++++++++++++++++++++++++++++ 2 files changed, 46 insertions(+), 5 deletions(-) diff --git a/include/nameof.hpp b/include/nameof.hpp index a7310a8..7c1dd4a 100644 --- a/include/nameof.hpp +++ b/include/nameof.hpp @@ -979,7 +979,7 @@ inline constexpr bool is_nameof_member_supported = detail::nameof_member_support // Checks is nameof_enum supported compiler. inline constexpr bool is_nameof_enum_supported = detail::nameof_enum_supported::value; -// Obtains simple (unqualified) name of enum variable. +// Obtains name of enum variable. template [[nodiscard]] constexpr auto nameof_enum(E value) noexcept -> detail::enable_if_enum_t { using D = std::decay_t; @@ -998,11 +998,22 @@ template } } - assert(valid && "enum variable does not have a name."); return {}; // Value out of range. } -// Obtains simple (unqualified) name of enum-flags variable. +// Obtains name of enum variable or default value if enum variable out of range. +template +[[nodiscard]] auto nameof_enum_or(E value, string_view default_value) noexcept -> detail::enable_if_enum_t { + using D = std::decay_t; + + if (auto v = nameof_enum(value); !v.empty()) { + return string{v.data(), v.size()}; + } + + return string{default_value.data(), default_value.size()}; +} + +// Obtains name of enum-flags variable. template [[nodiscard]] auto nameof_enum_flag(E value) -> detail::enable_if_enum_t { using D = std::decay_t; @@ -1032,11 +1043,10 @@ template return name; } - assert(valid && "enum-flags variable does not have a name."); return {}; // Invalid value or out of range. } -// Obtains simple (unqualified) name of static storage enum variable. +// Obtains name of static storage enum variable. // This version is much lighter on the compile times and is not restricted to the enum_range limitation. template [[nodiscard]] constexpr auto nameof_enum() noexcept -> detail::enable_if_enum_t { @@ -1123,6 +1133,9 @@ template // Obtains name of enum variable. #define NAMEOF_ENUM(...) ::nameof::nameof_enum<::std::decay_t>(__VA_ARGS__) +// Obtains name of enum variable or default value if enum variable out of range. +#define NAMEOF_ENUM_OR(...) ::nameof::nameof_enum_or(__VA_ARGS__) + // Obtains name of static storage enum variable. // This version is much lighter on the compile times and is not restricted to the enum_range limitation. #define NAMEOF_ENUM_CONST(...) ::nameof::nameof_enum<__VA_ARGS__>() diff --git a/test/test.cpp b/test/test.cpp index a7d2d0a..22f7803 100644 --- a/test/test.cpp +++ b/test/test.cpp @@ -107,6 +107,12 @@ struct nameof::customize::enum_range { static_assert(max > min, "nameof::enum_range requires max > min."); }; +enum class OutOfRange { + too_low = NAMEOF_ENUM_RANGE_MIN - 1, + required_to_work = 0, + too_high = NAMEOF_ENUM_RANGE_MAX + 1 +}; + struct TestRtti{ struct Base { virtual ~Base() = default; }; struct Derived : Base {}; @@ -442,6 +448,28 @@ TEST_CASE("NAMEOF_ENUM_FLAG") { NAMEOF_DEBUG_REQUIRE(NAMEOF_ENUM_FLAG(static_cast((static_cast(0x1) << 63) | 2)).empty()); } +TEST_CASE("nameof_enum_or") { + OutOfRange low = OutOfRange::too_low; + OutOfRange high = OutOfRange::too_high; + auto low_name = nameof::nameof_enum_or(low, "-121"); + auto high_name = nameof::nameof_enum_or(high, "121"); + constexpr OutOfRange oor[] = {OutOfRange::too_high, OutOfRange::too_low}; + REQUIRE(low_name == "-121"); + REQUIRE(high_name == "121"); + REQUIRE(nameof::nameof_enum_or(oor[0], "121") == "121"); +} + +TEST_CASE("NAMEOF_ENUM_OR") { + OutOfRange low = OutOfRange::too_low; + OutOfRange high = OutOfRange::too_high; + auto low_name = NAMEOF_ENUM_OR(low, "-121"); + auto high_name = NAMEOF_ENUM_OR(high, "121"); + constexpr OutOfRange oor[] = {OutOfRange::too_high, OutOfRange::too_low}; + REQUIRE(low_name == "-121"); + REQUIRE(high_name == "121"); + REQUIRE(NAMEOF_ENUM_OR(oor[0], "121") == "121"); +} + #endif #if defined(NAMEOF_TYPE_SUPPORTED)