Indices

You have a tuple and you want to expand it as if it was a parameter pack. How do you solve that?

# The indices trick

The indices trick basically amounts to tag dispatching to a structure that encodes all the indices.

Such a structure can be as simple as this:

template <std::size_t... Indices> struct indices {};

Then we use a single tagged overload that uses type deduction to extract the parameters of `indices` as a pack:

template <Tuple, std::size_t... Indices> std::array<int, std::tuple_size<Tuple>::value> f_them_all(Tuple&& t, indices<Indices...>) { return std::array<int, std::tuple_size<Tuple>::value> { { f(std::get<Indices>(std::forward<Tuple>(t)))... } }; }

Now all that's left is a way to build a pack of indices. Not that complicated.

template <std::size_t... Is> struct indices {}; template <std::size_t N, std::size_t... Is> struct build_indices : build_indices<N-1, N-1, Is...> {}; template <std::size_t... Is> struct build_indices<0, Is...> : indices<Is...> {}; template <typename Tuple> using IndicesFor = build_indices<std::tuple_size<Bare<Tuple>>::value>;

And the overload that builds the tag and dispatches:

template <typename Tuple> std::array<int, std::tuple_size<Tuple>::value> f_them_all(Tuple&& t) { return f_them_all(std::forward<Tuple>(t), IndicesFor<Tuple> {}); }