#include <iostream>
#include <typeinfo>
#include <memory>
#include <cxxabi.h>
#include <tuple>
#include <type_traits>
std::string demangle(std::type_info const& type)
{
static int sta = 0;
return {abi::__cxa_demangle(type.name(), 0, 0, &sta)};
}
// class/struct template
template<typename...Args>
struct Foo
{
Foo(Args...args)
{
std::cout << demangle(typeid(Foo<Args...>)) << std::endl;
}
};
// function template
template<typename...Args>
void f(Args...args)
{
std::cout << sizeof...(Args) << std::endl;
}
template<typename...Args>
struct Bar
{
using tuple = std::tuple<Args...>;
using add_const = std::tuple<typename std::add_const<Args>::type...>;
Bar()
{
std::cout << "tuple : " << demangle(typeid(tuple)) << std::endl;
std::cout << "add_const : " << demangle(typeid(add_const)) << std::endl;
}
};
// pass as arguments
void target()
{
std::cout << "no arguments" << std::endl;
}
void target(int, char const*)
{
std::cout << "2 arguments" << std::endl;
}
template<typename...Args>
void call(Args...args)
{
target(args...);
}
// recursive call
template<typename...Args>
struct Baz;
template<typename T, typename...Args>
struct Baz<T, Args...>
{
void operator()(T head, Args...tail) const
{
std::cout << head << " ";
Baz<Args...>{}(tail...);
}
};
template<>
struct Baz<>
{
void operator()() const
{
std::cout << std::endl;
}
};
template<typename...Args>
void baz(Args...args)
{
Baz<Args...>{}(args...);
}
// integral
template<int...Args>
struct Sum;
template<int N, int...Args>
struct Sum<N, Args...>
{
operator int() const
{
return N + Sum<Args...>{};
}
};
template<>
struct Sum<>
{
operator int() const { return 0; }
};
// N2555: Extending variadic Template Template Parameters
template<typename...Args>
struct eval;
template<template<typename...> class T, typename... U>
struct eval<T<U...> >
{};
template<typename...> class A{};
template<typename T> class B{};
template<typename T1, typename T2> class C{};
template<typename T1, typename T2, typename...> class D{};
int main(int, char*[])
{
// class template
Foo<> x{};
Foo<int> y{0};
Foo<char, int, double> z{ '1', 2, 3.14 };
// function template
f();
f(0);
f('1', 2, 3.14);
// pack operator
Bar<> a{};
Bar<int> b{};
Bar<char, int, double> c{};
// pass as argument
call();
// call(0); // error
call(0, "test");
// call(0, 1); // error
// recursive call
baz();
baz(0);
baz('1', 2, 3.14);
// integral parameter
std::cout << demangle(typeid(Sum<1,2,3,4,5>)) << " = "
<< Sum<1,2,3,4,5>{} << std::endl;
// Variadic Template Template Parameters
eval<A<>> e1{};
eval<B<int>> e2{};
eval<C<int, int>> e3{};
eval<D<int, int>> e4{};
return 0;
}
I2luY2x1ZGUgPGlvc3RyZWFtPgojaW5jbHVkZSA8dHlwZWluZm8+CiNpbmNsdWRlIDxtZW1vcnk+CiNpbmNsdWRlIDxjeHhhYmkuaD4KI2luY2x1ZGUgPHR1cGxlPgojaW5jbHVkZSA8dHlwZV90cmFpdHM+CgpzdGQ6OnN0cmluZyBkZW1hbmdsZShzdGQ6OnR5cGVfaW5mbyBjb25zdCYgdHlwZSkKewoJc3RhdGljIGludCBzdGEgPSAwOwoJcmV0dXJuIHthYmk6Ol9fY3hhX2RlbWFuZ2xlKHR5cGUubmFtZSgpLCAwLCAwLCAmc3RhKX07Cn0KCi8vIGNsYXNzL3N0cnVjdCB0ZW1wbGF0ZQp0ZW1wbGF0ZTx0eXBlbmFtZS4uLkFyZ3M+CnN0cnVjdCBGb28KewoJRm9vKEFyZ3MuLi5hcmdzKQoJewoJCXN0ZDo6Y291dCA8PCBkZW1hbmdsZSh0eXBlaWQoRm9vPEFyZ3MuLi4+KSkgPDwgc3RkOjplbmRsOwoJfQp9OwoKLy8gZnVuY3Rpb24gdGVtcGxhdGUKdGVtcGxhdGU8dHlwZW5hbWUuLi5BcmdzPgp2b2lkIGYoQXJncy4uLmFyZ3MpCnsKCXN0ZDo6Y291dCA8PCBzaXplb2YuLi4oQXJncykgPDwgc3RkOjplbmRsOwp9Cgp0ZW1wbGF0ZTx0eXBlbmFtZS4uLkFyZ3M+CnN0cnVjdCBCYXIKewoJdXNpbmcgdHVwbGUgPSBzdGQ6OnR1cGxlPEFyZ3MuLi4+OwoJdXNpbmcgYWRkX2NvbnN0ID0gc3RkOjp0dXBsZTx0eXBlbmFtZSBzdGQ6OmFkZF9jb25zdDxBcmdzPjo6dHlwZS4uLj47CgoJQmFyKCkKCXsKCQlzdGQ6OmNvdXQgPDwgInR1cGxlICAgICA6ICIgPDwgZGVtYW5nbGUodHlwZWlkKHR1cGxlKSkgPDwgc3RkOjplbmRsOwoJCXN0ZDo6Y291dCA8PCAiYWRkX2NvbnN0IDogIiA8PCBkZW1hbmdsZSh0eXBlaWQoYWRkX2NvbnN0KSkgPDwgc3RkOjplbmRsOwoJfQp9OwoKLy8gcGFzcyBhcyBhcmd1bWVudHMKdm9pZCB0YXJnZXQoKQp7CglzdGQ6OmNvdXQgPDwgIm5vIGFyZ3VtZW50cyIgPDwgc3RkOjplbmRsOwp9IAp2b2lkIHRhcmdldChpbnQsIGNoYXIgY29uc3QqKQp7CglzdGQ6OmNvdXQgPDwgIjIgYXJndW1lbnRzIiA8PCBzdGQ6OmVuZGw7Cn0KCnRlbXBsYXRlPHR5cGVuYW1lLi4uQXJncz4Kdm9pZCBjYWxsKEFyZ3MuLi5hcmdzKQp7Cgl0YXJnZXQoYXJncy4uLik7Cn0KCgovLyByZWN1cnNpdmUgY2FsbAp0ZW1wbGF0ZTx0eXBlbmFtZS4uLkFyZ3M+CnN0cnVjdCBCYXo7Cgp0ZW1wbGF0ZTx0eXBlbmFtZSBULCB0eXBlbmFtZS4uLkFyZ3M+CnN0cnVjdCBCYXo8VCwgQXJncy4uLj4KewoJdm9pZCBvcGVyYXRvcigpKFQgaGVhZCwgQXJncy4uLnRhaWwpIGNvbnN0Cgl7CgkJc3RkOjpjb3V0IDw8IGhlYWQgPDwgIiAiOwoJCUJhejxBcmdzLi4uPnt9KHRhaWwuLi4pOwoJfQp9Owp0ZW1wbGF0ZTw+CnN0cnVjdCBCYXo8Pgp7Cgl2b2lkIG9wZXJhdG9yKCkoKSBjb25zdAoJewoJCXN0ZDo6Y291dCA8PCBzdGQ6OmVuZGw7Cgl9Cn07CnRlbXBsYXRlPHR5cGVuYW1lLi4uQXJncz4Kdm9pZCBiYXooQXJncy4uLmFyZ3MpCnsKICAgCUJhejxBcmdzLi4uPnt9KGFyZ3MuLi4pOwp9CgovLyBpbnRlZ3JhbAp0ZW1wbGF0ZTxpbnQuLi5BcmdzPgpzdHJ1Y3QgU3VtOwoKdGVtcGxhdGU8aW50IE4sIGludC4uLkFyZ3M+CnN0cnVjdCBTdW08TiwgQXJncy4uLj4KewoJb3BlcmF0b3IgaW50KCkgY29uc3QKCXsKCQlyZXR1cm4gTiArIFN1bTxBcmdzLi4uPnt9OwoJfQp9Owp0ZW1wbGF0ZTw+CnN0cnVjdCBTdW08Pgp7CglvcGVyYXRvciBpbnQoKSBjb25zdCB7IHJldHVybiAwOyB9Cn07CgovLyBOMjU1NTogRXh0ZW5kaW5nIHZhcmlhZGljIFRlbXBsYXRlIFRlbXBsYXRlIFBhcmFtZXRlcnMKdGVtcGxhdGU8dHlwZW5hbWUuLi5BcmdzPgpzdHJ1Y3QgZXZhbDsKdGVtcGxhdGU8dGVtcGxhdGU8dHlwZW5hbWUuLi4+IGNsYXNzIFQsIHR5cGVuYW1lLi4uIFU+CnN0cnVjdCBldmFsPFQ8VS4uLj4gPiAKe307CnRlbXBsYXRlPHR5cGVuYW1lLi4uPiBjbGFzcyBBe307CnRlbXBsYXRlPHR5cGVuYW1lIFQ+IGNsYXNzIEJ7fTsKdGVtcGxhdGU8dHlwZW5hbWUgVDEsIHR5cGVuYW1lIFQyPiBjbGFzcyBDe307CnRlbXBsYXRlPHR5cGVuYW1lIFQxLCB0eXBlbmFtZSBUMiwgdHlwZW5hbWUuLi4+IGNsYXNzIER7fTsKCmludCBtYWluKGludCwgY2hhcipbXSkKewoJLy8gY2xhc3MgdGVtcGxhdGUKCUZvbzw+IHh7fTsKCUZvbzxpbnQ+IHl7MH07CglGb288Y2hhciwgaW50LCBkb3VibGU+IHp7ICcxJywgMiwgMy4xNCB9OwoKCS8vIGZ1bmN0aW9uIHRlbXBsYXRlCglmKCk7CglmKDApOwoJZignMScsIDIsIDMuMTQpOwoKCS8vIHBhY2sgb3BlcmF0b3IKCUJhcjw+IGF7fTsKCUJhcjxpbnQ+IGJ7fTsKCUJhcjxjaGFyLCBpbnQsIGRvdWJsZT4gY3t9OwoKCS8vIHBhc3MgYXMgYXJndW1lbnQKCWNhbGwoKTsKCS8vIGNhbGwoMCk7IC8vIGVycm9yCgljYWxsKDAsICJ0ZXN0Iik7CgkvLyBjYWxsKDAsIDEpOyAvLyBlcnJvcgoKCS8vIHJlY3Vyc2l2ZSBjYWxsCgliYXooKTsKCWJheigwKTsKCWJheignMScsIDIsIDMuMTQpOwoKCS8vIGludGVncmFsIHBhcmFtZXRlcgoJc3RkOjpjb3V0IDw8IGRlbWFuZ2xlKHR5cGVpZChTdW08MSwyLDMsNCw1PikpIDw8ICIgPSAiIAoJCQkgIDw8IFN1bTwxLDIsMyw0LDU+e30gPDwgc3RkOjplbmRsOwoKCS8vIFZhcmlhZGljIFRlbXBsYXRlIFRlbXBsYXRlIFBhcmFtZXRlcnMKCWV2YWw8QTw+PiBlMXt9OwoJZXZhbDxCPGludD4+IGUye307CglldmFsPEM8aW50LCBpbnQ+PiBlM3t9OwoJZXZhbDxEPGludCwgaW50Pj4gZTR7fTsKCglyZXR1cm4gMDsKfQ==