Created
July 17, 2025 10:21
-
-
Save neugen86/b65370d3a55b9690b7e38de7bed86776 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #pragma once | |
| #include <stddef.h> | |
| #include <memory.h> | |
| // Getting the type of a template argument as string – without RTTI | |
| // https://blog.molecular-matters.com/2015/12/11/getting-the-type-of-a-template-argument-as-string-without-rtti/ | |
| namespace internal | |
| { | |
| #if defined(__clang__) | |
| // e.g.: static const char *internal::GetTypeNameHelper<MyStruct>::Apply() [T = TypeName] | |
| #define FUNCTION_MACRO __PRETTY_FUNCTION__ | |
| #define PREFIX "static const char *internal::GetTypeNameHelper<" | |
| #define SUFFIX_1 ">::Apply() [T = " | |
| #define SUFFIX_2 "]" | |
| #define NUM_TYPE_REPEATS 2 | |
| #elif defined(__GNUC__) || defined(__GNUG__) | |
| // e.g.: static const char* internal::GetTypeNameHelper<T>::Apply() [with T = TypeName] | |
| #define FUNCTION_MACRO __PRETTY_FUNCTION__ | |
| #define PREFIX "static const char* internal::GetTypeNameHelper<T>::Apply() [with T = " | |
| #define SUFFIX_1 "]" | |
| #define SUFFIX_2 "" | |
| #define NUM_TYPE_REPEATS 1 | |
| #elif defined(_MSC_VER) | |
| // e.g.: internal::GetTypeNameHelper<TypeName>::Apply | |
| #define FUNCTION_MACRO __FUNCTION__ | |
| #define PREFIX "internal::GetTypeNameHelper<" | |
| #define SUFFIX_1 ">::Apply" | |
| #define SUFFIX_2 "" | |
| #define NUM_TYPE_REPEATS 1 | |
| #else | |
| #error "Not implemented for current compiler" | |
| #endif | |
| template <typename T> | |
| struct GetTypeNameHelper | |
| { | |
| static const char* Apply() | |
| { | |
| static const size_t funcNameLength = sizeof(FUNCTION_MACRO) - 1u; | |
| static const size_t prefixLength = sizeof(PREFIX) - 1u; | |
| static const size_t suffixLength = sizeof(SUFFIX_1) - 1u + sizeof(SUFFIX_2) - 1u; | |
| static const size_t typeLength = (funcNameLength - (prefixLength + suffixLength)) / NUM_TYPE_REPEATS; | |
| static char typeName[typeLength + 1u] = {}; | |
| memcpy(&typeName[0], FUNCTION_MACRO + prefixLength, typeLength); | |
| return typeName; | |
| } | |
| }; | |
| #undef FUNCTION_MACRO | |
| #undef PREFIX | |
| #undef SUFFIX_1 | |
| #undef SUFFIX_2 | |
| #undef NUM_TYPE_REPEATS | |
| template <typename T> | |
| const char* GetTypeName() | |
| { | |
| static const char* typeName = GetTypeNameHelper<T>::Apply(); | |
| return typeName; | |
| } | |
| } // namespace internal | |
| namespace X | |
| { | |
| struct A {}; | |
| namespace Y | |
| { | |
| struct B : X::A {}; | |
| namespace Z | |
| { | |
| struct C : Y::B {}; | |
| } // namespace Z | |
| } // namespace Y | |
| } // namespace X | |
| #include <iostream> | |
| #include <memory> | |
| int main() | |
| { | |
| std::cout << internal::GetTypeName<int>() << '\n'; | |
| std::cout << internal::GetTypeName<X::A>() << '\n'; | |
| std::cout << internal::GetTypeName<X::Y::B>() << '\n'; | |
| std::cout << internal::GetTypeName<X::Y::Z::C>() << '\n'; | |
| std::cout << internal::GetTypeName<std::unique_ptr<float>>() << '\n'; | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment