#include <iostream>
#include <typeinfo>
#include <type_traits>
template<class...>
struct type_list {};
template<class L, template<class> class F>
struct map /* undefined */;
template<class... Contents, template<class> class F>
struct map<type_list<Contents...>, F> {
using type = type_list<typename F<Contents>::type...>;
};
template<class L, template<class> class F>
using map_t = typename map<L, F>::type;
template<class L1, class L2>
struct concatenate /* undefined */;
template<class... Contents1, class... Contents2>
struct concatenate<type_list<Contents1...>, type_list<Contents2...>> {
using type = type_list<Contents1..., Contents2...>;
};
template<class L1, class L2>
using concatenate_t = typename concatenate<L1, L2>::type;
template<int Low, int High, class = void>
struct range;
template<int Low, int High>
using range_t = typename range<Low, High>::type;
template<int Low, int High, class>
struct range {
using type =
concatenate_t<range_t<Low, (Low+High)/2>, range_t<(Low+High)/2, High>>;
};
template<int Low>
struct range<Low, Low, void> { using type = type_list<>; };
template<int Low, int High>
struct range<Low, High, typename std::enable_if<High - Low == 1>::type> {
using type = type_list<std::integral_constant<int, Low>>;
};
template<int N>
struct A {};
template<class N>
struct make_A {
using type = A<N::value>;
};
using my_list_of_A = map_t<range_t<0, 16>, make_A>;
int main() {
std::cout << typeid(my_list_of_A).name() << std::endl;
// you may pass that to c++filt
return 0;
}
I2luY2x1ZGUgPGlvc3RyZWFtPgojaW5jbHVkZSA8dHlwZWluZm8+CiNpbmNsdWRlIDx0eXBlX3RyYWl0cz4KCnRlbXBsYXRlPGNsYXNzLi4uPgpzdHJ1Y3QgdHlwZV9saXN0IHt9OwoKdGVtcGxhdGU8Y2xhc3MgTCwgdGVtcGxhdGU8Y2xhc3M+IGNsYXNzIEY+CnN0cnVjdCBtYXAgLyogdW5kZWZpbmVkICovOwoKdGVtcGxhdGU8Y2xhc3MuLi4gQ29udGVudHMsIHRlbXBsYXRlPGNsYXNzPiBjbGFzcyBGPgpzdHJ1Y3QgbWFwPHR5cGVfbGlzdDxDb250ZW50cy4uLj4sIEY+IHsKCXVzaW5nIHR5cGUgPSB0eXBlX2xpc3Q8dHlwZW5hbWUgRjxDb250ZW50cz46OnR5cGUuLi4+Owp9OwoKdGVtcGxhdGU8Y2xhc3MgTCwgdGVtcGxhdGU8Y2xhc3M+IGNsYXNzIEY+CnVzaW5nIG1hcF90ID0gdHlwZW5hbWUgbWFwPEwsIEY+Ojp0eXBlOwoKdGVtcGxhdGU8Y2xhc3MgTDEsIGNsYXNzIEwyPgpzdHJ1Y3QgY29uY2F0ZW5hdGUgLyogdW5kZWZpbmVkICovOwoKdGVtcGxhdGU8Y2xhc3MuLi4gQ29udGVudHMxLCBjbGFzcy4uLiBDb250ZW50czI+CnN0cnVjdCBjb25jYXRlbmF0ZTx0eXBlX2xpc3Q8Q29udGVudHMxLi4uPiwgdHlwZV9saXN0PENvbnRlbnRzMi4uLj4+IHsKCXVzaW5nIHR5cGUgPSB0eXBlX2xpc3Q8Q29udGVudHMxLi4uLCBDb250ZW50czIuLi4+Owp9OwoKdGVtcGxhdGU8Y2xhc3MgTDEsIGNsYXNzIEwyPgp1c2luZyBjb25jYXRlbmF0ZV90ID0gdHlwZW5hbWUgY29uY2F0ZW5hdGU8TDEsIEwyPjo6dHlwZTsKCnRlbXBsYXRlPGludCBMb3csIGludCBIaWdoLCBjbGFzcyA9IHZvaWQ+CnN0cnVjdCByYW5nZTsKCnRlbXBsYXRlPGludCBMb3csIGludCBIaWdoPgp1c2luZyByYW5nZV90ID0gdHlwZW5hbWUgcmFuZ2U8TG93LCBIaWdoPjo6dHlwZTsKCnRlbXBsYXRlPGludCBMb3csIGludCBIaWdoLCBjbGFzcz4Kc3RydWN0IHJhbmdlIHsKCXVzaW5nIHR5cGUgPQoJCWNvbmNhdGVuYXRlX3Q8cmFuZ2VfdDxMb3csIChMb3crSGlnaCkvMj4sIHJhbmdlX3Q8KExvdytIaWdoKS8yLCBIaWdoPj47Cn07Cgp0ZW1wbGF0ZTxpbnQgTG93PgpzdHJ1Y3QgcmFuZ2U8TG93LCBMb3csIHZvaWQ+IHsgdXNpbmcgdHlwZSA9IHR5cGVfbGlzdDw+OyB9OwoKdGVtcGxhdGU8aW50IExvdywgaW50IEhpZ2g+CnN0cnVjdCByYW5nZTxMb3csIEhpZ2gsIHR5cGVuYW1lIHN0ZDo6ZW5hYmxlX2lmPEhpZ2ggLSBMb3cgPT0gMT46OnR5cGU+IHsKCXVzaW5nIHR5cGUgPSB0eXBlX2xpc3Q8c3RkOjppbnRlZ3JhbF9jb25zdGFudDxpbnQsIExvdz4+OyAKfTsKCnRlbXBsYXRlPGludCBOPgpzdHJ1Y3QgQSB7fTsKCnRlbXBsYXRlPGNsYXNzIE4+CnN0cnVjdCBtYWtlX0EgewoJdXNpbmcgdHlwZSA9IEE8Tjo6dmFsdWU+Owp9OwoKdXNpbmcgbXlfbGlzdF9vZl9BID0gbWFwX3Q8cmFuZ2VfdDwwLCAxNj4sIG1ha2VfQT47CmludCBtYWluKCkgewoJc3RkOjpjb3V0IDw8IHR5cGVpZChteV9saXN0X29mX0EpLm5hbWUoKSA8PCBzdGQ6OmVuZGw7CgkvLyB5b3UgbWF5IHBhc3MgdGhhdCB0byBjKytmaWx0CglyZXR1cm4gMDsKfQ==