Search code examples
c++templatesvariadic-templatesc++20

Transform variadic type list to tuple of pairs


Is the following type transformation possible:

T1, T2, T3, T4, ...., T2n-1, T2n 
    ---> transform to --->
tuple<
  pair<T1, T2>, 
  pair<T3, T4>, 
  ..., 
  pair<T2n-1, T2n>
>

Such a meta-function

template <class... Args>
using split_in_pairs_t = ???

would be used like so:

template <class... Args>
class UseCase
{
  split_in_pairs_t<Args...> _tupleOfPairs;
};

A non-recursive solution would be preferable.


Solution

  • Make an index sequence of half the size, and pair elements 2*i, 2*i+1 together:

    template <class...> struct pairwise_impl;
    
    template <class... Args, size_t... Is> 
    struct pairwise_impl<std::tuple<Args...>, std::index_sequence<Is...>>
    {
        using full_tuple_t = std::tuple<Args...>;
        
        using type = std::tuple<std::pair<
            std::tuple_element_t<2*Is, full_tuple_t>,
            std::tuple_element_t<2*Is+1, full_tuple_t>
        >...>;
    };
    
    template <class... Args> struct pairwise
    {
        static_assert(sizeof...(Args) % 2 == 0,
                       "Only even typelists can be split to pairs");
        
        using type = typename pairwise_impl<
            std::tuple<Args...>, 
            std::make_index_sequence<sizeof...(Args) / 2>
        >::type;           
    };  
    
    template <class... Args>
    using pairwise_t = typename pairwise<Args...>::type;
    

    Demo