Nobody else produce an example based on a C++11 simulation of std::integer_sequence
(as suggested by W.F., Passer By and Sopel and the simpler solution, IMHO) so I propose the following one (of std::index_sequence
and std::make_index_sequence
in reality: simulate std::integer_sequence
is more complicated)
template <std::size_t ...>
struct indexSequence
{ };
template <std::size_t N, std::size_t ... Next>
struct indexSequenceHelper : public indexSequenceHelper<N-1U, N-1U, Next...>
{ };
template <std::size_t ... Next>
struct indexSequenceHelper<0U, Next ... >
{ using type = indexSequence<Next ... >; };
template <std::size_t N>
using makeIndexSequence = typename indexSequenceHelper<N>::type;
So a function (with function helper) to reproduce the asked loop can be written as
template
void shiftValHelper (T & t, indexSequence<Is...> const &)
{
using unused = int[];
(void)unused { 0,
(t.template bit<Is+Sh>() = t.template bit<Is>(), 0)... };
}
template <std::size_t Sh, std::size_t N, typename T>
void shiftVal (T & t)
{ shiftValHelper<Sh>(t, makeIndexSequence<N>{}); }
and called ad follows
shiftVal<2, N-2>(x);
The following is a full working example
#include <array>
#include <iostream>
template <std::size_t ...>
struct indexSequence
{ };
template <std::size_t N, std::size_t ... Next>
struct indexSequenceHelper : public indexSequenceHelper<N-1U, N-1U, Next...>
{ };
template <std::size_t ... Next>
struct indexSequenceHelper<0U, Next ... >
{ using type = indexSequence<Next ... >; };
template <std::size_t N>
using makeIndexSequence = typename indexSequenceHelper<N>::type;
template <std::size_t N>
struct foo
{
std::array<int, N> arr;
template <std::size_t I>
int & bit ()
{ return arr[I]; }
};
template <std::size_t Sh, typename T, std::size_t ... Is>
void shiftValHelper (T & t, indexSequence<Is...> const &)
{
using unused = int[];
(void)unused { 0,
(t.template bit<Is+Sh>() = t.template bit<Is>(), 0)... };
}
template <std::size_t Sh, std::size_t N, typename T>
void shiftVal (T & t)
{ shiftValHelper<Sh>(t, makeIndexSequence<N>{}); }
int main ()
{
foo<10U> f { { { 2, 3, 5, 7, 11, 13, 17, 19, 23, 29 } } };
for ( auto const & i : f.arr )
std::cout << i << ' ';
std::cout << std::endl;
shiftVal<2, 10-2>(f);
for ( auto const & i : f.arr )
std::cout << i << ' ';
std::cout << std::endl;
}