#include <cstddef>
#include <functional>
#include <utility>
#include <type_traits>
template <typename C, std::size_t N>
struct NaryDispatch
{
template <typename T, std::size_t K, typename ...Args>
struct function_maker
{
using type = typename function_maker<T, K - 1, T, Args...>::type;
};
template <typename T, typename ...Args>
struct function_maker<T, 0, Args...>
{
using type = std::function<void(Args...)>;
};
using f_type = typename function_maker<C &, N>::type;
template <typename F>
NaryDispatch(F && f) : fn_(std::forward<F>(f)) {}
template <typename ...Args,
typename = typename std::enable_if<sizeof...(Args) == N>::type>
void run(Args &&... args)
{
fn_(std::forward<Args>(args)...);
}
f_type fn_;
};
#include <iostream>
void print(const char * msg, int a, int b, int c)
{
std::cout << msg << ": [" << a << ", " << b << ", " << c << "]\n";
}
int main()
{
int x = 1, y = 2, z = 3;
print("Before", x, y, z);
NaryDispatch<int, 3> d([](int & a, int & b, int & c){ print("During", a++, b++, c++); });
d.run(x, y, z);
print("After", x, y, z);
}
I2luY2x1ZGUgPGNzdGRkZWY+CiNpbmNsdWRlIDxmdW5jdGlvbmFsPgojaW5jbHVkZSA8dXRpbGl0eT4KI2luY2x1ZGUgPHR5cGVfdHJhaXRzPgoKdGVtcGxhdGUgPHR5cGVuYW1lIEMsIHN0ZDo6c2l6ZV90IE4+CnN0cnVjdCBOYXJ5RGlzcGF0Y2gKewogICAgdGVtcGxhdGUgPHR5cGVuYW1lIFQsIHN0ZDo6c2l6ZV90IEssIHR5cGVuYW1lIC4uLkFyZ3M+CiAgICBzdHJ1Y3QgZnVuY3Rpb25fbWFrZXIKICAgIHsKICAgICAgICB1c2luZyB0eXBlID0gdHlwZW5hbWUgZnVuY3Rpb25fbWFrZXI8VCwgSyAtIDEsIFQsIEFyZ3MuLi4+Ojp0eXBlOwogICAgfTsKCiAgICB0ZW1wbGF0ZSA8dHlwZW5hbWUgVCwgdHlwZW5hbWUgLi4uQXJncz4KICAgIHN0cnVjdCBmdW5jdGlvbl9tYWtlcjxULCAwLCBBcmdzLi4uPgogICAgewogICAgICAgIHVzaW5nIHR5cGUgPSBzdGQ6OmZ1bmN0aW9uPHZvaWQoQXJncy4uLik+OwogICAgfTsKCiAgICB1c2luZyBmX3R5cGUgPSB0eXBlbmFtZSBmdW5jdGlvbl9tYWtlcjxDICYsIE4+Ojp0eXBlOwoKICAgIHRlbXBsYXRlIDx0eXBlbmFtZSBGPgogICAgTmFyeURpc3BhdGNoKEYgJiYgZikgOiBmbl8oc3RkOjpmb3J3YXJkPEY+KGYpKSB7fQoKICAgIHRlbXBsYXRlIDx0eXBlbmFtZSAuLi5BcmdzLAogICAgICAgICAgICAgIHR5cGVuYW1lID0gdHlwZW5hbWUgc3RkOjplbmFibGVfaWY8c2l6ZW9mLi4uKEFyZ3MpID09IE4+Ojp0eXBlPgogICAgdm9pZCBydW4oQXJncyAmJi4uLiBhcmdzKQogICAgewogICAgICAgIGZuXyhzdGQ6OmZvcndhcmQ8QXJncz4oYXJncykuLi4pOwogICAgfQoKICAgIGZfdHlwZSBmbl87Cn07CgoKI2luY2x1ZGUgPGlvc3RyZWFtPgoKdm9pZCBwcmludChjb25zdCBjaGFyICogbXNnLCBpbnQgYSwgaW50IGIsIGludCBjKQp7CiAgIHN0ZDo6Y291dCA8PCBtc2cgPDwgIjogWyIgPDwgYSA8PCAiLCAiIDw8IGIgPDwgIiwgIiA8PCBjIDw8ICJdXG4iOwp9CgppbnQgbWFpbigpCnsKICAgIGludCB4ID0gMSwgeSA9IDIsIHogPSAzOwoKICAgIHByaW50KCJCZWZvcmUiLCB4LCB5LCB6KTsKCiAgICBOYXJ5RGlzcGF0Y2g8aW50LCAzPiBkKFtdKGludCAmIGEsIGludCAmIGIsIGludCAmIGMpeyBwcmludCgiRHVyaW5nIiwgYSsrLCBiKyssIGMrKyk7IH0pOwogICAgZC5ydW4oeCwgeSwgeik7CgogICAgcHJpbnQoIkFmdGVyIiwgeCwgeSwgeik7Cn0K