#include <iostream>
#include <functional>
template<size_t... indexes>
struct index_tuple {};
template<size_t head, size_t... indexes>
struct index_tuple<head, indexes...> {
typedef typename index_tuple<head-1, head-1, indexes...>::type type;
};
template<size_t... indexes>
struct index_tuple<0, indexes...> {
typedef index_tuple<indexes...> type;
};
template<typename... Args>
struct index_tuple_maker {
typedef typename index_tuple<sizeof...(Args)>::type type;
};
template< typename ... Args >
class Message {
public:
Message( Args&& ... args ) {
mArgs = std::make_tuple( args ... );
}
std::tuple< Args ... > mArgs;
typedef std::function< void ( Args ... ) > HandlerType;
void Consume( const HandlerType &handler ) {
Consume(handler, typename index_tuple_maker<Args...>::type());
}
template<size_t... ns>
void Consume(const HandlerType &handler, index_tuple<ns...>) {
handler(std::get<ns>(mArgs)...);
}
};
int main() {
Message<int, int> msg(1, 2);
msg.Consume( [] ( int i, int j ) {
std::cout << i << ',' << j << '\n';
});
}
I2luY2x1ZGUgPGlvc3RyZWFtPgojaW5jbHVkZSA8ZnVuY3Rpb25hbD4KCnRlbXBsYXRlPHNpemVfdC4uLiBpbmRleGVzPgpzdHJ1Y3QgaW5kZXhfdHVwbGUge307Cgp0ZW1wbGF0ZTxzaXplX3QgaGVhZCwgc2l6ZV90Li4uIGluZGV4ZXM+CnN0cnVjdCBpbmRleF90dXBsZTxoZWFkLCBpbmRleGVzLi4uPiB7CiAgICB0eXBlZGVmIHR5cGVuYW1lIGluZGV4X3R1cGxlPGhlYWQtMSwgaGVhZC0xLCBpbmRleGVzLi4uPjo6dHlwZSB0eXBlOwp9OwoKdGVtcGxhdGU8c2l6ZV90Li4uIGluZGV4ZXM+CnN0cnVjdCBpbmRleF90dXBsZTwwLCBpbmRleGVzLi4uPiB7CiAgICB0eXBlZGVmIGluZGV4X3R1cGxlPGluZGV4ZXMuLi4+IHR5cGU7Cn07Cgp0ZW1wbGF0ZTx0eXBlbmFtZS4uLiBBcmdzPgpzdHJ1Y3QgaW5kZXhfdHVwbGVfbWFrZXIgewogICAgdHlwZWRlZiB0eXBlbmFtZSBpbmRleF90dXBsZTxzaXplb2YuLi4oQXJncyk+Ojp0eXBlIHR5cGU7Cn07CiAgICAKCnRlbXBsYXRlPCB0eXBlbmFtZSAuLi4gQXJncyA+CmNsYXNzIE1lc3NhZ2UgewpwdWJsaWM6CiAgICBNZXNzYWdlKCBBcmdzJiYgLi4uIGFyZ3MgKSB7CiAgICAgICAgbUFyZ3MgPSBzdGQ6Om1ha2VfdHVwbGUoIGFyZ3MgLi4uICApOwogICAgfQoKICAgIHN0ZDo6dHVwbGU8IEFyZ3MgLi4uID4gbUFyZ3M7CiAgICB0eXBlZGVmIHN0ZDo6ZnVuY3Rpb248IHZvaWQgKCBBcmdzIC4uLiApID4gSGFuZGxlclR5cGU7CgogICAgdm9pZCBDb25zdW1lKCBjb25zdCBIYW5kbGVyVHlwZSAmaGFuZGxlciApIHsKICAgICAgICBDb25zdW1lKGhhbmRsZXIsIHR5cGVuYW1lIGluZGV4X3R1cGxlX21ha2VyPEFyZ3MuLi4+Ojp0eXBlKCkpOwogICAgfQogICAgCiAgICB0ZW1wbGF0ZTxzaXplX3QuLi4gbnM+CiAgICB2b2lkIENvbnN1bWUoY29uc3QgSGFuZGxlclR5cGUgJmhhbmRsZXIsIGluZGV4X3R1cGxlPG5zLi4uPikgewogICAgICAgIGhhbmRsZXIoc3RkOjpnZXQ8bnM+KG1BcmdzKS4uLik7CiAgICB9Cn07CgoKaW50IG1haW4oKSB7CiAgICBNZXNzYWdlPGludCwgaW50PiBtc2coMSwgMik7CgogICAgbXNnLkNvbnN1bWUoIFtdICggaW50IGksIGludCBqICkgewogICAgICAgIHN0ZDo6Y291dCA8PCBpIDw8ICcsJyA8PCBqIDw8ICdcbic7CiAgICB9KTsKfQo=