#include <iostream>
#include <string>
template <typename>
struct typeinfo;
#define DEFINE_TYPEINFO_0(t, v) \
template <> \
struct typeinfo<t> \
{ \
static std::string name() { return v; } \
};
#define DEFINE_TYPEINFO_1(t, v) \
template <typename T> \
struct typeinfo<t> \
{ \
static std::string name() { return v; } \
};
#define TYPEINFO(x) typeinfo<x>::name()
DEFINE_TYPEINFO_0(int, "int")
DEFINE_TYPEINFO_0(float, "float")
DEFINE_TYPEINFO_1(T*, TYPEINFO(T) + "*")
namespace foo
{
struct bar
{};
}
DEFINE_TYPEINFO_0(foo::bar, "foo::bar")
int main()
{
std::cout << TYPEINFO(int) << '\n';
std::cout << TYPEINFO(float*) << '\n';
std::cout << TYPEINFO(foo::bar) << '\n';
}
I2luY2x1ZGUgPGlvc3RyZWFtPgojaW5jbHVkZSA8c3RyaW5nPgoKdGVtcGxhdGUgPHR5cGVuYW1lPgpzdHJ1Y3QgdHlwZWluZm87CgojZGVmaW5lIERFRklORV9UWVBFSU5GT18wKHQsIHYpIFwKICAgICAgICB0ZW1wbGF0ZSA8PiBcCiAgICAgICAgc3RydWN0IHR5cGVpbmZvPHQ+IFwKICAgICAgICB7IFwKICAgICAgICAgICAgICAgIHN0YXRpYyBzdGQ6OnN0cmluZyBuYW1lKCkgeyByZXR1cm4gdjsgfSBcCiAgICAgICAgfTsKCiNkZWZpbmUgREVGSU5FX1RZUEVJTkZPXzEodCwgdikgXAogICAgICAgIHRlbXBsYXRlIDx0eXBlbmFtZSBUPiBcCiAgICAgICAgc3RydWN0IHR5cGVpbmZvPHQ+IFwKICAgICAgICB7IFwKICAgICAgICAgICAgICAgIHN0YXRpYyBzdGQ6OnN0cmluZyBuYW1lKCkgeyByZXR1cm4gdjsgfSBcCiAgICAgICAgfTsKCiNkZWZpbmUgVFlQRUlORk8oeCkgdHlwZWluZm88eD46Om5hbWUoKQoKREVGSU5FX1RZUEVJTkZPXzAoaW50LCAiaW50IikKREVGSU5FX1RZUEVJTkZPXzAoZmxvYXQsICJmbG9hdCIpCgpERUZJTkVfVFlQRUlORk9fMShUKiwgVFlQRUlORk8oVCkgKyAiKiIpCgpuYW1lc3BhY2UgZm9vCnsKICAgICAgICBzdHJ1Y3QgYmFyCiAgICAgICAge307Cn0KCkRFRklORV9UWVBFSU5GT18wKGZvbzo6YmFyLCAiZm9vOjpiYXIiKQoKaW50IG1haW4oKQp7CiAgICAgICAgc3RkOjpjb3V0IDw8IFRZUEVJTkZPKGludCkgPDwgJ1xuJzsKICAgICAgICBzdGQ6OmNvdXQgPDwgVFlQRUlORk8oZmxvYXQqKSA8PCAnXG4nOwogICAgICAgIHN0ZDo6Y291dCA8PCBUWVBFSU5GTyhmb286OmJhcikgPDwgJ1xuJzsKfQ==