Switch two types to type list

For simplicity, use std::tuple as our list of types.

What is the best (compressed, least recursive, etc.) way to replace two types in std::tuple ?

Functionality illustration using indexes:

 #include <tuple> int main() { using tuple_t = std::tuple<int, void, double>; // int, void, double using swapped_tuple_t = std::tuple<double, void, int>; // double, void, int static_assert( std::is_same<swap<0, 2, tuple_t>::type, swapped_tuple_t>::value, "!" ); } 
+5
source share
4 answers
 #include <tuple> #include <utility> #include <cstddef> template <std::size_t I , std::size_t J , typename T , typename = std::make_index_sequence<I> , typename = std::make_index_sequence<J - I - 1> , typename = std::make_index_sequence<std::tuple_size<T>::value - J - 1>> struct swap; template <std::size_t I , std::size_t J , typename T , std::size_t... As , std::size_t... Bs , std::size_t... Cs> struct swap<I, J, T , std::index_sequence<As...> , std::index_sequence<Bs...> , std::index_sequence<Cs...> > { using type = std::tuple<typename std::tuple_element<As, T>::type... , typename std::tuple_element<J, T>::type , typename std::tuple_element<Bs + I + 1, T>::type... , typename std::tuple_element<I, T>::type , typename std::tuple_element<Cs + J + 1, T>::type...>; }; 

Demo


In cases where J can be lower than or equal to I , use the following characteristic:

 template <std::size_t I, std::size_t J, typename T> struct swap : swap_impl<I<J?I:J, I<J?J:I, T> {}; template <std::size_t I, typename T> struct swap<I,I,T> { using type = T; }; 

Demo 2

+6
source

There is no reason to use three sequences. One is enough:

 template <std::size_t I , std::size_t J , typename T , typename = std::make_index_sequence<std::tuple_size<T>::value>> struct swap_impl; template <std::size_t I , std::size_t J , typename T , std::size_t... As> struct swap_impl<I, J, T , std::index_sequence<As...> > { using type = std::tuple<std::tuple_element_t<As == I ? J : As == J? I : As, T>... >; }; template <std::size_t I, std::size_t J, typename T> struct swap : swap_impl<I, J, T> {}; 

And now there is no need for a special case I> = J.

Demo

+5
source

I throw away the alternative (but I think the @Piotr solution will be more elegant).

 template <size_t ...> struct seq { }; // X, Y are the indeces we want to swap template <size_t N, size_t X, size_t Y, size_t ...S> struct gen : gen<N-1, X, Y, (N-1 == X ? Y : (N-1 == Y ? X : N - 1)), S...> { }; template <size_t X, size_t Y, size_t ...S> struct gen<0, X, Y, S...> { typedef seq<S...> type; }; // X and Y are the index we want to swap, T is the tuple template <size_t X, size_t Y, class T, class S> struct swapImpl; template <size_t X, size_t Y, class T, size_t... S> struct swapImpl<X, Y, T, seq<S...>>{ using type = std::tuple<typename std::tuple_element<S, T>::type...>; }; template <size_t X, size_t Y, class T> struct swap { using type = typename swapImpl<X, Y, T, typename gen<std::tuple_size<T>::value, X, Y>::type>::type; }; int main() { using tuple_t = std::tuple<int, unsigned, void, char, double>; // int, void, double using swapped_tuple_a_t = std::tuple<unsigned, int, void, char, double>; // double, void, int static_assert( std::is_same<swap<0, 1, tuple_t>::type, swapped_tuple_a_t>::value, "!" ); static_assert( std::is_same<swap<1, 0, tuple_t>::type, swapped_tuple_a_t>::value, "!" ); using swapped_tuple_b_t = std::tuple<int, char, void, unsigned, double>; // double, void, int static_assert( std::is_same<swap<1, 3, tuple_t>::type, swapped_tuple_b_t>::value, "!" ); static_assert( std::is_same<swap<3, 1, tuple_t>::type, swapped_tuple_b_t>::value, "!" ); } 
+3
source
 months = ("January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December") num_days = (31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31) for x,y in zip(months,num_days): print("Month is ",x," Max days :- ",y) 

Output:

Month January Max. Days: - 31

Month February Max. Days: - 28

Month March Max. Days: - 31

Month April Max. Days: - 30

Month May Max Days: - 31

Month June Max. Days: - 30

Month July Max. Days: - 31

Month of August Max. Days: - 31

Month September Max. Days: - 30

Month October Max. Days: - 31

Month November Max. Days: - 30

Month December Max. Days: - 31

-1
source

Source: https://habr.com/ru/post/1236568/


All Articles