[ Web Proxy ]
URL:
Viewing: https://en.cppreference.com/cpp/algorithm/rotate [Back]  [Original]

std::rotate - cppreference.com
cppreference.com
Namespaces
Variants

std::rotate

From cppreference.com
 
 
Algorithm library
Constrained algorithms and algorithms on ranges (C++20)
Constrained algorithms, e.g. ranges::copy, ranges::sort, ...
Non-modifying sequence operations    
Batch operations
(C++17)
Search operations
Modifying sequence operations
Copy operations
(C++11)
(C++11)
Swap operations
Transformation operations
Generation operations
Removing operations
Order-changing operations
(until C++17)(C++11)
(C++20)(C++20)
Sampling operations
(C++17)

Sorting and related operations
Partitioning operations
(C++11)    

Sorting operations
Binary search operations
(on partitioned ranges)
Set operations (on sorted ranges)
Merge operations (on sorted ranges)
Heap operations
Minimum/maximum operations
(C++11)
(C++17)
Lexicographical comparison operations
Permutation operations


 
Defined in header <algorithm>
template< class ForwardIt >
ForwardIt rotate( ForwardIt first, ForwardIt middle, ForwardIt last );
(1) (constexpr since C++20)
template< class ExecutionPolicy, class ForwardIt >
ForwardIt rotate( ExecutionPolicy&& policy,
                  ForwardIt first, ForwardIt middle, ForwardIt last );
(2) (since C++17)
1) Performs a left rotation on the target range [firstlast). Elements are swapped in such a way that the elements in [firstmiddle) are placed after the elements in [middlelast) while the orders of the elements in both ranges are preserved.
2) Same as (1), but executed according to policy.
This overload participates in overload resolution only if the value of the following expression is true:

std::is_execution_policy_v<std::decay_t<ExecutionPolicy>>

(until C++20)

std::is_execution_policy_v<std::remove_cvref_t<ExecutionPolicy>>

(since C++20)

If any of the following conditions is satisfied, the behavior is undefined:

  • [firstmiddle) or [middlelast) is not a valid range.
(until C++11)
(since C++11)

Parameters

first, last - the pair of iterators defining the target range
middle - the beginning of the part to be moved to the left
policy - the execution policy to use
Type requirements
-
ForwardIt must meet the requirements of LegacyForwardIterator.

Return value

The iterator to the element originally pointed to by first, or last if middle is equal to first.

Complexity

At most std::distance(first, last) swaps.

Exceptions

2) During the execution process:
  • If the temporary memory resources required for parallelization are not available, std::bad_alloc is thrown.
  • If an uncaught exception is thrown while accessing objects via an algorithm argument, the behavior is determined by the execution policy (for standard policies, std::terminate is invoked).

Notes

std::rotate has better efficiency on common implementations if ForwardIt satisfies LegacyBidirectionalIterator or (better) LegacyRandomAccessIterator.

Implementations (e.g. MSVC STL) may enable vectorization when the iterator type satisfies LegacyContiguousIterator and swapping its value type calls neither non-trivial special member function nor ADL-found swap.

Possible implementation

See also the implementations in libstdc++, libc++, and MSVC STL.

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;
}

Example

std::rotate is a common building block in many algorithms. This example demonstrates insertion sort.

#include <algorithm>
#include <print>
#include <string_view>
#include <vector>

template<typename ForwardIt>
void rotate_left(ForwardIt it_begin, ForwardIt it_end, std::size_t offset)
{
    std::rotate(it_begin, it_begin + offset, it_end);
}

template<typename ForwardIt>
void rotate_right(ForwardIt it_begin, ForwardIt it_end, std::size_t offset)
{
    std::rotate(it_begin, it_end - offset, it_end);
}

int main()
{
    constexpr std::string_view fmt = "{:21}{}\n";

    std::vector<int> v{2, 4, 2, 0, 5, 10, 7, 3, 7, 1};
    std::print(fmt, "before sort:", v);

    // insertion sort
    for (auto it = v.begin(); it != v.end(); ++it)
        rotate_right(std::upper_bound(v.begin(), it, *it), it + 1, 1);
    std::print(fmt, "after sort:", v);

    // simple rotation to the left
    rotate_left(v.begin(), v.end(), 1);
    std::print(fmt, "simple rotate left:", v);

    // simple rotation to the right
    rotate_right(v.begin(), v.end(), 1);
    std::print(fmt, "simple rotate right:", v);
}

Output:

before sort:         [2, 4, 2, 0, 5, 10, 7, 3, 7, 1]
after sort:          [0, 1, 2, 2, 3, 4, 5, 7, 7, 10]
simple rotate left:  [1, 2, 2, 3, 4, 5, 7, 7, 10, 0]
simple rotate right: [0, 1, 2, 2, 3, 4, 5, 7, 7, 10]

Defect reports

The following behavior-changing defect reports were applied retroactively to previously published C++ standards.

DR Applied to Behavior as published Correct behavior
LWG 488 C++98 the new location of the element pointed by first was not returned returned

See also

rotates the order of elements in a range
(algorithm function object)[edit]
copies and rotate a range of elements
(function template & algorithm function object)[edit]

Web Proxy Viewer  |  New URL  |  Original Page