Skip to content

Instantly share code, notes, and snippets.

@neugen86
Created July 17, 2025 10:21
Show Gist options
  • Select an option

  • Save neugen86/b65370d3a55b9690b7e38de7bed86776 to your computer and use it in GitHub Desktop.

Select an option

Save neugen86/b65370d3a55b9690b7e38de7bed86776 to your computer and use it in GitHub Desktop.
#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