150 lines
6.6 KiB
C++
150 lines
6.6 KiB
C++
|
#ifndef NEARGYE_NAMEOF_MACRO_HPP
|
||
|
#define NEARGYE_NAMEOF_MACRO_HPP
|
||
|
|
||
|
// Checks nameof_type compiler compatibility.
|
||
|
#if defined(__clang__) && __clang_major__ >= 5 || defined(__GNUC__) && __GNUC__ >= 7 || defined(_MSC_VER) && _MSC_VER >= 1910
|
||
|
#undef NAMEOF_TYPE_SUPPORTED
|
||
|
#define NAMEOF_TYPE_SUPPORTED 1
|
||
|
#endif
|
||
|
|
||
|
// Checks nameof_type_rtti compiler compatibility.
|
||
|
#if defined(__clang__)
|
||
|
#if __has_feature(cxx_rtti)
|
||
|
#undef NAMEOF_TYPE_RTTI_SUPPORTED
|
||
|
#define NAMEOF_TYPE_RTTI_SUPPORTED 1
|
||
|
#endif
|
||
|
#elif defined(__GNUC__)
|
||
|
#if defined(__GXX_RTTI)
|
||
|
#undef NAMEOF_TYPE_RTTI_SUPPORTED
|
||
|
#define NAMEOF_TYPE_RTTI_SUPPORTED 1
|
||
|
#endif
|
||
|
#elif defined(_MSC_VER)
|
||
|
#if defined(_CPPRTTI)
|
||
|
#undef NAMEOF_TYPE_RTTI_SUPPORTED
|
||
|
#define NAMEOF_TYPE_RTTI_SUPPORTED 1
|
||
|
#endif
|
||
|
#endif
|
||
|
|
||
|
// Checks nameof_member compiler compatibility.
|
||
|
#if defined(__clang__) && __clang_major__ >= 5 || defined(__GNUC__) && __GNUC__ >= 7 || \
|
||
|
defined(_MSC_VER) && defined(_MSVC_LANG) && _MSVC_LANG >= 202002L
|
||
|
#undef NAMEOF_MEMBER_SUPPORTED
|
||
|
#define NAMEOF_MEMBER_SUPPORTED 1
|
||
|
#endif
|
||
|
|
||
|
// Checks nameof_pointer compiler compatibility.
|
||
|
#if defined(__clang__) && __clang_major__ >= 5 || defined(__GNUC__) && __GNUC__ >= 7 || \
|
||
|
defined(_MSC_VER) && defined(_MSVC_LANG) && _MSVC_LANG >= 202002L
|
||
|
#undef NAMEOF_POINTER_SUPPORTED
|
||
|
#define NAMEOF_POINTER_SUPPORTED 1
|
||
|
#endif
|
||
|
|
||
|
// Checks nameof_enum compiler compatibility.
|
||
|
#if defined(__clang__) && __clang_major__ >= 5 || defined(__GNUC__) && __GNUC__ >= 9 || defined(_MSC_VER) && _MSC_VER >= 1910
|
||
|
#undef NAMEOF_ENUM_SUPPORTED
|
||
|
#define NAMEOF_ENUM_SUPPORTED 1
|
||
|
#endif
|
||
|
|
||
|
// Checks nameof_enum compiler aliases compatibility.
|
||
|
#if defined(__clang__) && __clang_major__ >= 5 || defined(__GNUC__) && __GNUC__ >= 9 || defined(_MSC_VER) && _MSC_VER >= 1920
|
||
|
#undef NAMEOF_ENUM_SUPPORTED_ALIASES
|
||
|
#define NAMEOF_ENUM_SUPPORTED_ALIASES 1
|
||
|
#endif
|
||
|
|
||
|
// Enum value must be greater or equals than NAMEOF_ENUM_RANGE_MIN. By default NAMEOF_ENUM_RANGE_MIN = -128.
|
||
|
// If need another min range for all enum types by default, redefine the macro NAMEOF_ENUM_RANGE_MIN.
|
||
|
#if !defined(NAMEOF_ENUM_RANGE_MIN)
|
||
|
#define NAMEOF_ENUM_RANGE_MIN -128
|
||
|
#endif
|
||
|
|
||
|
// Enum value must be less or equals than NAMEOF_ENUM_RANGE_MAX. By default NAMEOF_ENUM_RANGE_MAX = 128.
|
||
|
// If need another max range for all enum types by default, redefine the macro NAMEOF_ENUM_RANGE_MAX.
|
||
|
#if !defined(NAMEOF_ENUM_RANGE_MAX)
|
||
|
#define NAMEOF_ENUM_RANGE_MAX 128
|
||
|
#endif
|
||
|
|
||
|
#define NAMEOF_VERSION_MAJOR 0
|
||
|
#define NAMEOF_VERSION_MINOR 10
|
||
|
#define NAMEOF_VERSION_PATCH 4
|
||
|
|
||
|
// Obtains name of variable, function, macro.
|
||
|
#define NAMEOF(...) \
|
||
|
[]() constexpr noexcept { \
|
||
|
::std::void_t<decltype(__VA_ARGS__)>(); \
|
||
|
constexpr auto _name = ::nameof::detail::pretty_name(#__VA_ARGS__); \
|
||
|
static_assert(!_name.empty(), "Expression does not have a name."); \
|
||
|
constexpr auto _size = _name.size(); \
|
||
|
constexpr auto _nameof = ::nameof::cstring<_size>{_name}; \
|
||
|
return _nameof; \
|
||
|
}()
|
||
|
|
||
|
// Obtains full name of variable, function, macro.
|
||
|
#define NAMEOF_FULL(...) \
|
||
|
[]() constexpr noexcept { \
|
||
|
::std::void_t<decltype(__VA_ARGS__)>(); \
|
||
|
constexpr auto _name = ::nameof::detail::pretty_name(#__VA_ARGS__, false); \
|
||
|
static_assert(!_name.empty(), "Expression does not have a name."); \
|
||
|
constexpr auto _size = _name.size(); \
|
||
|
constexpr auto _nameof_full = ::nameof::cstring<_size>{_name}; \
|
||
|
return _nameof_full; \
|
||
|
}()
|
||
|
|
||
|
// Obtains raw name of variable, function, macro.
|
||
|
#define NAMEOF_RAW(...) \
|
||
|
[]() constexpr noexcept { \
|
||
|
::std::void_t<decltype(__VA_ARGS__)>(); \
|
||
|
constexpr auto _name = ::nameof::string_view{#__VA_ARGS__}; \
|
||
|
static_assert(!_name.empty(), "Expression does not have a name."); \
|
||
|
constexpr auto _size = _name.size(); \
|
||
|
constexpr auto _nameof_raw = ::nameof::cstring<_size>{_name}; \
|
||
|
return _nameof_raw; \
|
||
|
}()
|
||
|
|
||
|
// Obtains name of enum variable.
|
||
|
#define NAMEOF_ENUM(...) ::nameof::nameof_enum<::std::decay_t<decltype(__VA_ARGS__)>>(__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__>()
|
||
|
|
||
|
// Obtains name of enum-flags variable.
|
||
|
#define NAMEOF_ENUM_FLAG(...) ::nameof::nameof_enum_flag<::std::decay_t<decltype(__VA_ARGS__)>>(__VA_ARGS__)
|
||
|
|
||
|
// Obtains type name, reference and cv-qualifiers are ignored.
|
||
|
#define NAMEOF_TYPE(...) ::nameof::nameof_type<__VA_ARGS__>()
|
||
|
|
||
|
// Obtains full type name, with reference and cv-qualifiers.
|
||
|
#define NAMEOF_FULL_TYPE(...) ::nameof::nameof_full_type<__VA_ARGS__>()
|
||
|
|
||
|
// Obtains short type name.
|
||
|
#define NAMEOF_SHORT_TYPE(...) ::nameof::nameof_short_type<__VA_ARGS__>()
|
||
|
|
||
|
// Obtains type name of expression, reference and cv-qualifiers are ignored.
|
||
|
#define NAMEOF_TYPE_EXPR(...) ::nameof::nameof_type<decltype(__VA_ARGS__)>()
|
||
|
|
||
|
// Obtains full type name of expression, with reference and cv-qualifiers.
|
||
|
#define NAMEOF_FULL_TYPE_EXPR(...) ::nameof::nameof_full_type<decltype(__VA_ARGS__)>()
|
||
|
|
||
|
// Obtains short type name of expression.
|
||
|
#define NAMEOF_SHORT_TYPE_EXPR(...) ::nameof::nameof_short_type<decltype(__VA_ARGS__)>()
|
||
|
|
||
|
// Obtains type name, with reference and cv-qualifiers, using RTTI.
|
||
|
#define NAMEOF_TYPE_RTTI(...) ::nameof::detail::nameof_type_rtti<::std::void_t<decltype(__VA_ARGS__)>>(typeid(__VA_ARGS__).name())
|
||
|
|
||
|
// Obtains full type name, using RTTI.
|
||
|
#define NAMEOF_FULL_TYPE_RTTI(...) ::nameof::detail::nameof_full_type_rtti<decltype(__VA_ARGS__)>(typeid(__VA_ARGS__).name())
|
||
|
|
||
|
// Obtains short type name, using RTTI.
|
||
|
#define NAMEOF_SHORT_TYPE_RTTI(...) ::nameof::detail::nameof_short_type_rtti<decltype(__VA_ARGS__)>(typeid(__VA_ARGS__).name())
|
||
|
|
||
|
// Obtains name of member.
|
||
|
#define NAMEOF_MEMBER(...) ::nameof::nameof_member<__VA_ARGS__>()
|
||
|
|
||
|
// Obtains name of a function, a global or class static variable.
|
||
|
#define NAMEOF_POINTER(...) ::nameof::nameof_pointer<__VA_ARGS__>()
|
||
|
|
||
|
#endif
|