diff --git a/README.md b/README.md index 980a975..a35dddf 100644 --- a/README.md +++ b/README.md @@ -75,7 +75,7 @@ Header-only C++17 library provides nameof macros and functions to simply obtain // Static storage enum variable to string. // This version is much lighter on the compile times and is not restricted to the enum_range limitation. - NAMEOF_CONST_ENUM(Color::GREEN) -> "GREEN" + NAMEOF_ENUM_CONST(Color::GREEN) -> "GREEN" nameof::nameof_enum() -> "GREEN" // Enum flag variable to string. diff --git a/doc/limitations.md b/doc/limitations.md index 5aad519..dc60ac4 100644 --- a/doc/limitations.md +++ b/doc/limitations.md @@ -16,6 +16,8 @@ ## Nameof Enum +* Do not use [nameof](https://github.com/Neargye/nameof) and [magic_enum](https://github.com/Neargye/magic_enum) in the same project to get enum name. + * To check is nameof enum supported compiler use macro `NAMEOF_ENUM_SUPPORTED` or constexpr constant `nameof::is_nameof_enum_supported`. * This library uses a compiler-specific hack (based on `__PRETTY_FUNCTION__` / `__FUNCSIG__`), which works on Clang >= 5, MSVC >= 15.3 and GCC >= 9. diff --git a/doc/reference.md b/doc/reference.md index 9e0507a..f1972f3 100644 --- a/doc/reference.md +++ b/doc/reference.md @@ -5,7 +5,7 @@ * [`NAMEOF_RAW` macro that obtains raw string name of variable, function, macro.](#nameof_raw) * [`nameof_enum` function that obtains simple (unqualified) string name of enum variable.](#nameof_enum) * [`NAMEOF_ENUM` macro that obtains simple (unqualified) string name of enum variable.](#nameof_enum-1) -* [`NAMEOF_CONST_ENUM` macro that obtains simple (unqualified) string name of static storage enum variable.](#nameof_const_enum) +* [`NAMEOF_ENUM_CONST` macro that obtains simple (unqualified) string name of static storage enum variable.](#nameof_enum_const) * [`nameof_enum_flag` function that obtains simple (unqualified) string name of enum variable.](#nameof_enum_flag) * [`NAMEOF_ENUM_FLAG` function that obtains simple (unqualified) string name of enum variable.](#nameof_enum_flag-1) * [`nameof_type` function that obtains string name of type, reference and cv-qualifiers are ignored.](#nameof_type) @@ -134,7 +134,7 @@ NAMEOF_ENUM(color) -> "RED" ``` -## `NAMEOF_CONST_ENUM` +## `NAMEOF_ENUM_CONST` * Macro that obtains simple (unqualified) string name of static storage enum variable. @@ -147,7 +147,7 @@ * Examples ```cpp - NAMEOF_CONST_ENUM(Color::GREEN) -> "GREEN" + NAMEOF_ENUM_CONST(Color::GREEN) -> "GREEN" ``` ## `nameof_enum_flag` @@ -156,7 +156,7 @@ * Returns `std::string`. -* If argument does not have name or [out of range](limitations.md#nameof-enum), returns empty `std::string_view`. +* If argument does not have name or [out of range](limitations.md#nameof-enum), returns empty `std::string`. * Examples @@ -177,7 +177,7 @@ * Returns `std::string`. -* If argument does not have name or [out of range](limitations.md#nameof-enum), returns empty `std::string_view`. +* If argument does not have name or [out of range](limitations.md#nameof-enum), returns empty `std::string`. * Examples diff --git a/example/example.cpp b/example/example.cpp index e005967..850eebc 100644 --- a/example/example.cpp +++ b/example/example.cpp @@ -128,9 +128,9 @@ int main() { std::cout << nameof::nameof_enum() << std::endl; // 'GREEN' // Nameof enum flags. - AnimalFlags flag = static_cast(AnimalFlags::CanFly | AnimalFlags::EatsFish); - std::cout << nameof::nameof_enum_flags(flag) << std::endl; // 'CanFly|EatsFish' - std::cout << NAMEOF_ENUM_FLAGS(flag) << std::endl; // 'CanFly|EatsFish' + auto flag = static_cast(AnimalFlags::CanFly | AnimalFlags::EatsFish); + std::cout << nameof::nameof_enum_flag(flag) << std::endl; // 'CanFly|EatsFish' + std::cout << NAMEOF_ENUM_FLAG(flag) << std::endl; // 'CanFly|EatsFish' #endif // Nameof. diff --git a/include/nameof.hpp b/include/nameof.hpp index f192e45..0a8c8a9 100644 --- a/include/nameof.hpp +++ b/include/nameof.hpp @@ -720,11 +720,11 @@ template // Obtains simple (unqualified) string name of enum-flags variable. template -[[nodiscard]] auto nameof_enum_flags(E value) -> detail::enable_if_enum_t { +[[nodiscard]] auto nameof_enum_flag(E value) -> detail::enable_if_enum_t { using D = std::decay_t; using U = std::underlying_type_t; - static_assert(detail::nameof_enum_supported::value, "nameof::nameof_enum_flags unsupported compiler (https://github.com/Neargye/nameof#compiler-compatibility)."); - static_assert(detail::count_v > 0, "nameof::nameof_enum_flags requires enum flag implementation."); + static_assert(detail::nameof_enum_supported::value, "nameof::nameof_enum_flag unsupported compiler (https://github.com/Neargye/nameof#compiler-compatibility)."); + static_assert(detail::count_v > 0, "nameof::nameof_enum_flag requires enum-flags implementation."); constexpr auto size = detail::is_sparse_v ? detail::count_v : detail::range_size_v; std::string name; @@ -818,20 +818,20 @@ template // Obtains simple (unqualified) string 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_CONST_ENUM(...) ::nameof::nameof_enum<__VA_ARGS__>() +#define NAMEOF_ENUM_CONST(...) ::nameof::nameof_enum<__VA_ARGS__>() -// Obtains simple (unqualified) string name of enum flag variable. -#define NAMEOF_ENUM_FLAGS(...) ::nameof::nameof_enum_flags<::std::decay_t>(__VA_ARGS__) +// Obtains simple (unqualified) string name of enum-flags variable. +#define NAMEOF_ENUM_FLAG(...) ::nameof::nameof_enum_flag<::std::decay_t>(__VA_ARGS__) // Obtains string name of type, reference and cv-qualifiers are ignored. #define NAMEOF_TYPE(...) ::nameof::nameof_type<__VA_ARGS__>() -// Obtains string name of full type, with reference and cv-qualifiers. -#define NAMEOF_FULL_TYPE(...) ::nameof::nameof_full_type<__VA_ARGS__>() - // Obtains string name type of expression, reference and cv-qualifiers are ignored. #define NAMEOF_TYPE_EXPR(...) ::nameof::nameof_type() +// Obtains string name of full type, with reference and cv-qualifiers. +#define NAMEOF_FULL_TYPE(...) ::nameof::nameof_full_type<__VA_ARGS__>() + // Obtains string name full type of expression, with reference and cv-qualifiers. #define NAMEOF_FULL_TYPE_EXPR(...) ::nameof::nameof_full_type() diff --git a/test/test.cpp b/test/test.cpp index dc0f472..90a33a7 100644 --- a/test/test.cpp +++ b/test/test.cpp @@ -277,34 +277,34 @@ TEST_CASE("NAMEOF_ENUM") { REQUIRE(NAMEOF_ENUM(static_cast(0)).empty()); } -TEST_CASE("NAMEOF_CONST_ENUM") { +TEST_CASE("NAMEOF_ENUM_CONST") { constexpr Color cr = Color::RED; - constexpr auto cr_name = NAMEOF_CONST_ENUM(cr); + constexpr auto cr_name = NAMEOF_ENUM_CONST(cr); constexpr Color cm[3] = {Color::RED, Color::GREEN, Color::BLUE}; REQUIRE(cr_name == "RED"); - REQUIRE(NAMEOF_CONST_ENUM(Color::BLUE) == "BLUE"); - REQUIRE(NAMEOF_CONST_ENUM(cm[1]) == "GREEN"); + REQUIRE(NAMEOF_ENUM_CONST(Color::BLUE) == "BLUE"); + REQUIRE(NAMEOF_ENUM_CONST(cm[1]) == "GREEN"); constexpr Numbers no = Numbers::one; - constexpr auto no_name = NAMEOF_CONST_ENUM(no); + constexpr auto no_name = NAMEOF_ENUM_CONST(no); REQUIRE(no_name == "one"); - REQUIRE(NAMEOF_CONST_ENUM(Numbers::two) == "two"); - REQUIRE(NAMEOF_CONST_ENUM(Numbers::three) == "three"); - REQUIRE(NAMEOF_CONST_ENUM(Numbers::many) == "many"); + REQUIRE(NAMEOF_ENUM_CONST(Numbers::two) == "two"); + REQUIRE(NAMEOF_ENUM_CONST(Numbers::three) == "three"); + REQUIRE(NAMEOF_ENUM_CONST(Numbers::many) == "many"); constexpr Directions dr = Directions::Right; - constexpr auto dr_name = NAMEOF_CONST_ENUM(dr); - REQUIRE(NAMEOF_CONST_ENUM(Directions::Up) == "Up"); - REQUIRE(NAMEOF_CONST_ENUM(Directions::Down) == "Down"); + constexpr auto dr_name = NAMEOF_ENUM_CONST(dr); + REQUIRE(NAMEOF_ENUM_CONST(Directions::Up) == "Up"); + REQUIRE(NAMEOF_ENUM_CONST(Directions::Down) == "Down"); REQUIRE(dr_name == "Right"); - REQUIRE(NAMEOF_CONST_ENUM(Directions::Left) == "Left"); + REQUIRE(NAMEOF_ENUM_CONST(Directions::Left) == "Left"); constexpr number nt = number::three; - constexpr auto nt_name = NAMEOF_CONST_ENUM(nt); - REQUIRE(NAMEOF_CONST_ENUM(number::one) == "one"); - REQUIRE(NAMEOF_CONST_ENUM(number::two) == "two"); + constexpr auto nt_name = NAMEOF_ENUM_CONST(nt); + REQUIRE(NAMEOF_ENUM_CONST(number::one) == "one"); + REQUIRE(NAMEOF_ENUM_CONST(number::two) == "two"); REQUIRE(nt_name == "three"); - REQUIRE(NAMEOF_CONST_ENUM(number::four) == "four"); + REQUIRE(NAMEOF_ENUM_CONST(number::four) == "four"); } TEST_CASE("nameof_enum") { @@ -373,64 +373,64 @@ TEST_CASE("nameof_enum") { } } -TEST_CASE("nameof_enum_flags") { +TEST_CASE("nameof_enum_flag") { constexpr AnimalFlags af = AnimalFlags::HasClaws; - auto af_name = nameof::nameof_enum_flags(af); + auto af_name = nameof::nameof_enum_flag(af); AnimalFlags afm[3] = {AnimalFlags::HasClaws, AnimalFlags::CanFly, AnimalFlags::EatsFish}; REQUIRE(af_name == "HasClaws"); - REQUIRE(nameof::nameof_enum_flags(AnimalFlags::EatsFish) == "EatsFish"); - REQUIRE(nameof::nameof_enum_flags(afm[1]) == "CanFly"); - REQUIRE(nameof::nameof_enum_flags(static_cast(0)).empty()); - REQUIRE(nameof::nameof_enum_flags(static_cast(1 | 2)) == "HasClaws|CanFly"); - REQUIRE(nameof::nameof_enum_flags(static_cast(1 | 2 | 4)) == "HasClaws|CanFly|EatsFish"); - REQUIRE(nameof::nameof_enum_flags(static_cast(1 | 0 | 8)) == "HasClaws|Endangered"); - REQUIRE(nameof::nameof_enum_flags(static_cast(0)).empty()); + REQUIRE(nameof::nameof_enum_flag(AnimalFlags::EatsFish) == "EatsFish"); + REQUIRE(nameof::nameof_enum_flag(afm[1]) == "CanFly"); + REQUIRE(nameof::nameof_enum_flag(static_cast(0)).empty()); + REQUIRE(nameof::nameof_enum_flag(static_cast(1 | 2)) == "HasClaws|CanFly"); + REQUIRE(nameof::nameof_enum_flag(static_cast(1 | 2 | 4)) == "HasClaws|CanFly|EatsFish"); + REQUIRE(nameof::nameof_enum_flag(static_cast(1 | 0 | 8)) == "HasClaws|Endangered"); + REQUIRE(nameof::nameof_enum_flag(static_cast(0)).empty()); constexpr BigFlags bf = BigFlags::A; - auto bf_name = nameof::nameof_enum_flags(bf); + auto bf_name = nameof::nameof_enum_flag(bf); BigFlags bfm[3] = {BigFlags::A, BigFlags::B, BigFlags::C}; REQUIRE(bf_name == "A"); - REQUIRE(nameof::nameof_enum_flags(BigFlags::C) == "C"); - REQUIRE(nameof::nameof_enum_flags(bfm[1]) == "B"); - REQUIRE(nameof::nameof_enum_flags(static_cast(0)).empty()); - REQUIRE(nameof::nameof_enum_flags(static_cast(1 | 2)).empty()); - REQUIRE(nameof::nameof_enum_flags(static_cast(1 | (static_cast(0x1) << 20))) == "A|B"); - REQUIRE(nameof::nameof_enum_flags(static_cast(1 | (static_cast(0x1) << 20) | (static_cast(0x1) << 63))) == "A|B|D"); - REQUIRE(nameof::nameof_enum_flags(static_cast(1 | 0 | (static_cast(0x1) << 40))) == "A|C"); - REQUIRE(nameof::nameof_enum_flags(static_cast(1 | 0 | (static_cast(0x1) << 40))) == "A|C"); - REQUIRE(nameof::nameof_enum_flags(static_cast((static_cast(0x1) << 63) | 1)) == "A|D"); - REQUIRE(nameof::nameof_enum_flags(static_cast(2)).empty()); - REQUIRE(nameof::nameof_enum_flags(static_cast((static_cast(0x1) << 63) | 2)).empty()); + REQUIRE(nameof::nameof_enum_flag(BigFlags::C) == "C"); + REQUIRE(nameof::nameof_enum_flag(bfm[1]) == "B"); + REQUIRE(nameof::nameof_enum_flag(static_cast(0)).empty()); + REQUIRE(nameof::nameof_enum_flag(static_cast(1 | 2)).empty()); + REQUIRE(nameof::nameof_enum_flag(static_cast(1 | (static_cast(0x1) << 20))) == "A|B"); + REQUIRE(nameof::nameof_enum_flag(static_cast(1 | (static_cast(0x1) << 20) | (static_cast(0x1) << 63))) == "A|B|D"); + REQUIRE(nameof::nameof_enum_flag(static_cast(1 | 0 | (static_cast(0x1) << 40))) == "A|C"); + REQUIRE(nameof::nameof_enum_flag(static_cast(1 | 0 | (static_cast(0x1) << 40))) == "A|C"); + REQUIRE(nameof::nameof_enum_flag(static_cast((static_cast(0x1) << 63) | 1)) == "A|D"); + REQUIRE(nameof::nameof_enum_flag(static_cast(2)).empty()); + REQUIRE(nameof::nameof_enum_flag(static_cast((static_cast(0x1) << 63) | 2)).empty()); } -TEST_CASE("NAMEOF_ENUM_FLAGS") { +TEST_CASE("NAMEOF_ENUM_FLAG") { constexpr AnimalFlags af = AnimalFlags::HasClaws; - auto af_name = NAMEOF_ENUM_FLAGS(af); + auto af_name = NAMEOF_ENUM_FLAG(af); AnimalFlags afm[3] = {AnimalFlags::HasClaws, AnimalFlags::CanFly, AnimalFlags::EatsFish}; REQUIRE(af_name == "HasClaws"); - REQUIRE(NAMEOF_ENUM_FLAGS(afm[1]) == "CanFly"); - REQUIRE(NAMEOF_ENUM_FLAGS(AnimalFlags::EatsFish) == "EatsFish"); - REQUIRE(NAMEOF_ENUM_FLAGS(AnimalFlags::Endangered) == "Endangered"); - REQUIRE(NAMEOF_ENUM_FLAGS(static_cast(0)).empty()); - REQUIRE(NAMEOF_ENUM_FLAGS(static_cast(1 | 2)) == "HasClaws|CanFly"); - REQUIRE(NAMEOF_ENUM_FLAGS(static_cast(1 | 2 | 4)) == "HasClaws|CanFly|EatsFish"); - REQUIRE(NAMEOF_ENUM_FLAGS(static_cast(1 | 0 | 8)) == "HasClaws|Endangered"); - REQUIRE(NAMEOF_ENUM_FLAGS(static_cast(0)).empty()); + REQUIRE(NAMEOF_ENUM_FLAG(afm[1]) == "CanFly"); + REQUIRE(NAMEOF_ENUM_FLAG(AnimalFlags::EatsFish) == "EatsFish"); + REQUIRE(NAMEOF_ENUM_FLAG(AnimalFlags::Endangered) == "Endangered"); + REQUIRE(NAMEOF_ENUM_FLAG(static_cast(0)).empty()); + REQUIRE(NAMEOF_ENUM_FLAG(static_cast(1 | 2)) == "HasClaws|CanFly"); + REQUIRE(NAMEOF_ENUM_FLAG(static_cast(1 | 2 | 4)) == "HasClaws|CanFly|EatsFish"); + REQUIRE(NAMEOF_ENUM_FLAG(static_cast(1 | 0 | 8)) == "HasClaws|Endangered"); + REQUIRE(NAMEOF_ENUM_FLAG(static_cast(0)).empty()); constexpr BigFlags bf = BigFlags::A; - auto bf_name = NAMEOF_ENUM_FLAGS(bf); + auto bf_name = NAMEOF_ENUM_FLAG(bf); BigFlags bfm[3] = {BigFlags::A, BigFlags::B, BigFlags::C}; REQUIRE(bf_name == "A"); - REQUIRE(NAMEOF_ENUM_FLAGS(bfm[1]) == "B"); - REQUIRE(NAMEOF_ENUM_FLAGS(BigFlags::C) == "C"); - REQUIRE(NAMEOF_ENUM_FLAGS(BigFlags::D) == "D"); - REQUIRE(NAMEOF_ENUM_FLAGS(static_cast(0)).empty()); - REQUIRE(NAMEOF_ENUM_FLAGS(static_cast(1 | 2)).empty()); - REQUIRE(NAMEOF_ENUM_FLAGS(static_cast(1 | (static_cast(0x1) << 20))) == "A|B"); - REQUIRE(NAMEOF_ENUM_FLAGS(static_cast(1 | (static_cast(0x1) << 20) | (static_cast(0x1) << 63))) == "A|B|D"); - REQUIRE(NAMEOF_ENUM_FLAGS(static_cast((static_cast(0x1) << 63) | 1)) == "A|D"); - REQUIRE(NAMEOF_ENUM_FLAGS(static_cast(2)).empty()); - REQUIRE(NAMEOF_ENUM_FLAGS(static_cast((static_cast(0x1) << 63) | 2)).empty()); + REQUIRE(NAMEOF_ENUM_FLAG(bfm[1]) == "B"); + REQUIRE(NAMEOF_ENUM_FLAG(BigFlags::C) == "C"); + REQUIRE(NAMEOF_ENUM_FLAG(BigFlags::D) == "D"); + REQUIRE(NAMEOF_ENUM_FLAG(static_cast(0)).empty()); + REQUIRE(NAMEOF_ENUM_FLAG(static_cast(1 | 2)).empty()); + REQUIRE(NAMEOF_ENUM_FLAG(static_cast(1 | (static_cast(0x1) << 20))) == "A|B"); + REQUIRE(NAMEOF_ENUM_FLAG(static_cast(1 | (static_cast(0x1) << 20) | (static_cast(0x1) << 63))) == "A|B|D"); + REQUIRE(NAMEOF_ENUM_FLAG(static_cast((static_cast(0x1) << 63) | 1)) == "A|D"); + REQUIRE(NAMEOF_ENUM_FLAG(static_cast(2)).empty()); + REQUIRE(NAMEOF_ENUM_FLAG(static_cast((static_cast(0x1) << 63) | 2)).empty()); } #endif