consider working code:
#include <type_traits> template <typename t, typename indexpack> struct make; template <typename t, template <t...> class p, t... indices> struct make<t, p<indices...>> { using type = p<(indices+1)..., (-3*indices)..., (indices-1)...>; }; template <int...> class pack; int main() { static_assert (std::is_same<make<int, pack<1,2,3,4>>::type, pack<2,3,4,5, -3,-6,-9,-12, 0,1,2,3>>::value, "false"); }
what want output is
pack<2,-3,0, 3,-6,1, 4,-9,2, 5,-12,3>
instead of pack<2,3,4,5, -3,-6,-9,-12, 0,1,2,3>
. first tried
using type = p<(indices+1, -3*indices, indices-1)...>;
but understood compiler useless comma operator. desired syntax want? if there no such syntax, cleanest way this, keeping in mind using indices
3 times example (we may want use more 3 times). please don't tell me have write helper extract individual packs , "interlace" elements. nightmarish method cannot best solution (and such solution work if knew how many individual packs extract).
would defining
template <typename t, template <t...> class p, t i> struct component { using type = p<i+1, -3*i, i-1>; };
help somehow? make pack expansion on this?
yes, can concat recursively:
template <typename, typename, typename> struct concat; template <typename t, template <t...> class p, t... a, t... b> struct concat<t, p<a...>, p<b...>> { using type = p<a..., b...>; }; template <typename t, typename indexpack> struct make; template <typename t, template <t...> class p, t... i, t f > struct make<t, p<f, i...>> { using type = typename concat<t, typename make<t, p<f>>::type, typename make<t, p<i...>>::type>::type; }; template <typename t, template <t...> class p, t i> struct make<t, p<i>> { using type = p<i+1, -3*i, i-1>; };