How can I replace 1 type from variadic template by its index? For example I have:
//-------------static_list-------------
template<class ...Elements>
struct static_list {};
struct execute_command<index, static_list<Commands...>> {
static constexpr int value = execute_s<index + 1, static_list<Commands...>>::value;
}
and I want to rewrite it so in Commands it will replace type at for example index 5 with type variable<0, 0>
like this:
struct execute_command<false, true, false, false, false, index, static_list<Commands...>> {
static constexpr int value = execute_s<index + 1, static_list_replace<5, variable<0, 0>, Commands...>>::value;
}
I have tried it many different ways but nothing was working. For example:
//-------------static_list_replace-------------
template<std::size_t N, typename T, typename Tuple, class IndexSequence>
struct static_list_replace;
template<std::size_t N, typename T, typename Tuple, std::size_t... Idx>
struct static_list_replace<N, T, Tuple, std::index_sequence<Idx ...>> {
using type = std::tuple<std::conditional_t<N == Idx, T, std::tuple_element_t<N, Tuple>>...>;
};
or
namespace detail {
template<std::size_t N, typename T, typename Tuple, std::size_t... Idx>
auto replace(std::index_sequence<Idx...>) ->
std::tuple<std::conditional_t<N == Idx,
T,
std::tuple_element_t<N, Tuple>>...>;
}
template <std::size_t N, typename T, typename... Args>
using Replace = decltype(detail::replace<N, T, std::tuple<Args...>>
(std::index_sequence_for<Args...>{}));
or I tried to get beginnig of the list and end without the one element and then pack it like static_list<list_beginning<index, Commands...>, element, list_ending<index, Commands...>>>
Nothing worked.
I suppose there are many ways...
For example, given an helper class as slrh
(Static List Replace Helper)
template <std::size_t, typename...>
struct slrh;
template <std::size_t N, typename R, std::size_t ... Is, typename ... Ts>
struct slrh<N, R, std::index_sequence<Is...>, Ts...>
{ using type = static_list<std::conditional_t<(N == Is), R, Ts>...>; };
your static_list_replace
can be simply written as follows
template <std::size_t, typename R, typename SL>
struct static_list_replace;
template <std::size_t N, typename R, typename ... Ts>
struct static_list_replace<N, R, static_list<Ts...>>
: public slrh<N, R, std::make_index_sequence<sizeof...(Ts)>, Ts...>
{ };
The following is a full compiling example
#include <utility>
#include <type_traits>
template <typename ...>
struct static_list
{ };
template <std::size_t, typename...>
struct slrh;
template <std::size_t N, typename R, std::size_t ... Is, typename ... Ts>
struct slrh<N, R, std::index_sequence<Is...>, Ts...>
{ using type = static_list<std::conditional_t<(N == Is), R, Ts>...>; };
template <std::size_t, typename R, typename SL>
struct static_list_replace;
template <std::size_t N, typename R, typename ... Ts>
struct static_list_replace<N, R, static_list<Ts...>>
: public slrh<N, R, std::make_index_sequence<sizeof...(Ts)>, Ts...>
{ };
template <int...>
struct variable
{ };
int main()
{
using T1 = static_list<char, short, int, long, long long>;
using T2 = static_list<char, short, char, long, long long>;
using T3 = typename static_list_replace<2u, char, T1>::type;
using T4 = static_list_replace<4, variable<16, 16>,
static_list<char, short, int, long, long long>>::type;
using T5 = static_list<char, short, int, long, variable<16, 16>>;
static_assert( std::is_same_v<T2, T3> );
static_assert( std::is_same_v<T4, T5> );
}