using size_type = unsigned;
using index_type = size_type;
template<typename T>
using eval = typename T::type;
template<index_type ... args>
struct index_list
{
using type = index_list;
};
template <typename, typename> struct multiply;
template <index_type... indices, index_type... tail>
struct multiply<index_list<indices...>,
index_list<tail... >> : index_list<indices..., (sizeof...(indices)+indices)...,
(2*sizeof...(indices)+indices)...,
(3*sizeof...(indices)+indices)...,
(4*sizeof...(indices)+tail)...> {};
template <index_type N>
struct make_index_list :
multiply< eval<make_index_list<N/4>>,
eval<make_index_list<N%4>> > {};
template <> struct make_index_list<3> : index_list<0, 1, 2> {};
template <> struct make_index_list<2> : index_list<0, 1> {};
template <> struct make_index_list<1> : index_list<0> {};
template <> struct make_index_list<0> : index_list<> {};
template< void(*)(index_type),
size_type len,
typename = eval<make_index_list<len>>> struct repeat;
template< void(*ptr)(index_type), size_type len,
index_type... indices >
struct repeat<ptr, len, index_list<indices...>>
{
static void run()
{
bool _[]{ (ptr(indices), false)... };
}
};
#include <iostream>
void foo(index_type i)
{
std::cout << i << '\n';
}
int main()
{
repeat<foo, 7>::run();
}
dXNpbmcgc2l6ZV90eXBlID0gdW5zaWduZWQ7Cgp1c2luZyBpbmRleF90eXBlID0gc2l6ZV90eXBlOwoKdGVtcGxhdGU8dHlwZW5hbWUgVD4KdXNpbmcgZXZhbCA9IHR5cGVuYW1lIFQ6OnR5cGU7Cgp0ZW1wbGF0ZTxpbmRleF90eXBlIC4uLiBhcmdzPgpzdHJ1Y3QgaW5kZXhfbGlzdAp7Cgl1c2luZyB0eXBlID0gaW5kZXhfbGlzdDsKfTsKCnRlbXBsYXRlIDx0eXBlbmFtZSwgdHlwZW5hbWU+IHN0cnVjdCBtdWx0aXBseTsKdGVtcGxhdGUgPGluZGV4X3R5cGUuLi4gaW5kaWNlcywgaW5kZXhfdHlwZS4uLiB0YWlsPgpzdHJ1Y3QgbXVsdGlwbHk8aW5kZXhfbGlzdDxpbmRpY2VzLi4uPiwKICAgICAgICAgICAgICAgIGluZGV4X2xpc3Q8dGFpbC4uLiAgID4+IDogaW5kZXhfbGlzdDxpbmRpY2VzLi4uLCAoc2l6ZW9mLi4uKGluZGljZXMpK2luZGljZXMpLi4uLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICgyKnNpemVvZi4uLihpbmRpY2VzKStpbmRpY2VzKS4uLiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoMypzaXplb2YuLi4oaW5kaWNlcykraW5kaWNlcykuLi4sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKDQqc2l6ZW9mLi4uKGluZGljZXMpK3RhaWwpLi4uPiB7fTsKdGVtcGxhdGUgPGluZGV4X3R5cGUgTj4Kc3RydWN0IG1ha2VfaW5kZXhfbGlzdCA6CgltdWx0aXBseTwgZXZhbDxtYWtlX2luZGV4X2xpc3Q8Ti80Pj4sCgkgICAgICAgICAgZXZhbDxtYWtlX2luZGV4X2xpc3Q8TiU0Pj4gPiB7fTsKCnRlbXBsYXRlIDw+IHN0cnVjdCBtYWtlX2luZGV4X2xpc3Q8Mz4gOiBpbmRleF9saXN0PDAsIDEsIDI+IHt9Owp0ZW1wbGF0ZSA8PiBzdHJ1Y3QgbWFrZV9pbmRleF9saXN0PDI+IDogaW5kZXhfbGlzdDwwLCAxPiB7fTsKdGVtcGxhdGUgPD4gc3RydWN0IG1ha2VfaW5kZXhfbGlzdDwxPiA6IGluZGV4X2xpc3Q8MD4ge307CnRlbXBsYXRlIDw+IHN0cnVjdCBtYWtlX2luZGV4X2xpc3Q8MD4gOiBpbmRleF9saXN0PD4ge307Cgp0ZW1wbGF0ZTwgdm9pZCgqKShpbmRleF90eXBlKSwKICAgICAgICAgIHNpemVfdHlwZSBsZW4sCiAgICAgICAgICB0eXBlbmFtZSA9IGV2YWw8bWFrZV9pbmRleF9saXN0PGxlbj4+PiBzdHJ1Y3QgcmVwZWF0OwoKdGVtcGxhdGU8IHZvaWQoKnB0cikoaW5kZXhfdHlwZSksIHNpemVfdHlwZSBsZW4sCiAgICAgICAgICBpbmRleF90eXBlLi4uIGluZGljZXMgPgpzdHJ1Y3QgcmVwZWF0PHB0ciwgbGVuLCBpbmRleF9saXN0PGluZGljZXMuLi4+Pgp7CglzdGF0aWMgdm9pZCBydW4oKQoJewoJCWJvb2wgX1tdeyAocHRyKGluZGljZXMpLCBmYWxzZSkuLi4gfTsKCX0KfTsKCiNpbmNsdWRlIDxpb3N0cmVhbT4KCnZvaWQgZm9vKGluZGV4X3R5cGUgaSkKewoJc3RkOjpjb3V0IDw8IGkgPDwgJ1xuJzsKfQoKaW50IG1haW4oKQp7CglyZXBlYXQ8Zm9vLCA3Pjo6cnVuKCk7Cn0K