Created
May 22, 2023 19:06
-
-
Save Len42/62038fd328be6af69ba7245f28531c3f to your computer and use it in GitHub Desktop.
ShowDecl: Pretty-print an expression's decltype (C++)
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
// 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