Skip to content

Instantly share code, notes, and snippets.

@niXman
Last active December 25, 2022 08:49
Show Gist options
  • Save niXman/febe1fe53c7d98693f284a0e1a9ba063 to your computer and use it in GitHub Desktop.
Save niXman/febe1fe53c7d98693f284a0e1a9ba063 to your computer and use it in GitHub Desktop.
constexpr type_name()
#include <iostream>
#include <array>
#include <utility>
#include <string_view>
template<std::size_t...Idxs>
constexpr auto substring_as_array(std::string_view str, std::index_sequence<Idxs...>) {
return std::array{str[Idxs]..., '\n'};
}
template <typename T>
constexpr auto type_name_array() {
#if defined(__clang__)
constexpr auto prefix = std::string_view{"[T = "};
constexpr auto suffix = std::string_view{"]"};
constexpr auto function = std::string_view{__PRETTY_FUNCTION__};
#elif defined(__GNUC__)
constexpr auto prefix = std::string_view{"with T = "};
constexpr auto suffix = std::string_view{"]"};
constexpr auto function = std::string_view{__PRETTY_FUNCTION__};
#elif defined(_MSC_VER)
constexpr auto prefix = std::string_view{"type_name_array<"};
constexpr auto suffix = std::string_view{">(void)"};
constexpr auto function = std::string_view{__FUNCSIG__};
#else
# error Unsupported compiler
#endif
constexpr auto double_colon = std::string_view{"::"};
constexpr auto start = function.find(prefix) + prefix.size();
constexpr auto end = function.rfind(suffix);
static_assert(start < end);
constexpr auto name = function.substr(start, (end - start));
constexpr auto double_colon_pos = name.find(double_colon);
if constexpr ( double_colon_pos != std::string_view::npos ) {
constexpr auto name2 = name.substr(double_colon_pos + double_colon.size()
,end - (double_colon_pos + double_colon.size()));
return substring_as_array(name2, std::make_index_sequence<name2.size()>{});
}
return substring_as_array(name, std::make_index_sequence<name.size()>{});
}
template <typename T>
struct type_name_holder {
static inline constexpr auto value = type_name_array<T>();
};
template <typename T>
constexpr auto type_name() -> std::string_view {
constexpr auto& value = type_name_holder<T>::value;
return std::string_view{value.data(), value.size()};
}
int main()
{
std::cout << type_name<int>() << std::endl;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment