#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(); \ 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(); \ 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(); \ 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>(__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>(__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() // Obtains full type name of expression, with reference and cv-qualifiers. #define NAMEOF_FULL_TYPE_EXPR(...) ::nameof::nameof_full_type() // Obtains short type name of expression. #define NAMEOF_SHORT_TYPE_EXPR(...) ::nameof::nameof_short_type() // Obtains type name, with reference and cv-qualifiers, using RTTI. #define NAMEOF_TYPE_RTTI(...) ::nameof::detail::nameof_type_rtti<::std::void_t>(typeid(__VA_ARGS__).name()) // Obtains full type name, using RTTI. #define NAMEOF_FULL_TYPE_RTTI(...) ::nameof::detail::nameof_full_type_rtti(typeid(__VA_ARGS__).name()) // Obtains short type name, using RTTI. #define NAMEOF_SHORT_TYPE_RTTI(...) ::nameof::detail::nameof_short_type_rtti(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