#include <typeinfo>
#include <iostream>
template <typename... Elements>
struct type_list
{
};
template <typename TypeList>
struct type_list_first_element
{
};
template <typename FirstElement, typename... OtherElements>
struct type_list_first_element<type_list<FirstElement, OtherElements...>>
{
typedef FirstElement type;
};
template <typename TypeList>
struct type_list_last_element;
template <typename FirstElement, typename... OtherElements>
struct type_list_last_element<type_list<FirstElement, OtherElements...>>
{
typedef typename type_list_last_element<type_list<OtherElements...>>::type type;
};
template <typename LastElement>
struct type_list_last_element<type_list<LastElement>>
{
typedef LastElement type;
};
int main()
{
typedef type_list<int, float, char> list;
typedef type_list_first_element<list>::type first;
std::cout << typeid(first).name() << std::endl;
typedef type_list_last_element<list>::type last;
std::cout << typeid(last).name() << std::endl;
return 0;
}
I2luY2x1ZGUgPHR5cGVpbmZvPgojaW5jbHVkZSA8aW9zdHJlYW0+Cgp0ZW1wbGF0ZSA8dHlwZW5hbWUuLi4gRWxlbWVudHM+CnN0cnVjdCB0eXBlX2xpc3QKewp9OwoKdGVtcGxhdGUgPHR5cGVuYW1lIFR5cGVMaXN0PgpzdHJ1Y3QgdHlwZV9saXN0X2ZpcnN0X2VsZW1lbnQKewp9OwoKdGVtcGxhdGUgPHR5cGVuYW1lIEZpcnN0RWxlbWVudCwgdHlwZW5hbWUuLi4gT3RoZXJFbGVtZW50cz4Kc3RydWN0IHR5cGVfbGlzdF9maXJzdF9lbGVtZW50PHR5cGVfbGlzdDxGaXJzdEVsZW1lbnQsIE90aGVyRWxlbWVudHMuLi4+Pgp7CiAgICB0eXBlZGVmIEZpcnN0RWxlbWVudCB0eXBlOwp9OwoKdGVtcGxhdGUgPHR5cGVuYW1lIFR5cGVMaXN0PgpzdHJ1Y3QgdHlwZV9saXN0X2xhc3RfZWxlbWVudDsKCnRlbXBsYXRlIDx0eXBlbmFtZSBGaXJzdEVsZW1lbnQsIHR5cGVuYW1lLi4uIE90aGVyRWxlbWVudHM+CnN0cnVjdCB0eXBlX2xpc3RfbGFzdF9lbGVtZW50PHR5cGVfbGlzdDxGaXJzdEVsZW1lbnQsIE90aGVyRWxlbWVudHMuLi4+Pgp7CiAgICB0eXBlZGVmIHR5cGVuYW1lIHR5cGVfbGlzdF9sYXN0X2VsZW1lbnQ8dHlwZV9saXN0PE90aGVyRWxlbWVudHMuLi4+Pjo6dHlwZSB0eXBlOwp9Owp0ZW1wbGF0ZSA8dHlwZW5hbWUgTGFzdEVsZW1lbnQ+CnN0cnVjdCB0eXBlX2xpc3RfbGFzdF9lbGVtZW50PHR5cGVfbGlzdDxMYXN0RWxlbWVudD4+CnsKICAgIHR5cGVkZWYgTGFzdEVsZW1lbnQgdHlwZTsKfTsKCmludCBtYWluKCkKewogICB0eXBlZGVmIHR5cGVfbGlzdDxpbnQsIGZsb2F0LCBjaGFyPiBsaXN0OwogICB0eXBlZGVmIHR5cGVfbGlzdF9maXJzdF9lbGVtZW50PGxpc3Q+Ojp0eXBlIGZpcnN0OwogICBzdGQ6OmNvdXQgPDwgdHlwZWlkKGZpcnN0KS5uYW1lKCkgPDwgc3RkOjplbmRsOwogICB0eXBlZGVmIHR5cGVfbGlzdF9sYXN0X2VsZW1lbnQ8bGlzdD46OnR5cGUgbGFzdDsKICAgc3RkOjpjb3V0IDw8IHR5cGVpZChsYXN0KS5uYW1lKCkgPDwgc3RkOjplbmRsOwogICByZXR1cm4gMDsKfQ==