#include <iostream>
#include <tuple>
#include <cassert>
template<std::size_t ...Indices>
struct index_tuple{
};
template<typename Left,typename Right>
struct concat_index_tuple;
template<std::size_t ...Lefts,std::size_t ...Rights>
struct concat_index_tuple<index_tuple<Lefts...>,index_tuple<Rights...>>{
using type = index_tuple<Lefts...,Rights...>;
};
template<std::size_t Beg,std::size_t End>
struct make_index_tuple{
using type = typename concat_index_tuple<
index_tuple<Beg>,
typename make_index_tuple<Beg + 1,End>::type
>::type;
};
template<std::size_t End>
struct make_index_tuple<End,End>{
using type = index_tuple<End>;
};
template<typename Tuple>
struct tuple_index;
template<typename ...Ts>
struct tuple_index<std::tuple<Ts...>>{
using type = typename make_index_tuple<0,sizeof...(Ts) - 1>::type;
};
struct outputter{
std::ostream &os;
outputter(std::ostream &s) : os(s){
}
template<typename T>
void operator ()(T const& v){
os << v << std::endl;
}
};
struct add_x{
int i;
add_x(int v) : i(v){
}
template<typename T>
void operator ()(T &v){
v += i;
}
};
template<typename F,typename T>
void work_impl(F func,std::size_t s,T &&x){
assert(s == 0);
func(std::forward<T>(x));
}
template<typename F,typename T,typename ...Us>
void work_impl(F func,std::size_t s,T &&x,Us &&...xs){
if(s){
work_impl(func,s - 1,std::forward<Us>(xs)...);
}
else{
func(std::forward<T>(x));
}
}
template<typename F,typename Tuple,std::size_t ...Indices>
void work_unpack(F func,std::size_t s,Tuple &&t,index_tuple<Indices...>){
work_impl(func,s,std::get<Indices>(std::forward<Tuple>(t))...);
}
template<typename F,typename Tuple>
void work(F func,std::size_t s,Tuple &&t){
work_unpack(func,s,std::forward<Tuple>(t),typename tuple_index<typename std::remove_reference<Tuple>::type>::type{});
}
int main() {
int i;
std::cout << "Enter index" << std::endl;
std::cin >> i;
auto t = std::make_tuple(1,2.0,3ull,4.f);
work(outputter{std::cout},i,t);
work(add_x{2},i,t);
work(outputter{std::cout},i,t);
work(outputter{std::cout},i,std::make_tuple("a",42,3.14f,&i));
return 0;
}
I2luY2x1ZGUgPGlvc3RyZWFtPgojaW5jbHVkZSA8dHVwbGU+CiNpbmNsdWRlIDxjYXNzZXJ0PgoKdGVtcGxhdGU8c3RkOjpzaXplX3QgLi4uSW5kaWNlcz4Kc3RydWN0IGluZGV4X3R1cGxlewp9Owp0ZW1wbGF0ZTx0eXBlbmFtZSBMZWZ0LHR5cGVuYW1lIFJpZ2h0PgpzdHJ1Y3QgY29uY2F0X2luZGV4X3R1cGxlOwp0ZW1wbGF0ZTxzdGQ6OnNpemVfdCAuLi5MZWZ0cyxzdGQ6OnNpemVfdCAuLi5SaWdodHM+CnN0cnVjdCBjb25jYXRfaW5kZXhfdHVwbGU8aW5kZXhfdHVwbGU8TGVmdHMuLi4+LGluZGV4X3R1cGxlPFJpZ2h0cy4uLj4+ewoJdXNpbmcgdHlwZSA9IGluZGV4X3R1cGxlPExlZnRzLi4uLFJpZ2h0cy4uLj47Cn07CnRlbXBsYXRlPHN0ZDo6c2l6ZV90IEJlZyxzdGQ6OnNpemVfdCBFbmQ+CnN0cnVjdCBtYWtlX2luZGV4X3R1cGxlewoJdXNpbmcgdHlwZSA9IHR5cGVuYW1lIGNvbmNhdF9pbmRleF90dXBsZTwKCQkJCQlpbmRleF90dXBsZTxCZWc+LAoJCQkJCXR5cGVuYW1lIG1ha2VfaW5kZXhfdHVwbGU8QmVnICsgMSxFbmQ+Ojp0eXBlCgk+Ojp0eXBlOwp9Owp0ZW1wbGF0ZTxzdGQ6OnNpemVfdCBFbmQ+CnN0cnVjdCBtYWtlX2luZGV4X3R1cGxlPEVuZCxFbmQ+ewoJdXNpbmcgdHlwZSA9IGluZGV4X3R1cGxlPEVuZD47Cn07CnRlbXBsYXRlPHR5cGVuYW1lIFR1cGxlPgpzdHJ1Y3QgdHVwbGVfaW5kZXg7CnRlbXBsYXRlPHR5cGVuYW1lIC4uLlRzPgpzdHJ1Y3QgdHVwbGVfaW5kZXg8c3RkOjp0dXBsZTxUcy4uLj4+ewoJdXNpbmcgdHlwZSA9IHR5cGVuYW1lIG1ha2VfaW5kZXhfdHVwbGU8MCxzaXplb2YuLi4oVHMpIC0gMT46OnR5cGU7Cn07CgpzdHJ1Y3Qgb3V0cHV0dGVyewoJc3RkOjpvc3RyZWFtICZvczsKCW91dHB1dHRlcihzdGQ6Om9zdHJlYW0gJnMpIDogb3Mocyl7Cgl9CgkKCXRlbXBsYXRlPHR5cGVuYW1lIFQ+Cgl2b2lkIG9wZXJhdG9yICgpKFQgY29uc3QmIHYpewoJCW9zIDw8IHYgPDwgc3RkOjplbmRsOwoJfQp9OwpzdHJ1Y3QgYWRkX3h7CglpbnQgaTsKCWFkZF94KGludCB2KSA6IGkodil7Cgl9CgkKCXRlbXBsYXRlPHR5cGVuYW1lIFQ+Cgl2b2lkIG9wZXJhdG9yICgpKFQgJnYpewoJCXYgKz0gaTsKCX0KfTsKCnRlbXBsYXRlPHR5cGVuYW1lIEYsdHlwZW5hbWUgVD4Kdm9pZCB3b3JrX2ltcGwoRiBmdW5jLHN0ZDo6c2l6ZV90IHMsVCAmJngpewoJYXNzZXJ0KHMgPT0gMCk7CglmdW5jKHN0ZDo6Zm9yd2FyZDxUPih4KSk7Cn0KdGVtcGxhdGU8dHlwZW5hbWUgRix0eXBlbmFtZSBULHR5cGVuYW1lIC4uLlVzPgp2b2lkIHdvcmtfaW1wbChGIGZ1bmMsc3RkOjpzaXplX3QgcyxUICYmeCxVcyAmJi4uLnhzKXsKCWlmKHMpewoJCXdvcmtfaW1wbChmdW5jLHMgLSAxLHN0ZDo6Zm9yd2FyZDxVcz4oeHMpLi4uKTsKCX0KCWVsc2V7CgkJZnVuYyhzdGQ6OmZvcndhcmQ8VD4oeCkpOwoJfQp9CnRlbXBsYXRlPHR5cGVuYW1lIEYsdHlwZW5hbWUgVHVwbGUsc3RkOjpzaXplX3QgLi4uSW5kaWNlcz4Kdm9pZCB3b3JrX3VucGFjayhGIGZ1bmMsc3RkOjpzaXplX3QgcyxUdXBsZSAmJnQsaW5kZXhfdHVwbGU8SW5kaWNlcy4uLj4pewoJd29ya19pbXBsKGZ1bmMscyxzdGQ6OmdldDxJbmRpY2VzPihzdGQ6OmZvcndhcmQ8VHVwbGU+KHQpKS4uLik7Cn0KdGVtcGxhdGU8dHlwZW5hbWUgRix0eXBlbmFtZSBUdXBsZT4Kdm9pZCB3b3JrKEYgZnVuYyxzdGQ6OnNpemVfdCBzLFR1cGxlICYmdCl7Cgl3b3JrX3VucGFjayhmdW5jLHMsc3RkOjpmb3J3YXJkPFR1cGxlPih0KSx0eXBlbmFtZSB0dXBsZV9pbmRleDx0eXBlbmFtZSBzdGQ6OnJlbW92ZV9yZWZlcmVuY2U8VHVwbGU+Ojp0eXBlPjo6dHlwZXt9KTsKfQoKaW50IG1haW4oKSB7CglpbnQgaTsKCXN0ZDo6Y291dCA8PCAiRW50ZXIgaW5kZXgiIDw8IHN0ZDo6ZW5kbDsKCXN0ZDo6Y2luID4+IGk7CgkKCWF1dG8gdCA9IHN0ZDo6bWFrZV90dXBsZSgxLDIuMCwzdWxsLDQuZik7Cgl3b3JrKG91dHB1dHRlcntzdGQ6OmNvdXR9LGksdCk7Cgl3b3JrKGFkZF94ezJ9LGksdCk7Cgl3b3JrKG91dHB1dHRlcntzdGQ6OmNvdXR9LGksdCk7Cgl3b3JrKG91dHB1dHRlcntzdGQ6OmNvdXR9LGksc3RkOjptYWtlX3R1cGxlKCJhIiw0MiwzLjE0ZiwmaSkpOwoJcmV0dXJuIDA7Cn0=