As for the runtime, I would linearly index it and make to_multi_index , something like:
// Is0 * Is1 * ... * Isn template <std::size_t ... Is> struct accum_mul; template <> struct accum_mul<> : std::integral_constant<std::size_t, 1u>{}; template <std::size_t I, std::size_t ... Is> struct accum_mul<I, Is...> : std::integral_constant<std::size_t, I * accum_mul<Is...>::value>{}; template <typename Seq, typename Res = std::tuple<>> struct coeff; template <typename Res> struct coeff<std::index_sequence<>, Res> { using type = Res; }; template <std::size_t I, std::size_t ... Is, typename ... TRes> struct coeff<std::index_sequence<I, Is...>, std::tuple<TRes...>> : coeff<std::index_sequence<Is...>, std::tuple<TRes..., accum_mul<Is...>>> {}; template <std::size_t I, typename coeffs, typename dims, typename Seq> struct to_multi_index; template <std::size_t I, typename coeffs, typename dims, std::size_t... Is> struct to_multi_index<I, coeffs, dims, std::index_sequence<Is...>> { using type = std::index_sequence<(I / (std::tuple_element<Is, coeffs>::type::value) % (std::tuple_element<Is, dims>::type::value))...>; }; template <typename Indexes, typename coeffs, typename dims, typename dim_indexes> struct to_multi_indexes; template <std::size_t... Is, typename coeffs, typename dims, typename dim_indexes> struct to_multi_indexes<std::index_sequence<Is...>, coeffs, dims, dim_indexes> { using type = std::tuple<typename to_multi_index<Is, coeffs, dims, dim_indexes>::type...>; }; template <std::size_t...Is> struct all_indexes { private: using as_seq = std::index_sequence<Is...>; using as_tuple = std::tuple<std::integral_constant<std::size_t, Is>...>; using dim_index = std::make_index_sequence<sizeof...(Is)>; using coeffs = typename coeff<as_seq>::type; using elem_count = accum_mul<Is...>; using index_seq = std::make_index_sequence<elem_count::value>; public: using type = typename to_multi_indexes<index_seq, coeffs, as_tuple, dim_index>::type; };
Live demo
source share