#include <iostream>
#include <typeinfo>
#include <cstdlib>
#include <vector>
#include <algorithm>
#include <iterator>
#include <utility>
#include <cxxabi.h>
std::string dem(const char* mang)
{
int status = -4; // some arbitrary value to eliminate the compiler warning
std::string ret;
char* d = abi::__cxa_demangle(mang, NULL, NULL, &status);
if (status == 0 && d) ret = d;
if (d) std::free(d);
return (status == 0 ? ret : mang);
}
template <typename Ret, typename ... Args>
void func (Ret (*f)(Args...))
{
std::cout << dem(typeid(f).name()) << std::endl;
std::vector<std::string> types {dem(typeid(Args).name())...};
std::copy(std::begin(types), std::end(types), std::ostream_iterator<std::string>(std::cout, "\n"));
}
int foo (int a, int* b, double** c) {}
int main ()
{
func(foo);
}
I2luY2x1ZGUgPGlvc3RyZWFtPgojaW5jbHVkZSA8dHlwZWluZm8+CiNpbmNsdWRlIDxjc3RkbGliPgojaW5jbHVkZSA8dmVjdG9yPgojaW5jbHVkZSA8YWxnb3JpdGhtPgojaW5jbHVkZSA8aXRlcmF0b3I+CiNpbmNsdWRlIDx1dGlsaXR5PgoKI2luY2x1ZGUgPGN4eGFiaS5oPgoKc3RkOjpzdHJpbmcgZGVtKGNvbnN0IGNoYXIqIG1hbmcpCnsKICAgIGludCBzdGF0dXMgPSAtNDsgLy8gc29tZSBhcmJpdHJhcnkgdmFsdWUgdG8gZWxpbWluYXRlIHRoZSBjb21waWxlciB3YXJuaW5nCiAgICBzdGQ6OnN0cmluZyByZXQ7CiAgICBjaGFyKiBkID0gYWJpOjpfX2N4YV9kZW1hbmdsZShtYW5nLCBOVUxMLCBOVUxMLCAmc3RhdHVzKTsKICAgIGlmIChzdGF0dXMgPT0gMCAmJiBkKSByZXQgPSBkOwogICAgaWYgKGQpIHN0ZDo6ZnJlZShkKTsKICAgIHJldHVybiAoc3RhdHVzID09IDAgPyByZXQgOiBtYW5nKTsKfQoKCnRlbXBsYXRlIDx0eXBlbmFtZSBSZXQsIHR5cGVuYW1lIC4uLiBBcmdzPgp2b2lkIGZ1bmMgKFJldCAoKmYpKEFyZ3MuLi4pKQp7CiAgICBzdGQ6OmNvdXQgPDwgZGVtKHR5cGVpZChmKS5uYW1lKCkpIDw8IHN0ZDo6ZW5kbDsKICAgIHN0ZDo6dmVjdG9yPHN0ZDo6c3RyaW5nPiB0eXBlcyB7ZGVtKHR5cGVpZChBcmdzKS5uYW1lKCkpLi4ufTsKICAgIHN0ZDo6Y29weShzdGQ6OmJlZ2luKHR5cGVzKSwgc3RkOjplbmQodHlwZXMpLCBzdGQ6Om9zdHJlYW1faXRlcmF0b3I8c3RkOjpzdHJpbmc+KHN0ZDo6Y291dCwgIlxuIikpOwp9CgppbnQgZm9vIChpbnQgYSwgaW50KiBiLCBkb3VibGUqKiBjKSB7fQoKaW50IG1haW4gKCkKewogICAgZnVuYyhmb28pOwp9Cg==