#include <array>
#include <iostream>
#include <utility>
template<int VRange, int VRepCount, int VValueRIndex = VRepCount> class
t_Looper
{
public: template<typename TAction> static void
process(::std::array<int, VRepCount> & values, TAction && action)
{
for(;;)
{
t_Looper<VRange, VRepCount, VValueRIndex - 1>::process(values, ::std::forward<TAction>(action));
auto & value{values[VRepCount - VValueRIndex]};
if((VRange - 1) != value)
{
++value;
}
else
{
value = 0;
break;
}
}
}
};
template<int VRange, int VRepCount> class
t_Looper<VRange, VRepCount, 0>
{
private: template<int... VIndexes, typename TAction> static void
invoke(::std::integer_sequence<int, VIndexes...>, ::std::array<int, VRepCount> const & values, TAction && action)
{
action(values[VIndexes]...);
}
public: template<typename TAction> static void
process(::std::array<int, VRepCount> & values, TAction && action)
{
invoke(::std::make_integer_sequence<int, VRepCount>(), values, ::std::forward<TAction>(action));
}
};
template<int VRange, int VRepCount, typename TAction> void
multiloop(TAction && action)
{
::std::array<int, VRepCount> values{};
t_Looper<VRange, VRepCount>::process(values, ::std::forward<TAction>(action));
}
int main()
{
multiloop<3, 2>([](int i, int j){::std::cout << i << " " << j << ::std::endl;});
multiloop<3, 4>([](int i, int j, int k, int l){::std::cout << i << " " << j << " " << k << " " << l << ::std::endl;});
return(0);
}
I2luY2x1ZGUgPGFycmF5PgojaW5jbHVkZSA8aW9zdHJlYW0+CiNpbmNsdWRlIDx1dGlsaXR5PgoKdGVtcGxhdGU8aW50IFZSYW5nZSwgaW50IFZSZXBDb3VudCwgaW50IFZWYWx1ZVJJbmRleCA9IFZSZXBDb3VudD4gY2xhc3MKdF9Mb29wZXIKewoJcHVibGljOiB0ZW1wbGF0ZTx0eXBlbmFtZSBUQWN0aW9uPiBzdGF0aWMgdm9pZAoJcHJvY2Vzcyg6OnN0ZDo6YXJyYXk8aW50LCBWUmVwQ291bnQ+ICYgdmFsdWVzLCBUQWN0aW9uICYmIGFjdGlvbikKCXsKCQlmb3IoOzspCgkJewoJCQl0X0xvb3BlcjxWUmFuZ2UsIFZSZXBDb3VudCwgVlZhbHVlUkluZGV4IC0gMT46OnByb2Nlc3ModmFsdWVzLCA6OnN0ZDo6Zm9yd2FyZDxUQWN0aW9uPihhY3Rpb24pKTsKCQkJYXV0byAmIHZhbHVle3ZhbHVlc1tWUmVwQ291bnQgLSBWVmFsdWVSSW5kZXhdfTsKCQkJaWYoKFZSYW5nZSAtIDEpICE9IHZhbHVlKQoJCQl7CgkJCQkrK3ZhbHVlOwoJCQl9CgkJCWVsc2UKCQkJewoJCQkJdmFsdWUgPSAwOwoJCQkJYnJlYWs7CgkJCX0KCQl9Cgl9Cn07Cgp0ZW1wbGF0ZTxpbnQgVlJhbmdlLCBpbnQgVlJlcENvdW50PiBjbGFzcwp0X0xvb3BlcjxWUmFuZ2UsIFZSZXBDb3VudCwgMD4KewoJcHJpdmF0ZTogdGVtcGxhdGU8aW50Li4uIFZJbmRleGVzLCB0eXBlbmFtZSBUQWN0aW9uPiBzdGF0aWMgdm9pZAoJaW52b2tlKDo6c3RkOjppbnRlZ2VyX3NlcXVlbmNlPGludCwgVkluZGV4ZXMuLi4+LCA6OnN0ZDo6YXJyYXk8aW50LCBWUmVwQ291bnQ+IGNvbnN0ICYgdmFsdWVzLCBUQWN0aW9uICYmIGFjdGlvbikKCXsKCQlhY3Rpb24odmFsdWVzW1ZJbmRleGVzXS4uLik7Cgl9CgoJcHVibGljOiB0ZW1wbGF0ZTx0eXBlbmFtZSBUQWN0aW9uPiBzdGF0aWMgdm9pZAoJcHJvY2Vzcyg6OnN0ZDo6YXJyYXk8aW50LCBWUmVwQ291bnQ+ICYgdmFsdWVzLCBUQWN0aW9uICYmIGFjdGlvbikKCXsKCQlpbnZva2UoOjpzdGQ6Om1ha2VfaW50ZWdlcl9zZXF1ZW5jZTxpbnQsIFZSZXBDb3VudD4oKSwgdmFsdWVzLCA6OnN0ZDo6Zm9yd2FyZDxUQWN0aW9uPihhY3Rpb24pKTsKCX0KfTsKCnRlbXBsYXRlPGludCBWUmFuZ2UsIGludCBWUmVwQ291bnQsIHR5cGVuYW1lIFRBY3Rpb24+IHZvaWQKbXVsdGlsb29wKFRBY3Rpb24gJiYgYWN0aW9uKQp7Cgk6OnN0ZDo6YXJyYXk8aW50LCBWUmVwQ291bnQ+IHZhbHVlc3t9OwoJdF9Mb29wZXI8VlJhbmdlLCBWUmVwQ291bnQ+Ojpwcm9jZXNzKHZhbHVlcywgOjpzdGQ6OmZvcndhcmQ8VEFjdGlvbj4oYWN0aW9uKSk7Cn0KCmludCBtYWluKCkKewoJbXVsdGlsb29wPDMsIDI+KFtdKGludCBpLCBpbnQgail7OjpzdGQ6OmNvdXQgPDwgaSA8PCAiICIgPDwgaiA8PCA6OnN0ZDo6ZW5kbDt9KTsKCW11bHRpbG9vcDwzLCA0PihbXShpbnQgaSwgaW50IGosIGludCBrLCBpbnQgbCl7OjpzdGQ6OmNvdXQgPDwgaSA8PCAiICIgPDwgaiA8PCAiICIgPDwgayA8PCAiICIgPDwgbCA8PCA6OnN0ZDo6ZW5kbDt9KTsKCXJldHVybigwKTsKfQo=