Namespaces
Variants

std:: rotate

From cppreference.net
Algorithm library
Constrained algorithms and algorithms on ranges (C++20)
Constrained algorithms, e.g. ranges::copy , ranges::sort , ...
Execution policies (C++17)
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
Sorting operations
Binary search operations
(on partitioned ranges)
Set operations (on sorted ranges)
Merge operations (on sorted ranges)
Heap operations
Minimum/maximum operations
Lexicographical comparison operations
Permutation operations
C library
Numeric operations
Operations on uninitialized memory
Определено в заголовке <algorithm>
template < class ForwardIt >
ForwardIt rotate ( ForwardIt first, ForwardIt middle, ForwardIt last ) ;
(1) (constexpr начиная с C++20)
template < class ExecutionPolicy, class ForwardIt >

ForwardIt rotate ( ExecutionPolicy && policy,

ForwardIt first, ForwardIt middle, ForwardIt last ) ;
(2) (начиная с C++17)
1) Выполняет левый поворот диапазона элементов.
В частности, std::rotate переставляет элементы в диапазоне [ first , last ) таким образом, что элементы в [ first , middle ) помещаются после элементов в [ middle , last ) при сохранении порядка элементов в обоих диапазонах.
2) То же, что и (1) , но выполняется в соответствии с policy .
Эта перегрузка участвует в разрешении перегрузки только при выполнении всех следующих условий:

std:: is_execution_policy_v < std:: decay_t < ExecutionPolicy >> is true .

(until C++20)

std:: is_execution_policy_v < std:: remove_cvref_t < ExecutionPolicy >> is true .

(since C++20)

Если выполняется любое из следующих условий, поведение является неопределённым:

(до C++11)
(начиная с C++11)

Содержание

Параметры

first, last - пара итераторов, определяющих диапазон элементов для ротации
middle - элемент, который должен оказаться в начале ротированного диапазона
policy - политика выполнения execution policy для использования
Требования к типам
-
ForwardIt должен удовлетворять требованиям LegacyForwardIterator .

Возвращаемое значение

Итератор на элемент, изначально ссылавшийся на * first , т.е. на std:: distance ( middle, last ) следующий итератор от first .

Сложность

Не более std:: distance ( first, last ) обменов.

Исключения

Перегрузка с параметром шаблона с именем ExecutionPolicy сообщает об ошибках следующим образом:

  • Если выполнение функции, вызванной как часть алгоритма, выбрасывает исключение и ExecutionPolicy является одним из стандартных политик , std::terminate вызывается. Для любой другой ExecutionPolicy поведение определяется реализацией.
  • Если алгоритму не удается выделить память, std::bad_alloc выбрасывается.

Возможная реализация

Смотрите также реализации в libstdc++ , libc++ , и MSVC STL .

template<class ForwardIt>
constexpr // начиная с 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» достигает «last»
    for (ForwardIt read = middle; read != last; ++write, ++read)
    {
        if (write == next_read)
            next_read = read; // отслеживаем, куда переместился «first»
        std::iter_swap(write, read);
    }
    // поворачиваем оставшуюся последовательность на место
    rotate(write, next_read, last);
    return write;
}

Примечания

std::rotate обладает лучшей эффективностью в распространённых реализациях, если ForwardIt удовлетворяет требованиям LegacyBidirectionalIterator или (что предпочтительнее) LegacyRandomAccessIterator .

Реализации (например, MSVC STL ) могут использовать векторизацию, когда тип итератора удовлетворяет требованиям LegacyContiguousIterator и обмен его типа значений не вызывает ни нетривиальные специальные функции-члены, ни ADL -найденную функцию swap .

Пример

std::rotate является распространённым строительным блоком во многих алгоритмах. Этот пример демонстрирует сортировку вставками .

#include <algorithm>
#include <iostream>
#include <vector>
auto print = [](const auto remark, const auto& v)
{
    std::cout << remark;
    for (auto n : v)
        std::cout << n << ' ';
    std::cout << '\n';
};
int main()
{
    std::vector<int> v{2, 4, 2, 0, 5, 10, 7, 3, 7, 1};
    print("before sort:\t\t", v);
    // insertion sort
    for (auto i = v.begin(); i != v.end(); ++i)
        std::rotate(std::upper_bound(v.begin(), i, *i), i, i + 1);
    print("after sort:\t\t", v);
    // simple rotation to the left
    std::rotate(v.begin(), v.begin() + 1, v.end());
    print("simple rotate left:\t", v);
    // simple rotation to the right
    std::rotate(v.rbegin(), v.rbegin() + 1, v.rend());
    print("simple rotate right:\t", v);
}

Вывод:

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

Отчеты о дефектах

Следующие отчеты об изменениях в поведении, содержащие описания дефектов, были применены ретроактивно к ранее опубликованным стандартам C++.

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

Смотрите также

копирует и поворачивает диапазон элементов
(шаблон функции)
поворачивает порядок элементов в диапазоне
(функциональный объект алгоритма)