diff --git a/doc/reference.md b/doc/reference.md index f0fbdc6..61c5f3e 100644 --- a/doc/reference.md +++ b/doc/reference.md @@ -12,6 +12,7 @@ * [`NAMEOF_FULL_TYPE` macro that obtains string name of full type, with reference and cv-qualifiers.](#nameof_full_type-1) * [`NAMEOF_TYPE_EXPR` macro that obtains string name type of expression, reference and cv-qualifiers are ignored.](#nameof_type_expr) * [`NAMEOF_FULL_TYPE_EXPR` macro that obtains string name full type of expression, with reference and cv-qualifiers.](#nameof_full_type_expr) +* [`NAMEOF_TYPE_RTTI` macro that obtains string name type, using RTTI.](#nameof_type_rtti) ## Synopsis @@ -256,3 +257,20 @@ T var = 42; NAMEOF_FULL_TYPE_EXPR(var) -> "const int&" ``` + +## `NAMEOF_TYPE_RTTI` + +* Macro macro that obtains string name of type, using RTTI. + +* Returns demangled RTTI type name. + +* Examples + + ```cpp + struct Base { virtual void foo() {} }; + struct Derived : Base {}; + + Base* ptr = new Derived(); + NAMEOF_TYPE_RTTI(ptr) -> "Base *" + NAMEOF_TYPE_RTTI(*ptr) -> "Derived" + ``` diff --git a/example/example.cpp b/example/example.cpp index 053b199..30c7e52 100644 --- a/example/example.cpp +++ b/example/example.cpp @@ -27,6 +27,10 @@ #include #include +struct Base { virtual void foo() {} }; + +struct Derived : Base {}; + struct SomeStruct { int somefield = 0; @@ -161,6 +165,13 @@ int main() { std::cout << NAMEOF_RAW(structvar.somefield) << std::endl; // 'structvar.somefield' std::cout << NAMEOF_RAW(&SomeStruct::SomeMethod1) << std::endl; // '&SomeStruct::SomeMethod1' +#if defined(NAMEOF_TYPE_RTTI_SUPPORTED) + // Nameof type using RTTI. + Base* ptr = new Derived(); + std::cout << NAMEOF_TYPE_RTTI(ptr) << std::endl; // "Base *" + std::cout << NAMEOF_TYPE_RTTI(*ptr) << std::endl; // "Derived" +#endif + // Some more complex example. std::cout << SomeMethod4(structvar) << std::endl; // 'SomeMethod4(SomeStruct value)' diff --git a/include/nameof.hpp b/include/nameof.hpp index 4e5d690..0fe447e 100644 --- a/include/nameof.hpp +++ b/include/nameof.hpp @@ -568,6 +568,10 @@ inline constexpr auto type_name_v = n(); #if __has_include() inline std::string demangle(const char* tn) { + if (tn == nullptr) { + return {}; + } + auto dmg = abi::__cxa_demangle(tn, nullptr, nullptr, nullptr); auto r = std::string{dmg != nullptr ? dmg : tn}; std::free(dmg); @@ -575,7 +579,7 @@ inline std::string demangle(const char* tn) { } #else constexpr std::string_view demangle(const char* tn) noexcept { - return std::string_view{tn}; + return {tn}; } #endif @@ -699,7 +703,7 @@ template // Obtains string name full type of expression, with reference and cv-qualifiers. #define NAMEOF_FULL_TYPE_EXPR(...) ::nameof::nameof_full_type() -// Obtains string name of type using RTTI. +// Obtains string name of type, using RTTI. #define NAMEOF_TYPE_RTTI(...) ::nameof::detail::demangle(typeid(__VA_ARGS__).name()) #if defined(_MSC_VER)