I would like to transform a compile time list of lists of types into a list of lists of std::integral_constant indices.
Appearently this requires some kind of 2d iota-like transformation.
Example source
template<typename... Ts> struct type_list{};
using L = type_list<
type_list<>,
type_list<>,
type_list<>,
type_list<>,
type_list<int>,
type_list<>,
type_list<int>,
type_list<int>,
type_list<int>,
type_list<int,double>,
type_list<int,double>
>;
expected result
template<uint64_t V> using I = std::integral_constant<uint64_t, V>; // alias for better legibility
using R = type_list<
type_list<>,
type_list<>,
type_list<>,
type_list<>,
type_list<I<0>>,
type_list<>,
type_list<I<1>>,
type_list<I<2>>,
type_list<I<3>>,
type_list<I<4>, I<5>>,
type_list<I<6>, I<7>>
>;
I think boost::mp11 fits this purpose perfectly, but I lack the experience to bring it all together. Please share your advice.
You are correct! Boost.Mp11 does fit this purpose perfectly.
This is basically a stateful fold. We have to keep track of how many values we've pushed so far, call that
N. Then, for each new element of the list,L, that we're iterating on, we append a new list that is[N, N+1, ..., N+len(L)-1]and then doN += len(L)in the state.For convenience, we can add a
State:An accumulating function that does what I described above:
And then lastly, we do the
foldand pull out thelist:Example demonstrating that it does the right thing.