I played a little bit with the rotating of container elements (after I saw a possible solution here in the forum).
I made a rotating function which works on forward-based iterators. But it has two iteration loops which will be nested.
Then I tried to make a solution which would work on random-access iterators which should work with only one iteration loop. My try works only with a shifting by one position.
So I ask: Is it be able making such a shifting function with only one iterative loop? And without copying/moving one container into another.
#include <iostream>
// Rotates all elements leftward by 'size' positions.
// Works with any forward iterator.
//
template <typename Itr>
void rotate_left( const Itr begin, const Itr end, std::size_t rotate_by)
{
if (begin == end) return;
auto pos = begin, pos2 = begin;
++pos2;
if (pos2 == end) return;
for( std::size_t n = 0; n < rotate_by; ++n)
{
pos2 = pos = begin;
++pos2;
auto tmp = std::move(*pos);
Itr last;
do
{
last = pos2;
*pos++ = std::move( *pos2++);
}
while (pos2 != end);
*last = tmp;
}
}
// Should work with any random access iterator
//
// The question is: Is it able to rotate all elements without nested loops?
//
template <typename Itr>
void rotate_left_with_random_access( const Itr begin, const Itr end, int rotate_by)
{
if (begin == end) return; // Empty container.
constint range = end - begin;
rotate_by %= range; // Rotate only in matching range.
for (int i = 0; i < range-1; ++i)
{
auto tmp = std::move(begin[i]);
begin[i] = std::move( begin[(i+rotate_by)%range]);
begin[(i+rotate_by)%range] = std::move(tmp);
}
}
int main()
{
char word[] = "0123456789";
rotate_left_with_random_access(word, word+4, 1);
std::cout << word;
}