Swap<T, Position1, Position2, Pack>::type, where Pack consists of elements of type T, is to return the pack with the elements in Position1 and Position2 swapped. My solution below is NOT the most efficient. There should be a way to accomplish this very cleanly, never visiting an element more than once. Can someone think of it?
// ReplaceElement replaces the element of a pack with a specified position (0 being the first position) with a specified value.
template <typename T, std::size_t, std::size_t, T, typename, typename> struct ReplaceElementHelper;
template <typename T, std::size_t Position, std::size_t CurrentPosition, T NewValue, template <T...> class Z, T First, T... Rest, T... Accumulated>
struct ReplaceElementHelper<T, Position, CurrentPosition, NewValue, Z<First, Rest...>, Z<Accumulated...>>
: ReplaceElementHelper<T, Position, CurrentPosition + 1, NewValue, Z<Rest...>, Z<Accumulated..., First>> {};
template <typename T, std::size_t Position, T NewValue, template <T...> class Z, T First, T... Rest, T... Accumulated>
struct ReplaceElementHelper<T, Position, Position, NewValue, Z<First, Rest...>, Z<Accumulated...>> {
using type = Z<Accumulated..., NewValue, Rest...>;
};
template <typename T, std::size_t, T, typename> struct ReplaceElement;
template <typename T, std::size_t Position, T NewValue, template <T...> class Z, T... Ts>
struct ReplaceElement<T, Position, NewValue, Z<Ts...>> : ReplaceElementHelper<T, Position, 0, NewValue, Z<Ts...>, Z<>> {
static_assert (Position < sizeof...(Ts), "Error! Invalid position for ReplaceElement.");
};
// Swapping two elements of specified positions in a pack.
template <typename, std::size_t, std::size_t, typename> struct Swap;
template <typename T, std::size_t Position1, std::size_t Position2, template <T...> class Z, T... Ts>
struct Swap<T, Position1, Position2, Z<Ts...>> {
template <std::size_t...> struct S;
static constexpr T a[sizeof...(Ts)] = {Ts...};
using type = typename ReplaceElement<T, Position2, a[Position1], typename ReplaceElement<T, Position1, a[Position2], Z<Ts...>>::type>::type;
};
Aucun commentaire:
Enregistrer un commentaire