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> {});
    }
Unless otherwise stated, the content of this page is licensed under Creative Commons Attribution-ShareAlike 3.0 License