#include <iostream>
#include <tuple>
#include <cassert>
struct foo
{
foo() = delete;
foo(int i, int k)
: i(i), k(k){}
void operator()()
{ std::cout << i << " " << k << std::endl;}
int i;
int k;
};
struct bar
{
bar() = delete;
bar(int x)
: x(x){}
void operator()()
{ std::cout << x << std::endl;}
int x;
};
template <size_t I>
struct visit_impl
{
template <typename T, typename F>
static void visit(T& tup, size_t idx, F fun)
{
if (idx == I - 1) fun(std::get<I - 1>(tup));
else visit_impl<I - 1>::visit(tup, idx, fun);
}
};
template <>
struct visit_impl<0>
{
template <typename T, typename F>
static void visit(T& tup, size_t idx, F fun) { assert(false); }
};
/// visit at runtime the tuple item at idx and run F
template <typename F, typename... Ts>
void visit_at(std::tuple<Ts...> const& tup, size_t idx, F fun)
{
visit_impl<sizeof...(Ts)>::visit(tup, idx, fun);
}
/// visit at runtime the tuple item at idx and run F
template <typename F, typename... Ts>
void visit_at(std::tuple<Ts...>& tup, size_t idx, F fun)
{
visit_impl<sizeof...(Ts)>::visit(tup, idx, fun);
}
/// make an object
template <typename T, typename... Args>
T make_class(Args ...args)
{
return T(args...);
}
template <typename... Args>
void make_classes(Args... args)
{
auto t = std::tuple<Args...>(args...);
unsigned int size = std::tuple_size<decltype(t)>::value;
auto execute = [](auto & obj){ obj.operator()(); };
for (int i = 0; i < size; i++) {
visit_at(t, i, execute);
}
}
int main()
{
make_classes(
foo(2, 6),
bar(3),
foo(10,11),
bar(9)
);
}
I2luY2x1ZGUgPGlvc3RyZWFtPgojaW5jbHVkZSA8dHVwbGU+CiNpbmNsdWRlIDxjYXNzZXJ0PgoKc3RydWN0IGZvbyAKewoJZm9vKCkgPSBkZWxldGU7CgkKCWZvbyhpbnQgaSwgaW50IGspCgk6IGkoaSksIGsoayl7fQoJCgl2b2lkIG9wZXJhdG9yKCkoKQoJeyBzdGQ6OmNvdXQgPDwgaSA8PCAiICIgPDwgayA8PCBzdGQ6OmVuZGw7fQoJCglpbnQgaTsKCWludCBrOwp9OwoKc3RydWN0IGJhcgp7CgliYXIoKSA9IGRlbGV0ZTsKCQoJYmFyKGludCB4KQoJOiB4KHgpe30KCQoJdm9pZCBvcGVyYXRvcigpKCkKCXsgc3RkOjpjb3V0IDw8IHggPDwgc3RkOjplbmRsO30KCQoJaW50IHg7Cn07CgoKdGVtcGxhdGUgPHNpemVfdCBJPgpzdHJ1Y3QgdmlzaXRfaW1wbAp7CiAgICB0ZW1wbGF0ZSA8dHlwZW5hbWUgVCwgdHlwZW5hbWUgRj4KICAgIHN0YXRpYyB2b2lkIHZpc2l0KFQmIHR1cCwgc2l6ZV90IGlkeCwgRiBmdW4pCiAgICB7CiAgICAgICAgaWYgKGlkeCA9PSBJIC0gMSkgZnVuKHN0ZDo6Z2V0PEkgLSAxPih0dXApKTsKICAgICAgICBlbHNlIHZpc2l0X2ltcGw8SSAtIDE+Ojp2aXNpdCh0dXAsIGlkeCwgZnVuKTsKICAgIH0KfTsKCnRlbXBsYXRlIDw+CnN0cnVjdCB2aXNpdF9pbXBsPDA+CnsKICAgIHRlbXBsYXRlIDx0eXBlbmFtZSBULCB0eXBlbmFtZSBGPgogICAgc3RhdGljIHZvaWQgdmlzaXQoVCYgdHVwLCBzaXplX3QgaWR4LCBGIGZ1bikgeyBhc3NlcnQoZmFsc2UpOyB9Cn07CiAKLy8vIHZpc2l0IGF0IHJ1bnRpbWUgdGhlIHR1cGxlIGl0ZW0gYXQgaWR4IGFuZCBydW4gRgp0ZW1wbGF0ZSA8dHlwZW5hbWUgRiwgdHlwZW5hbWUuLi4gVHM+CnZvaWQgdmlzaXRfYXQoc3RkOjp0dXBsZTxUcy4uLj4gY29uc3QmIHR1cCwgc2l6ZV90IGlkeCwgRiBmdW4pCnsKICAgIHZpc2l0X2ltcGw8c2l6ZW9mLi4uKFRzKT46OnZpc2l0KHR1cCwgaWR4LCBmdW4pOwp9CgovLy8gdmlzaXQgYXQgcnVudGltZSB0aGUgdHVwbGUgaXRlbSBhdCBpZHggYW5kIHJ1biBGCnRlbXBsYXRlIDx0eXBlbmFtZSBGLCB0eXBlbmFtZS4uLiBUcz4Kdm9pZCB2aXNpdF9hdChzdGQ6OnR1cGxlPFRzLi4uPiYgdHVwLCBzaXplX3QgaWR4LCBGIGZ1bikKewogICAgdmlzaXRfaW1wbDxzaXplb2YuLi4oVHMpPjo6dmlzaXQodHVwLCBpZHgsIGZ1bik7Cn0KCi8vLyBtYWtlIGFuIG9iamVjdAp0ZW1wbGF0ZSA8dHlwZW5hbWUgVCwgdHlwZW5hbWUuLi4gQXJncz4KVCBtYWtlX2NsYXNzKEFyZ3MgLi4uYXJncykKewoJcmV0dXJuIFQoYXJncy4uLik7Cn0KCnRlbXBsYXRlIDx0eXBlbmFtZS4uLiBBcmdzPgp2b2lkIG1ha2VfY2xhc3NlcyhBcmdzLi4uIGFyZ3MpCnsKCWF1dG8gdCA9IHN0ZDo6dHVwbGU8QXJncy4uLj4oYXJncy4uLik7Cgl1bnNpZ25lZCBpbnQgc2l6ZSA9IHN0ZDo6dHVwbGVfc2l6ZTxkZWNsdHlwZSh0KT46OnZhbHVlOwoJYXV0byBleGVjdXRlID0gW10oYXV0byAmIG9iail7IG9iai5vcGVyYXRvcigpKCk7IH07CgkKCWZvciAoaW50IGkgPSAwOyBpIDwgc2l6ZTsgaSsrKSB7CgkJdmlzaXRfYXQodCwgaSwgZXhlY3V0ZSk7Cgl9Cn0KCmludCBtYWluKCkgCnsKCW1ha2VfY2xhc3NlcygKCQkJCSBmb28oMiwgNiksCgkJCQkgYmFyKDMpLAoJCQkJIGZvbygxMCwxMSksCgkJCQkgYmFyKDkpCgkJCSAgICk7Cn0K