According to cppreference the return value of std::rotate()
is
The iterator to the element originally referenced by *first, i.e. the std::distance(middle, last) th next iterator of first.
And this is a possible implementation:
template<class ForwardIt>
constexpr // since C++20
ForwardIt rotate(ForwardIt first, ForwardIt middle, ForwardIt last)
{
if (first == middle)
return last;
if (middle == last)
return first;
ForwardIt write = first;
ForwardIt next_read = first; // read position for when “read” hits “last”
for (ForwardIt read = middle; read != last; ++write, ++read)
{
if (write == next_read)
next_read = read; // track where “first” went
std::iter_swap(write, read);
}
// rotate the remaining sequence into place
rotate(write, next_read, last);
return write;
}
if (first == middle) || (middle == last)
, there is nothing useful to do with a container, thus the function returns immediately. That makes sense. But why are different iterators returned in that case? Why return last
if first == middle
and return first
if middle == last
? Why not return first
in either case? Just curious. If it is implemented this way, there should be a reason for this. What is the point?
Think of rotate
not of a rotation operation, but of "swap two adjacent subsequences". Then the return value of rotate
tells where the separating element is located after the operation.
When the empty sequence comes first before the operation, i.e., first == middle
, then it is natural that in the result the empty sequence comes second, i.e., the new "separating" element is last
.
Simlarly, when the empty sequence comes second before the operation, i.e., middle == last
, then the empty sequence comes first in the result, i.e., the return value is first
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With