#include <tuple>
#include <cassert>
#include <iostream>
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); }
};
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);
}
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);
}
int main()
{
auto tup = std::make_tuple('a', 42, 13.37);
auto doSomething = [](auto v) { std::cout << v << "\n"; };
visit_at(tup, 0, doSomething);
}
I2luY2x1ZGUgPHR1cGxlPgojaW5jbHVkZSA8Y2Fzc2VydD4KI2luY2x1ZGUgPGlvc3RyZWFtPgoKdGVtcGxhdGUgPHNpemVfdCBJPgpzdHJ1Y3QgdmlzaXRfaW1wbAp7CiAgICB0ZW1wbGF0ZSA8dHlwZW5hbWUgVCwgdHlwZW5hbWUgRj4KICAgIHN0YXRpYyB2b2lkIHZpc2l0KFQmIHR1cCwgc2l6ZV90IGlkeCwgRiBmdW4pCiAgICB7CiAgICAgICAgaWYgKGlkeCA9PSBJIC0gMSkgZnVuKHN0ZDo6Z2V0PEkgLSAxPih0dXApKTsKICAgICAgICBlbHNlIHZpc2l0X2ltcGw8SSAtIDE+Ojp2aXNpdCh0dXAsIGlkeCwgZnVuKTsKICAgIH0KfTsKCnRlbXBsYXRlIDw+CnN0cnVjdCB2aXNpdF9pbXBsPDA+CnsKICAgIHRlbXBsYXRlIDx0eXBlbmFtZSBULCB0eXBlbmFtZSBGPgogICAgc3RhdGljIHZvaWQgdmlzaXQoVCYgdHVwLCBzaXplX3QgaWR4LCBGIGZ1bikgeyBhc3NlcnQoZmFsc2UpOyB9Cn07Cgp0ZW1wbGF0ZSA8dHlwZW5hbWUgRiwgdHlwZW5hbWUuLi4gVHM+CnZvaWQgdmlzaXRfYXQoc3RkOjp0dXBsZTxUcy4uLj4gY29uc3QmIHR1cCwgc2l6ZV90IGlkeCwgRiBmdW4pCnsKICAgIHZpc2l0X2ltcGw8c2l6ZW9mLi4uKFRzKT46OnZpc2l0KHR1cCwgaWR4LCBmdW4pOwp9Cgp0ZW1wbGF0ZSA8dHlwZW5hbWUgRiwgdHlwZW5hbWUuLi4gVHM+CnZvaWQgdmlzaXRfYXQoc3RkOjp0dXBsZTxUcy4uLj4mIHR1cCwgc2l6ZV90IGlkeCwgRiBmdW4pCnsKICAgIHZpc2l0X2ltcGw8c2l6ZW9mLi4uKFRzKT46OnZpc2l0KHR1cCwgaWR4LCBmdW4pOwp9CgppbnQgbWFpbigpCnsKCWF1dG8gdHVwID0gc3RkOjptYWtlX3R1cGxlKCdhJywgNDIsIDEzLjM3KTsKCWF1dG8gZG9Tb21ldGhpbmcgPSBbXShhdXRvIHYpIHsgc3RkOjpjb3V0IDw8IHYgPDwgIlxuIjsgfTsKCXZpc2l0X2F0KHR1cCwgMCwgZG9Tb21ldGhpbmcpOwp9