#include #include template struct identity { using type = T; }; template struct nth_type; template struct nth_type<0, T, Ts...> : identity {}; template struct nth_type : nth_type {}; template using nth_type_t = typename nth_type::type; template struct tuple_field { T value; }; template struct tuple_storage; template struct tuple_storage, Ts...> : tuple_field... { template tuple_storage(std::index_sequence, Us&&... vals) : tuple_field>{std::forward(vals)}... {} }; template struct tuple : tuple_storage, Ts...> { using super_t = tuple_storage, Ts...>; template tuple(Us&&... vals) : super_t(std::make_index_sequence(), std::forward(vals)...) {} }; template decltype(auto) get_helper_ix(tuple_field &fld) { return fld.value; } template decltype(auto) get_helper_ty(tuple_field &fld) { return fld.value; } template decltype(auto) get(tuple &tup) { return get_helper_ix(tup); } template decltype(auto) get(tuple &&tup) { return get_helper_ix(tup); } template decltype(auto) get(tuple &tup) { return get_helper_ty(tup); } template decltype(auto) get(tuple &&tup) { return get_helper_ty(tup); } template auto make_tuple(Ts&&... vals) { return tuple{std::forward(vals)...}; } auto what() { return make_tuple(1LL, 2LL); } auto hello() { return get<1>(what()); } auto poop() { return get(make_tuple(1, 2LL)); }