Skip to content

Instantly share code, notes, and snippets.

@Len42
Created May 22, 2023 19:06
Show Gist options
  • Save Len42/62038fd328be6af69ba7245f28531c3f to your computer and use it in GitHub Desktop.
Save Len42/62038fd328be6af69ba7245f28531c3f to your computer and use it in GitHub Desktop.
ShowDecl: Pretty-print an expression's decltype (C++)
// ShowDecl: Pretty-print an expression's decltype.
// Works with popular C++20 compilers.
// by Len Popp
// ref: Arthur O'Dwyer https://quuxplusone.github.io/blog/2018/08/22/puts-pretty-function/
#include <string>
#include <string_view>
#include <utility>
#include <iostream>
#define SHOW_DECL(expr) \
std::cout << "decltype(" #expr ") == " << getDecl<decltype(expr)>() << '\n'
template<typename T>
consteval std::string_view getDecl()
{
#if defined(__clang__)
auto declC = __PRETTY_FUNCTION__;
std::string_view head = "[T = ";
std::string_view tail = "]";
#elif defined(__GNUC__)
auto declC = __PRETTY_FUNCTION__;
std::string_view head = "[with T = ";
std::string_view tail = "; std::string_view = ";
#elif defined(_MSC_VER)
auto declC = __FUNCSIG__;
std::string_view head = "getDecl<";
std::string_view tail = ">(void)";
#else
#error Compiler not supported
#endif
// remove boilerplate text
std::string_view decl = declC;
size_t c1 = decl.find(head);
size_t c2 = decl.rfind(tail);
if (c1 == std::string::npos || c2 == std::string::npos || c1 > c2) {
return decl; // just in case
} else {
c1 += head.length();
return decl.substr(c1, c2 - c1);
}
}
// Examples
void showCallable(auto func)
{
SHOW_DECL(func);
SHOW_DECL(func(0));
}
auto sub(int i)
{
return std::tuple("word", i);
}
int main()
{
SHOW_DECL(0);
showCallable([](int i) { return std::tuple("word", i); });
showCallable(sub);
}
/* Output when compiled with MSC:
decltype(0) == int
decltype(func) == class main::<lambda_1>
decltype(func(0)) == class std::tuple<char const *,int>
decltype(func) == class std::tuple<char const *,int>(__cdecl *)(int)
decltype(func(0)) == class std::tuple<char const *,int>
*/
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment