#include <iostream>
#include <typeinfo>
#include <cxxabi.h>
using namespace std;
// demangle from https://stackoverflow.com/questions/11347373/issue-with-type-name-demangling
string demangle(const char* mangledName) {
int status;
char* result = abi::__cxa_demangle(mangledName, nullptr, nullptr, &status);
switch(status) {
case -1:
cerr << "Out of memory!" << endl;
exit(1);
case -2:
return mangledName;
case -3:
return mangledName;
}
string name = result;
free(result);
return name;
}
//
// START //
template <typename...>
struct type_list{};
template<template <typename...> typename tmpl>
struct tmpl_c
{
template <typename...Ts> using type = tmpl<Ts...>;
};
template<typename> struct template_of;
template <template <typename...> typename tmpl, typename... Ts>
struct template_of<tmpl<Ts...>>{
using type = tmpl_c<tmpl>;
};
template <typename T>
struct first{};
template <typename T>
struct second
{
// 'second' here refers to second<int>
using test = second;
// 'second' here refers to the template second
// is this due to the context? ie that the tmpl_c is expecting a template not a concrete type?
using types = type_list<tmpl_c<first>, tmpl_c<second> >;
// second here refers to the concrete type 'second<int>'
// this workaround is needed for visual studio as it seems second always
// refers to the concrete type, not the template.
using types2 = type_list<tmpl_c<first>, typename template_of<second>::type >;
};
template <typename...Ts>
void print_types(type_list<Ts...>)
{
using do_ = int[];
(void)do_{0,
(std::cout << demangle(typeid(Ts).name()) << std::endl,0)
...,0};
}
int main() {
std::cout << demangle(typeid(second<int>::test).name()) << std::endl;
print_types(second<int>::types());
print_types(second<int>::types2());
}
I2luY2x1ZGUgPGlvc3RyZWFtPgojaW5jbHVkZSA8dHlwZWluZm8+CiNpbmNsdWRlIDxjeHhhYmkuaD4KdXNpbmcgbmFtZXNwYWNlIHN0ZDsKCi8vIGRlbWFuZ2xlIGZyb20gaHR0cHM6Ly9zdGFja292ZXJmbG93LmNvbS9xdWVzdGlvbnMvMTEzNDczNzMvaXNzdWUtd2l0aC10eXBlLW5hbWUtZGVtYW5nbGluZwpzdHJpbmcgZGVtYW5nbGUoY29uc3QgY2hhciogbWFuZ2xlZE5hbWUpIHsKICAgIGludCBzdGF0dXM7CiAgICBjaGFyKiByZXN1bHQgPSBhYmk6Ol9fY3hhX2RlbWFuZ2xlKG1hbmdsZWROYW1lLCBudWxscHRyLCBudWxscHRyLCAmc3RhdHVzKTsKICAgIHN3aXRjaChzdGF0dXMpIHsKICAgIGNhc2UgLTE6CiAgICAgICAgY2VyciA8PCAiT3V0IG9mIG1lbW9yeSEiIDw8IGVuZGw7CiAgICAgICAgZXhpdCgxKTsKICAgIGNhc2UgLTI6CiAgICAgICAgcmV0dXJuIG1hbmdsZWROYW1lOwogICAgY2FzZSAtMzogCiAgICAgICAgcmV0dXJuIG1hbmdsZWROYW1lOwogICAgfQogICAgc3RyaW5nIG5hbWUgPSByZXN1bHQ7CiAgICBmcmVlKHJlc3VsdCk7CiAgICByZXR1cm4gbmFtZTsKfQovLwoKLy8gU1RBUlQgLy8KCgp0ZW1wbGF0ZSA8dHlwZW5hbWUuLi4+CnN0cnVjdCB0eXBlX2xpc3R7fTsKCnRlbXBsYXRlPHRlbXBsYXRlIDx0eXBlbmFtZS4uLj4gdHlwZW5hbWUgdG1wbD4gCnN0cnVjdCB0bXBsX2MKewoJdGVtcGxhdGUgPHR5cGVuYW1lLi4uVHM+IHVzaW5nIHR5cGUgPSB0bXBsPFRzLi4uPjsKfTsKCnRlbXBsYXRlPHR5cGVuYW1lPiBzdHJ1Y3QgdGVtcGxhdGVfb2Y7CnRlbXBsYXRlIDx0ZW1wbGF0ZSA8dHlwZW5hbWUuLi4+IHR5cGVuYW1lIHRtcGwsIHR5cGVuYW1lLi4uIFRzPgpzdHJ1Y3QgdGVtcGxhdGVfb2Y8dG1wbDxUcy4uLj4+ewogICAgdXNpbmcgdHlwZSA9IHRtcGxfYzx0bXBsPjsgCn07CgoKdGVtcGxhdGUgPHR5cGVuYW1lIFQ+CnN0cnVjdCBmaXJzdHt9OwoKCnRlbXBsYXRlIDx0eXBlbmFtZSBUPgpzdHJ1Y3Qgc2Vjb25kCnsKCS8vICdzZWNvbmQnIGhlcmUgcmVmZXJzIHRvIHNlY29uZDxpbnQ+Cgl1c2luZyB0ZXN0ID0gc2Vjb25kOyAKCQoJLy8gJ3NlY29uZCcgaGVyZSByZWZlcnMgdG8gdGhlIHRlbXBsYXRlIHNlY29uZAoJLy8gaXMgdGhpcyBkdWUgdG8gdGhlIGNvbnRleHQ/IGllIHRoYXQgdGhlIHRtcGxfYyBpcyBleHBlY3RpbmcgYSB0ZW1wbGF0ZSBub3QgYSBjb25jcmV0ZSB0eXBlPwoJdXNpbmcgdHlwZXMgPSB0eXBlX2xpc3Q8dG1wbF9jPGZpcnN0PiwgdG1wbF9jPHNlY29uZD4gPjsgCgkKCQoJLy8gc2Vjb25kIGhlcmUgcmVmZXJzIHRvIHRoZSBjb25jcmV0ZSB0eXBlICdzZWNvbmQ8aW50PicKCS8vIHRoaXMgd29ya2Fyb3VuZCBpcyBuZWVkZWQgZm9yIHZpc3VhbCBzdHVkaW8gYXMgaXQgc2VlbXMgc2Vjb25kIGFsd2F5cyAKCS8vIHJlZmVycyB0byB0aGUgY29uY3JldGUgdHlwZSwgbm90IHRoZSB0ZW1wbGF0ZS4KCXVzaW5nIHR5cGVzMiA9IHR5cGVfbGlzdDx0bXBsX2M8Zmlyc3Q+LCB0eXBlbmFtZSB0ZW1wbGF0ZV9vZjxzZWNvbmQ+Ojp0eXBlID47IAp9OwoKdGVtcGxhdGUgPHR5cGVuYW1lLi4uVHM+CnZvaWQgcHJpbnRfdHlwZXModHlwZV9saXN0PFRzLi4uPikKewoJdXNpbmcgZG9fID0gaW50W107Cgkodm9pZClkb197MCwKCQkoc3RkOjpjb3V0IDw8IGRlbWFuZ2xlKHR5cGVpZChUcykubmFtZSgpKSA8PCBzdGQ6OmVuZGwsMCkKCS4uLiwwfTsKfQoKaW50IG1haW4oKSB7CgkKCQoJc3RkOjpjb3V0IDw8IGRlbWFuZ2xlKHR5cGVpZChzZWNvbmQ8aW50Pjo6dGVzdCkubmFtZSgpKSA8PCBzdGQ6OmVuZGw7CglwcmludF90eXBlcyhzZWNvbmQ8aW50Pjo6dHlwZXMoKSk7CglwcmludF90eXBlcyhzZWNvbmQ8aW50Pjo6dHlwZXMyKCkpOwp9