fix nameof enum
This commit is contained in:
parent
2a118da028
commit
bfacde30f2
2 changed files with 32 additions and 21 deletions
|
@ -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>
|
||||||
|
|
|
@ -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");
|
||||||
|
|
Loading…
Reference in a new issue