wip
This commit is contained in:
parent
5e0024145c
commit
46a5376eb3
3 changed files with 87 additions and 155 deletions
|
@ -49,15 +49,16 @@ void SomeMethod3() {
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
T SomeMethod4() {
|
std::string SomeMethod4() {
|
||||||
return T{};
|
std::cout << NAMEOF_TYPE_T(T) << std::endl;
|
||||||
|
return NAMEOF_FULL(SomeMethod4<T>);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
class SomeClass {
|
class SomeClass {
|
||||||
public:
|
public:
|
||||||
void SomeMethod5() const {
|
void SomeMethod5() const {
|
||||||
std::cout << NAMEOF_TYPE_T(T) << std::endl;
|
std::cout << nameof::NameofType<T>() << std::endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename C>
|
template <typename C>
|
||||||
|
@ -103,6 +104,7 @@ int main() {
|
||||||
std::cout << NAMEOF(&SomeStruct::SomeMethod2) << std::endl; // SomeMethod2
|
std::cout << NAMEOF(&SomeStruct::SomeMethod2) << std::endl; // SomeMethod2
|
||||||
std::cout << NAMEOF(SomeMethod3) << std::endl; // SomeMethod3
|
std::cout << NAMEOF(SomeMethod3) << std::endl; // SomeMethod3
|
||||||
|
|
||||||
|
std::cout << NAMEOF(SomeMethod4<int>()) << std::endl; // SomeMethod4
|
||||||
std::cout << NAMEOF(SomeMethod4<int>) << std::endl; // SomeMethod4
|
std::cout << NAMEOF(SomeMethod4<int>) << std::endl; // SomeMethod4
|
||||||
std::cout << NAMEOF_FULL(SomeMethod4<int>) << std::endl; // SomeMethod4<int>
|
std::cout << NAMEOF_FULL(SomeMethod4<int>) << std::endl; // SomeMethod4<int>
|
||||||
|
|
||||||
|
@ -122,11 +124,9 @@ int main() {
|
||||||
std::cout << NAMEOF_TYPE_T(SomeClass<int>) << std::endl; // SomeClass<int>
|
std::cout << NAMEOF_TYPE_T(SomeClass<int>) << std::endl; // SomeClass<int>
|
||||||
|
|
||||||
// Raw name.
|
// Raw name.
|
||||||
std::cout << NAMEOF_RAW(volatile const int) << std::endl; // volatile const int
|
|
||||||
std::cout << NAMEOF_RAW(__LINE__) << std::endl; // __LINE__
|
std::cout << NAMEOF_RAW(__LINE__) << std::endl; // __LINE__
|
||||||
std::cout << NAMEOF_RAW(structvar.somefield) << std::endl; // structvar.somefield
|
std::cout << NAMEOF_RAW(structvar.somefield) << std::endl; // structvar.somefield
|
||||||
std::cout << NAMEOF_RAW(&SomeStruct::SomeMethod1) << std::endl; // &SomeStruct::SomeMethod1
|
std::cout << NAMEOF_RAW(&SomeStruct::SomeMethod1) << std::endl; // &SomeStruct::SomeMethod1
|
||||||
std::cout << NAMEOF_RAW(Long::LL) << std::endl; // Long::LL
|
|
||||||
|
|
||||||
const auto div = [](int x, int y) -> int {
|
const auto div = [](int x, int y) -> int {
|
||||||
if (y == 0) {
|
if (y == 0) {
|
||||||
|
@ -143,27 +143,31 @@ int main() {
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Remarks */
|
/* Remarks */
|
||||||
#if 0
|
#if 1
|
||||||
// This expression does not have a name.
|
// This expression does not have a name.
|
||||||
std::cout << NAMEOF("Bad case") << std::endl; // '"Bad case"'
|
std::cout << NAMEOF("Bad case"_string) << std::endl; // '_string'
|
||||||
std::cout << NAMEOF("Bad case"_string) << std::endl; // '"Bad case"_string'
|
|
||||||
std::cout << NAMEOF("somevar.somefield") << std::endl; // 'somefield"'
|
|
||||||
std::cout << NAMEOF(42.0) << std::endl; // '0'
|
std::cout << NAMEOF(42.0) << std::endl; // '0'
|
||||||
std::cout << NAMEOF(42.f) << std::endl; // 'f'
|
std::cout << NAMEOF(42.f) << std::endl; // 'f'
|
||||||
std::cout << NAMEOF(42) << std::endl; // '42'
|
std::cout << NAMEOF(42) << std::endl; // '42'
|
||||||
std::cout << NAMEOF(42.0_deg) << std::endl; // '0_deg'
|
std::cout << NAMEOF(42.0_deg) << std::endl; // '0_deg'
|
||||||
std::cout << NAMEOF(std::string()) << std::endl; // 'string()'
|
std::cout << NAMEOF(std::string()) << std::endl; // 'string'
|
||||||
std::cout << NAMEOF(std::string{}) << std::endl; // "string{}'
|
std::cout << NAMEOF(std::string{}) << std::endl; // 'string'
|
||||||
std::cout << NAMEOF(std::string{"test"}) << std::endl; // 'string{"test"}'
|
std::cout << NAMEOF(std::string{"test"}) << std::endl; // 'string'
|
||||||
std::cout << NAMEOF(SomeMethod4<int>()) << std::endl; // '()'
|
std::cout << NAMEOF(structvar.somefield + structvar.somefield) << std::endl; // ' somefield'
|
||||||
|
std::cout << NAMEOF(42 + 42) << std::endl; // ' 42'
|
||||||
|
std::cout << NAMEOF(NAMEOF(structvar)) << std::endl; // 'NAMEOF'
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
// This expression does not compilation.
|
||||||
|
std::cout << NAMEOF("Bad case") << std::endl; // ''
|
||||||
|
std::cout << NAMEOF("somevar.somefield") << std::endl; // ''
|
||||||
std::cout << NAMEOF(std::basic_string<char>) << std::endl; // ''
|
std::cout << NAMEOF(std::basic_string<char>) << std::endl; // ''
|
||||||
std::cout << NAMEOF(ptrvar[0]) << std::endl; // 'ptrvar[0]'
|
std::cout << NAMEOF(ptrvar[0]) << std::endl; // 'ptrvar[0]'
|
||||||
std::cout << NAMEOF(intvar + intvar) << std::endl; // ' intvar'
|
std::cout << NAMEOF(std::cout << structvar << std::endl) << std::endl; // ''
|
||||||
std::cout << NAMEOF(NAMEOF(intvar)) << std::endl; // 'NAMEOF(intvar)'
|
std::cout << NAMEOF(decltype(structvar)) << std::endl; // ''
|
||||||
std::cout << NAMEOF(std::cout << intvar << std::endl) << std::endl; // 'endl'
|
std::cout << NAMEOF(typeid(structvar)) << std::endl; // ''
|
||||||
std::cout << NAMEOF(decltype(intvar)) << std::endl; // 'decltype(intvar)'
|
std::cout << NAMEOF((structvar)) << std::endl; // ''
|
||||||
std::cout << NAMEOF(typeid(intvar)) << std::endl; // 'typeid(intvar)'
|
|
||||||
std::cout << NAMEOF((intvar)) << std::endl; // '(intvar)'
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
|
@ -39,7 +39,7 @@
|
||||||
# define NAMEOF_HAS_CONSTEXPR14 1
|
# define NAMEOF_HAS_CONSTEXPR14 1
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(__clang__) || defined(_MSC_VER)
|
#if (defined(__clang__) || defined(_MSC_VER)) || (defined(__GNUC__) && __GNUC__ >= 5)
|
||||||
# define NAMEOF_TYPE_CONSTEXPR constexpr
|
# define NAMEOF_TYPE_CONSTEXPR constexpr
|
||||||
# define NAMEOF_TYPE_HAS_CONSTEXPR 1
|
# define NAMEOF_TYPE_HAS_CONSTEXPR 1
|
||||||
#else
|
#else
|
||||||
|
@ -57,49 +57,6 @@ struct identity {
|
||||||
using type = T;
|
using type = T;
|
||||||
};
|
};
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
using identity_t = typename identity<T>::type;
|
|
||||||
|
|
||||||
// Removes all pointer from the given type.
|
|
||||||
template <typename T>
|
|
||||||
struct remove_all_p
|
|
||||||
: std::conditional<std::is_pointer<T>::value,
|
|
||||||
remove_all_p<typename std::remove_pointer<T>::type>,
|
|
||||||
identity<T>
|
|
||||||
>::type {};
|
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
using remove_all_p_t = typename remove_all_p<T>::type;
|
|
||||||
|
|
||||||
// Removes const, volatile, reference specifiers from the given type.
|
|
||||||
template <typename T>
|
|
||||||
struct remove_cvr {
|
|
||||||
using type = typename std::remove_cv<typename std::remove_reference<T>::type>::type;
|
|
||||||
};
|
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
using remove_cvr_t = typename remove_cvr<T>::type;
|
|
||||||
|
|
||||||
// Removes all const, volatile, reference, pointer specifiers from the given type.
|
|
||||||
template <typename T>
|
|
||||||
struct remove_all_cvrp {
|
|
||||||
using type = typename remove_cvr<typename remove_all_p<typename remove_cvr<T>::type>::type>::type;
|
|
||||||
};
|
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
using remove_all_cvrp_t = typename remove_all_cvrp<T>::type;
|
|
||||||
|
|
||||||
// Removes all const, volatile, reference, pointer, array extents specifiers from the given type.
|
|
||||||
template <typename T, typename U = typename remove_all_cvrp<T>::type>
|
|
||||||
struct remove_all_cvrpe
|
|
||||||
: std::conditional<std::is_array<U>::value,
|
|
||||||
remove_all_cvrpe<typename std::remove_all_extents<U>::type>,
|
|
||||||
identity<U>
|
|
||||||
>::type {};
|
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
using remove_all_cvrpe_t = typename remove_all_cvrpe<T>::type;
|
|
||||||
|
|
||||||
} // namespace nstd
|
} // namespace nstd
|
||||||
|
|
||||||
constexpr bool StrEquals(const char* lhs, const char* rhs, std::size_t size) {
|
constexpr bool StrEquals(const char* lhs, const char* rhs, std::size_t size) {
|
||||||
|
@ -220,13 +177,11 @@ constexpr bool IsLexeme(char s) noexcept {
|
||||||
constexpr cstring NameofPretty(cstring name, bool with_suffix) noexcept {
|
constexpr cstring NameofPretty(cstring name, bool with_suffix) noexcept {
|
||||||
std::size_t s = 0;
|
std::size_t s = 0;
|
||||||
for (std::size_t i = name.size(), h = 0; i > 0; --i) {
|
for (std::size_t i = name.size(), h = 0; i > 0; --i) {
|
||||||
if (name[i - 1] == '>') {
|
if (name[i - 1] == '>' || name[i - 1] == ')' || name[i - 1] == '}') {
|
||||||
++h;
|
++h;
|
||||||
++s;
|
++s;
|
||||||
continue;
|
continue;
|
||||||
}
|
} else if (name[i - 1] == '<' || name[i - 1] == '(' || name[i - 1] == '{') {
|
||||||
|
|
||||||
if (name[i - 1] == '<') {
|
|
||||||
--h;
|
--h;
|
||||||
++s;
|
++s;
|
||||||
continue;
|
continue;
|
||||||
|
@ -249,31 +204,32 @@ constexpr cstring NameofPretty(cstring name, bool with_suffix) noexcept {
|
||||||
return name.remove_suffix(with_suffix ? 0 : s);
|
return name.remove_suffix(with_suffix ? 0 : s);
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
constexpr std::size_t NameofBaseImpl1(cstring name, std::size_t h = 0, std::size_t s = 0) noexcept {
|
constexpr std::size_t FindSuffix(cstring name, std::size_t h = 0, std::size_t s = 0) noexcept {
|
||||||
return name[name.size() - 1 - s] == '>'
|
return (name[name.size() - 1 - s] == '>' || name[name.size() - 1 - s] == ')' || name[name.size() - 1 - s] == '}')
|
||||||
? NameofBaseImpl1(name, h + 1, s + 1)
|
? FindSuffix(name, h + 1, s + 1)
|
||||||
: name[name.size() - 1 - s] == '<'
|
: (name[name.size() - 1 - s] == '<' || name[name.size() - 1 - s] == ')' || name[name.size() - 1 - s] == '{')
|
||||||
? NameofBaseImpl1(name, h - 1, s + 1)
|
? FindSuffix(name, h - 1, s + 1)
|
||||||
: h == 0 ? s : NameofBaseImpl1(name, h, s + 1);
|
: h == 0 ? s : FindSuffix(name, h, s + 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
constexpr cstring NameofBaseImpl2(cstring name, const std::size_t p = 0) noexcept {
|
constexpr cstring RemovePrefix(cstring name, const std::size_t p = 0) noexcept {
|
||||||
return p == name.size() ? name : IsLexeme(name[name.size() - 1 - p])
|
return p == name.size() ? name : IsLexeme(name[name.size() - 1 - p])
|
||||||
? name.remove_prefix(name.size() - p)
|
? name.remove_prefix(name.size() - p)
|
||||||
: NameofBaseImpl2(name, p + 1);
|
: RemovePrefix(name, p + 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
constexpr cstring NameofBaseImpl3(cstring name, std::size_t s, bool with_suffix) noexcept {
|
constexpr cstring NameofPrettyImpl(cstring name, std::size_t s, bool with_suffix) noexcept {
|
||||||
return NameofBaseImpl2(name.remove_suffix(s)).add_suffix(with_suffix ? s : 0);
|
return RemovePrefix(name.remove_suffix(s)).add_suffix(with_suffix ? s : 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
constexpr cstring NameofPretty(cstring name, bool with_suffix) noexcept {
|
constexpr cstring NameofPretty(cstring name, bool with_suffix) noexcept {
|
||||||
return NameofBaseImpl3(name, NameofBaseImpl1(name), with_suffix);
|
return NameofPrettyImpl(name, FindSuffix(name), with_suffix);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
constexpr cstring RemoveSpace(cstring name) noexcept {
|
#if defined(_MSC_VER)
|
||||||
return name.back() == ' ' ? RemoveSpace(name.remove_suffix(1)) : name;
|
constexpr cstring RemoveSpaceSuffix(cstring name) noexcept {
|
||||||
|
return name.back() == ' ' ? RemoveSpaceSuffix(name.remove_suffix(1)) : name;
|
||||||
}
|
}
|
||||||
|
|
||||||
constexpr cstring RemoveClassPrefix(cstring name) noexcept {
|
constexpr cstring RemoveClassPrefix(cstring name) noexcept {
|
||||||
|
@ -297,27 +253,39 @@ constexpr cstring RemoveStructPrefix(cstring name) noexcept {
|
||||||
: name;
|
: name;
|
||||||
}
|
}
|
||||||
|
|
||||||
constexpr cstring NameofTypeRawPretty(cstring name) noexcept {
|
constexpr cstring NameofTypePretty(cstring name) noexcept {
|
||||||
return RemoveClassPrefix(RemoveStructPrefix(RemoveEnumPrefix(RemoveSpace(name))));
|
return RemoveClassPrefix(RemoveStructPrefix(RemoveEnumPrefix(RemoveSpaceSuffix(name))));
|
||||||
}
|
}
|
||||||
|
#elif defined(__clang__) || defined(__GNUC__)
|
||||||
|
constexpr cstring NameofTypePretty(const char* str, std::size_t size, std::size_t prefix, std::size_t suffix) noexcept {
|
||||||
|
return {str, size, prefix, suffix + (str[size - suffix - 1] == ' ' ? 1 : 0)};
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
NAMEOF_TYPE_CONSTEXPR cstring NameofTypeRaw() noexcept {
|
NAMEOF_TYPE_CONSTEXPR cstring NameofType() noexcept {
|
||||||
#if defined(__clang__)
|
#if defined(__clang__)
|
||||||
return {__PRETTY_FUNCTION__,
|
return NameofTypePretty(
|
||||||
|
__PRETTY_FUNCTION__,
|
||||||
sizeof(__PRETTY_FUNCTION__) - 1,
|
sizeof(__PRETTY_FUNCTION__) - 1,
|
||||||
sizeof("nameof::detail::cstring nameof::detail::NameofTypeRaw() [T = nameof::detail::nstd::identity<") - 1,
|
sizeof("nameof::detail::cstring nameof::detail::NameofType() [T = nameof::detail::nstd::identity<") - 1,
|
||||||
sizeof(">]") - 1};
|
sizeof(">]") - 1);
|
||||||
#elif defined(__GNUC__)
|
#elif defined(__GNUC__)
|
||||||
return {__PRETTY_FUNCTION__,
|
return NameofTypePretty(
|
||||||
|
__PRETTY_FUNCTION__,
|
||||||
sizeof(__PRETTY_FUNCTION__) - 1,
|
sizeof(__PRETTY_FUNCTION__) - 1,
|
||||||
sizeof("nameof::detail::cstring nameof::detail::NameofTypeRaw() [with T = nameof::detail::nstd::identity<") - 1,
|
# if defined(NAMEOF_TYPE_HAS_CONSTEXPR)
|
||||||
sizeof(">]") - 1};
|
sizeof("constexpr nameof::detail::cstring nameof::detail::NameofType() [with T = nameof::detail::nstd::identity<") - 1,
|
||||||
|
# else
|
||||||
|
sizeof("nameof::detail::cstring nameof::detail::NameofType() [with T = nameof::detail::nstd::identity<") - 1,
|
||||||
|
# endif
|
||||||
|
sizeof(">]") - 1);
|
||||||
#elif defined(_MSC_VER)
|
#elif defined(_MSC_VER)
|
||||||
return {__FUNCSIG__,
|
return NameofTypePretty(
|
||||||
|
{__FUNCSIG__,
|
||||||
sizeof(__FUNCSIG__) - 1,
|
sizeof(__FUNCSIG__) - 1,
|
||||||
sizeof("class nameof::detail::cstring __cdecl nameof::detail::NameofTypeRaw<struct nameof::detail::nstd::identity<") - 1,
|
sizeof("class nameof::detail::cstring __cdecl nameof::detail::NameofType<struct nameof::detail::nstd::identity<") - 1,
|
||||||
sizeof(">>(void) noexcept") - 1};
|
sizeof(">>(void) noexcept") - 1});
|
||||||
#else
|
#else
|
||||||
return {};
|
return {};
|
||||||
#endif
|
#endif
|
||||||
|
@ -326,16 +294,11 @@ NAMEOF_TYPE_CONSTEXPR cstring NameofTypeRaw() noexcept {
|
||||||
template <typename T,
|
template <typename T,
|
||||||
typename = typename std::enable_if<!std::is_reference<T>::value &&
|
typename = typename std::enable_if<!std::is_reference<T>::value &&
|
||||||
!std::is_void<T>::value>::type>
|
!std::is_void<T>::value>::type>
|
||||||
constexpr cstring Nameof(const T&, const char* name, std::size_t size, bool with_suffix) noexcept {
|
constexpr cstring Nameof(const char* name, std::size_t size, bool with_suffix) noexcept {
|
||||||
return NameofPretty({name, size}, with_suffix);
|
return NameofPretty({name, size}, with_suffix);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T,
|
template <typename T>
|
||||||
typename = typename std::enable_if<!std::is_enum<T>::value &&
|
|
||||||
!std::is_function<T>::value &&
|
|
||||||
!std::is_member_function_pointer<T>::value>::type>
|
|
||||||
constexpr cstring Nameof(T&&, const char*, std::size_t, bool) = delete;
|
|
||||||
|
|
||||||
constexpr cstring NameofRaw(const char* name, std::size_t size) noexcept {
|
constexpr cstring NameofRaw(const char* name, std::size_t size) noexcept {
|
||||||
return {name, size};
|
return {name, size};
|
||||||
}
|
}
|
||||||
|
@ -343,42 +306,21 @@ constexpr cstring NameofRaw(const char* name, std::size_t size) noexcept {
|
||||||
} // namespace detail
|
} // namespace detail
|
||||||
|
|
||||||
template <typename T, typename H = detail::nstd::identity<T>>
|
template <typename T, typename H = detail::nstd::identity<T>>
|
||||||
NAMEOF_TYPE_CONSTEXPR detail::cstring NameofType(bool pretty = true) noexcept {
|
NAMEOF_TYPE_CONSTEXPR detail::cstring NameofType() noexcept {
|
||||||
return pretty ? detail::NameofTypeRawPretty(detail::NameofTypeRaw<H>()) : detail::NameofTypeRaw<H>();
|
return true ? detail::NameofType<H>() : detail::NameofType<H>();
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace nameof
|
} // namespace nameof
|
||||||
|
|
||||||
#if defined(__clang__)
|
// Used to obtain the simple (unqualified) string name of a variable, member, function, macros.
|
||||||
# if __has_feature(cxx_rtti)
|
#define NAMEOF(name) ::nameof::detail::Nameof<decltype(name)>(#name, (sizeof(#name) / sizeof(char)) - 1, false)
|
||||||
# define NAMEOF_HAS_RTTI 1
|
|
||||||
# endif
|
|
||||||
#elif defined(__GNUC__)
|
|
||||||
# if defined(__GXX_RTTI)
|
|
||||||
# define NAMEOF_HAS_RTTI 1
|
|
||||||
# endif
|
|
||||||
#elif defined(_MSC_VER) && defined(_CPPRTTI)
|
|
||||||
# if defined(_CPPRTTI)
|
|
||||||
# define NAMEOF_HAS_RTTI 1
|
|
||||||
# endif
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if defined(NAMEOF_HAS_RTTI) || defined(_MSC_VER)
|
// Used to obtain the full string name of a variable, member, function, macros.
|
||||||
#include <typeinfo>
|
#define NAMEOF_FULL(name) ::nameof::detail::Nameof<decltype(name)>(#name, (sizeof(#name) / sizeof(char)) - 1, true)
|
||||||
|
|
||||||
// Used to obtain the raw string name of a variable, type, member, function, macros.
|
// Used to obtain the raw string name of a variable, member, function, macros.
|
||||||
# define NAMEOF_RAW(name) ::nameof::detail::NameofRaw(#name, ((sizeof(#name) / sizeof(char)) - 1) + (0 * sizeof(typeid(name))))
|
#define NAMEOF_RAW(name) ::nameof::detail::NameofRaw<decltype(name)>(#name, (sizeof(#name) / sizeof(char)) - 1)
|
||||||
#elif defined(__clang__) || defined(__GNUC__)
|
|
||||||
// Used to obtain the raw string name of a variable, type, member, function, macros.
|
|
||||||
# define NAMEOF_RAW(name) ::nameof::detail::NameofRaw(#name, ((sizeof(#name) / sizeof(char)) - 1) + (0 * sizeof(void(*)(__typeof__(name)))))
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// Used to obtain the simple (unqualified) string name of a variable, member, function.
|
|
||||||
#define NAMEOF(name) ::nameof::detail::Nameof<decltype(name)>(name, #name, (sizeof(#name) / sizeof(char)) - 1, false)
|
|
||||||
|
|
||||||
// Used to obtain the full string name of a variable, member, function.
|
|
||||||
#define NAMEOF_FULL(name) ::nameof::detail::Nameof<decltype(name)>(name, #name, (sizeof(#name) / sizeof(char)) - 1, true)
|
|
||||||
|
|
||||||
// Used to obtain the string name of a type.
|
// Used to obtain the string name of a type.
|
||||||
#define NAMEOF_TYPE(var) ::nameof::NameofType<decltype(var)>(true)
|
#define NAMEOF_TYPE(var) ::nameof::NameofType<decltype(var)>()
|
||||||
#define NAMEOF_TYPE_T(type) ::nameof::NameofType<type>(true)
|
#define NAMEOF_TYPE_T(type) ::nameof::NameofType<type>()
|
||||||
|
|
|
@ -114,9 +114,6 @@ TEST_CASE("constexpr") {
|
||||||
// member
|
// member
|
||||||
constexpr auto cx2 = NAMEOF_RAW((&structvar)->somefield);
|
constexpr auto cx2 = NAMEOF_RAW((&structvar)->somefield);
|
||||||
static_assert(cx2 == "(&structvar)->somefield", "");
|
static_assert(cx2 == "(&structvar)->somefield", "");
|
||||||
// type
|
|
||||||
constexpr auto cx3 = NAMEOF_RAW(std::string);
|
|
||||||
static_assert(cx3 == "std::string", "");
|
|
||||||
// function
|
// function
|
||||||
constexpr auto cx4 = NAMEOF_RAW(&SomeStruct::SomeMethod2);
|
constexpr auto cx4 = NAMEOF_RAW(&SomeStruct::SomeMethod2);
|
||||||
static_assert(cx4 == "&SomeStruct::SomeMethod2", "");
|
static_assert(cx4 == "&SomeStruct::SomeMethod2", "");
|
||||||
|
@ -127,9 +124,7 @@ TEST_CASE("constexpr") {
|
||||||
constexpr auto cx6 = NAMEOF_RAW(__cplusplus);
|
constexpr auto cx6 = NAMEOF_RAW(__cplusplus);
|
||||||
static_assert(cx6 == "__cplusplus", "");
|
static_assert(cx6 == "__cplusplus", "");
|
||||||
}
|
}
|
||||||
|
#if defined(NAMEOF_TYPE_HAS_CONSTEXPR)
|
||||||
// constexpr NAMEOF_TYPE not supported in GCC.
|
|
||||||
#if defined(_MSC_VER) || defined(__clang__)
|
|
||||||
SECTION("NAMEOF_TYPE") {
|
SECTION("NAMEOF_TYPE") {
|
||||||
constexpr auto cx = NAMEOF_TYPE(classvar);
|
constexpr auto cx = NAMEOF_TYPE(classvar);
|
||||||
# if defined(__clang__)
|
# if defined(__clang__)
|
||||||
|
@ -138,6 +133,7 @@ TEST_CASE("constexpr") {
|
||||||
static_assert(cx == "SomeClass<int> const volatile *", "");
|
static_assert(cx == "SomeClass<int> const volatile *", "");
|
||||||
# endif
|
# endif
|
||||||
}
|
}
|
||||||
|
|
||||||
SECTION("NAMEOF_TYPE_T") {
|
SECTION("NAMEOF_TYPE_T") {
|
||||||
constexpr auto cx = NAMEOF_TYPE_T(const SomeClass<int> volatile *);
|
constexpr auto cx = NAMEOF_TYPE_T(const SomeClass<int> volatile *);
|
||||||
# if defined(__clang__)
|
# if defined(__clang__)
|
||||||
|
@ -225,16 +221,6 @@ TEST_CASE("NAMEOF_RAW") {
|
||||||
REQUIRE(NAMEOF_RAW(othervar.ll.field) == "othervar.ll.field");
|
REQUIRE(NAMEOF_RAW(othervar.ll.field) == "othervar.ll.field");
|
||||||
}
|
}
|
||||||
|
|
||||||
SECTION("type") {
|
|
||||||
REQUIRE(NAMEOF_RAW(int[]) == "int[]");
|
|
||||||
REQUIRE(NAMEOF_RAW(int) == "int");
|
|
||||||
REQUIRE(NAMEOF_RAW(const volatile int[]) == "const volatile int[]");
|
|
||||||
REQUIRE(NAMEOF_RAW(std::string) == "std::string");
|
|
||||||
REQUIRE(NAMEOF_RAW(SomeStruct) == "SomeStruct");
|
|
||||||
REQUIRE(NAMEOF_RAW(Long::LL) == "Long::LL");
|
|
||||||
REQUIRE(NAMEOF_RAW(Color) == "Color");
|
|
||||||
}
|
|
||||||
|
|
||||||
SECTION("function") {
|
SECTION("function") {
|
||||||
REQUIRE(NAMEOF_RAW(&SomeStruct::SomeMethod1) == "&SomeStruct::SomeMethod1");
|
REQUIRE(NAMEOF_RAW(&SomeStruct::SomeMethod1) == "&SomeStruct::SomeMethod1");
|
||||||
REQUIRE(NAMEOF_RAW(&SomeStruct::SomeMethod2) == "&SomeStruct::SomeMethod2");
|
REQUIRE(NAMEOF_RAW(&SomeStruct::SomeMethod2) == "&SomeStruct::SomeMethod2");
|
||||||
|
|
Loading…
Reference in a new issue