fix nameof enum

This commit is contained in:
Neargye 2018-09-01 22:08:09 +05:00
parent 2a118da028
commit bfacde30f2
2 changed files with 32 additions and 21 deletions

View file

@ -42,10 +42,10 @@
#endif #endif
#if (defined(__clang__) || defined(_MSC_VER)) || (defined(__GNUC__) && __GNUC__ >= 5) #if (defined(__clang__) || defined(_MSC_VER)) || (defined(__GNUC__) && __GNUC__ >= 5)
# define NAMEOF_TYPE_HAS_CONSTEXPR 1 # define NAMEOF_HAS_CONSTEXPR 1
# define NAMEOF_TYPE_CONSTEXPR constexpr # define NAMEOF_CONSTEXPR constexpr
#else #else
# define NAMEOF_TYPE_CONSTEXPR inline # define NAMEOF_CONSTEXPR inline
#endif #endif
namespace nameof { namespace nameof {
@ -347,7 +347,7 @@ constexpr cstring NameofTypePretty(const char* str, std::size_t size, std::size_
#endif #endif
template <typename T> template <typename T>
constexpr int NameofEnumImpl1() { NAMEOF_CONSTEXPR int NameofEnumImpl1() {
#if defined(__clang__) #if defined(__clang__)
return sizeof(__PRETTY_FUNCTION__) - sizeof("int nameof::detail::NameofEnumImpl1() [T = ") - sizeof("]") + 1; return sizeof(__PRETTY_FUNCTION__) - sizeof("int nameof::detail::NameofEnumImpl1() [T = ") - sizeof("]") + 1;
#elif defined(__GNUC__) #elif defined(__GNUC__)
@ -360,7 +360,7 @@ constexpr int NameofEnumImpl1() {
} }
template <typename T, T V> template <typename T, T V>
constexpr nameof::cstring NameofEnumImpl2() { NAMEOF_CONSTEXPR nameof::cstring NameofEnumImpl2() {
#if defined(__clang__) #if defined(__clang__)
return {__PRETTY_FUNCTION__, return {__PRETTY_FUNCTION__,
sizeof(__PRETTY_FUNCTION__) - 1, sizeof(__PRETTY_FUNCTION__) - 1,
@ -383,20 +383,27 @@ constexpr nameof::cstring NameofEnumImpl2() {
template <typename T, int I = 0> template <typename T, int I = 0>
struct NameofEnumImpl { struct NameofEnumImpl {
constexpr nameof::cstring operator()(T value) const noexcept { NAMEOF_CONSTEXPR nameof::cstring operator()(T value) const {
return (static_cast<int>(value) - I == 0) return (static_cast<int>(value) - I == 0)
? NameofEnumImpl2<T, T(0 + I)>() ? NameofEnumImpl2<T, T(I)>()
: NameofEnumImpl<T, I + 1>{}(value); : (static_cast<int>(value) >= 0)
? NameofEnumImpl<T, I + 1>{}(value)
: NameofEnumImpl<T, I - 1>{}(value);
} }
}; };
template <typename T> template <typename T>
struct NameofEnumImpl<T, 128> { struct NameofEnumImpl<T, 128> {
constexpr nameof::cstring operator()(T) const noexcept { return {}; } NAMEOF_CONSTEXPR nameof::cstring operator()(T) const { return {}; }
}; };
template <typename T> template <typename T>
NAMEOF_TYPE_CONSTEXPR cstring NameofType() { struct NameofEnumImpl<T, -128> {
NAMEOF_CONSTEXPR nameof::cstring operator()(T) const { return {}; }
};
template <typename T>
NAMEOF_CONSTEXPR cstring NameofType() {
#if defined(__clang__) #if defined(__clang__)
return NameofTypePretty( return NameofTypePretty(
__PRETTY_FUNCTION__, __PRETTY_FUNCTION__,
@ -407,7 +414,7 @@ NAMEOF_TYPE_CONSTEXPR cstring NameofType() {
return NameofTypePretty( return NameofTypePretty(
__PRETTY_FUNCTION__, __PRETTY_FUNCTION__,
sizeof(__PRETTY_FUNCTION__) - 1, sizeof(__PRETTY_FUNCTION__) - 1,
# if defined(NAMEOF_TYPE_HAS_CONSTEXPR) # if defined(NAMEOF_HAS_CONSTEXPR)
sizeof("constexpr nameof::cstring nameof::detail::NameofType() [with T = nameof::detail::nstd::identity<") - 1, sizeof("constexpr nameof::cstring nameof::detail::NameofType() [with T = nameof::detail::nstd::identity<") - 1,
# else # else
sizeof("nameof::cstring nameof::detail::NameofType() [with T = nameof::detail::nstd::identity<") - 1, sizeof("nameof::cstring nameof::detail::NameofType() [with T = nameof::detail::nstd::identity<") - 1,
@ -434,7 +441,7 @@ constexpr cstring Nameof(const char* name, std::size_t size, bool with_suffix =
template <typename T, template <typename T,
typename = typename std::enable_if<!std::is_reference<T>::value && std::is_enum<T>::value>::type> typename = typename std::enable_if<!std::is_reference<T>::value && std::is_enum<T>::value>::type>
constexpr cstring NameofEnum(T value) { NAMEOF_CONSTEXPR cstring NameofEnum(T value) {
#if defined(__clang__) || defined(_MSC_VER) #if defined(__clang__) || defined(_MSC_VER)
return detail::NameofPretty(detail::NameofEnumImpl<T>{}(value), false); return detail::NameofPretty(detail::NameofEnumImpl<T>{}(value), false);
#elif defined(__GNUC__) #elif defined(__GNUC__)
@ -445,8 +452,8 @@ return {};
} }
template <typename T> template <typename T>
NAMEOF_TYPE_CONSTEXPR cstring NameofType() { NAMEOF_CONSTEXPR cstring NameofType() {
return detail::NameofType<detail::nstd::identity<T>>(); return true ? detail::NameofType<detail::nstd::identity<T>>() : detail::NameofType<detail::nstd::identity<T>>();
} }
template <typename T> template <typename T>

View file

@ -68,7 +68,7 @@ struct Long {
LL ll; LL ll;
}; };
enum class Color { RED, GREEN, BLUE }; enum class Color { RED = -1, GREEN, BLUE };
enum Directions { Up, Down, Right, Left}; enum Directions { Up, Down, Right, Left};
@ -151,7 +151,7 @@ TEST_CASE("constexpr") {
static_assert(cx == "RED", ""); static_assert(cx == "RED", "");
REQUIRE(cx == "RED"); REQUIRE(cx == "RED");
#elif defined(__GNUC__) #elif defined(__GNUC__)
REQUIRE(cx == "(const Color)0"); REQUIRE(cx == "(const Color)-1");
#endif #endif
} }
@ -308,13 +308,17 @@ TEST_CASE("NAMEOF_RAW") {
TEST_CASE("NAMEOF_ENUM") { TEST_CASE("NAMEOF_ENUM") {
# if defined(__clang__) || defined(_MSC_VER) # if defined(__clang__) || defined(_MSC_VER)
REQUIRE(NAMEOF_ENUM(Color::RED) == "RED"); REQUIRE(NAMEOF_ENUM(Color::RED) == "RED");
REQUIRE(NAMEOF_ENUM(color) == "RED"); REQUIRE(NAMEOF_ENUM(::color) == "RED");
auto color_ = Color::BLUE;
REQUIRE(NAMEOF_ENUM(Color::BLUE) == "BLUE");
REQUIRE(NAMEOF_ENUM(color_) == "BLUE");
REQUIRE(NAMEOF_ENUM(Directions::Right) == "Right"); REQUIRE(NAMEOF_ENUM(Directions::Right) == "Right");
REQUIRE(NAMEOF_ENUM(directions) == "Right"); REQUIRE(NAMEOF_ENUM(directions) == "Right");
# elif defined(__GNUC__) # elif defined(__GNUC__)
REQUIRE(NAMEOF_ENUM(Color::RED) == "(Color)0"); REQUIRE(NAMEOF_ENUM(Color::RED) == "(Color)-1");
REQUIRE(NAMEOF_ENUM(color) == "(const Color)0"); REQUIRE(NAMEOF_ENUM(color) == "(const Color)-1");
REQUIRE(NAMEOF_ENUM(Directions::Right) == "(Directions)2"); REQUIRE(NAMEOF_ENUM(Directions::Right) == "(Directions)2");
REQUIRE(NAMEOF_ENUM(directions) == "(const Directions)2"); REQUIRE(NAMEOF_ENUM(directions) == "(const Directions)2");
@ -430,7 +434,7 @@ TEST_CASE("Spaces and Tabs ignored") {
#if defined(__clang__) || defined(_MSC_VER) #if defined(__clang__) || defined(_MSC_VER)
REQUIRE(NAMEOF_ENUM( color ) == "RED"); REQUIRE(NAMEOF_ENUM( color ) == "RED");
#elif defined(__GNUC__) #elif defined(__GNUC__)
REQUIRE(NAMEOF_ENUM( color ) == "(const Color)0"); REQUIRE(NAMEOF_ENUM( color ) == "(const Color)-1");
#endif #endif
REQUIRE(NAMEOF_TYPE( struct_var ) == "SomeStruct"); REQUIRE(NAMEOF_TYPE( struct_var ) == "SomeStruct");
REQUIRE(NAMEOF_TYPE_T( decltype(struct_var) ) == "SomeStruct"); REQUIRE(NAMEOF_TYPE_T( decltype(struct_var) ) == "SomeStruct");
@ -443,7 +447,7 @@ TEST_CASE("Spaces and Tabs ignored") {
#if defined(__clang__) || defined(_MSC_VER) #if defined(__clang__) || defined(_MSC_VER)
REQUIRE(NAMEOF_ENUM( color ) == "RED"); REQUIRE(NAMEOF_ENUM( color ) == "RED");
#elif defined(__GNUC__) #elif defined(__GNUC__)
REQUIRE(NAMEOF_ENUM( color ) == "(const Color)0"); REQUIRE(NAMEOF_ENUM( color ) == "(const Color)-1");
#endif #endif
REQUIRE(NAMEOF_TYPE( struct_var ) == "SomeStruct"); REQUIRE(NAMEOF_TYPE( struct_var ) == "SomeStruct");
REQUIRE(NAMEOF_TYPE_T( decltype(struct_var) ) == "SomeStruct"); REQUIRE(NAMEOF_TYPE_T( decltype(struct_var) ) == "SomeStruct");