Skip to content

Instantly share code, notes, and snippets.

@melak47
Created June 14, 2019 12:56
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save melak47/149f89536c76279521ca8be2fb51a531 to your computer and use it in GitHub Desktop.
Save melak47/149f89536c76279521ca8be2fb51a531 to your computer and use it in GitHub Desktop.
Obtain type name as constexpr string
#include <string_view>
#include <stdexcept>
namespace detail {
template<typename T>
constexpr const char* type_name() {
#if defined(__GNUC__) || defined(__clang__)
return __PRETTY_FUNCTION__;
#elif defined(_MSC_VER)
return __FUNCSIG__;
#else
#error unknown compiler
#endif
}
}
template<typename T>
constexpr std::string_view type_name() {
using namespace std::literals;
constexpr std::string_view funcsig = detail::type_name<T>();
#if defined(__GNUC__) || defined(__clang__)
constexpr auto start_bit = "T = "sv;
constexpr auto end_bit = "]"sv;
#elif defined(_MSC_VER)
constexpr auto start_bit = "detail::type_name<"sv;
constexpr auto end_bit = ">("sv;
#else
#error unknown compiler
#endif
constexpr auto start = funcsig.find(start_bit);
constexpr auto end = funcsig.rfind(end_bit);
if constexpr(start == funcsig.npos || end == funcsig.npos || end <= start) {
throw std::runtime_error("__PRETTY_FUNCTION__/__FUNCSIG__ string does not meet expectation");
}
return funcsig.substr(start + start_bit.size(), end - start - start_bit.size());
}
#include <iostream>
#include <variant>
template<auto V, typename... T>
struct foo {};
std::string_view fun(std::variant<int, float>);
struct bar {
void foo();
};
int main() {
try {
constexpr std::size_t T = 4;
auto name = type_name<foo<&fun, void(int), int[T], foo<&bar::foo>>>();
std::cout << name << "\n";
}
catch (const std::exception& e) {
std::cerr << "error: " << e.what() << "\n";
return 1;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment