6#ifndef INCLUDE_GUARD_ARENE_BASE_ARENE_BASE_ALGORITHM_ROTATE_HPP_
7#define INCLUDE_GUARD_ARENE_BASE_ARENE_BASE_ALGORITHM_ROTATE_HPP_
13#include "arene/base/algorithm/detail/traits.hpp"
14#include "arene/base/algorithm/iter_swap.hpp"
15#include "arene/base/algorithm/move.hpp"
16#include "arene/base/algorithm/move_backward.hpp"
17#include "arene/base/algorithm/swap_ranges.hpp"
18#include "arene/base/compiler_support/cpp14_inline.hpp"
19#include "arene/base/constraints/constraints.hpp"
20#include "arene/base/contracts/contract.hpp"
21#include "arene/base/iterator/advance.hpp"
22#include "arene/base/iterator/distance.hpp"
23#include "arene/base/iterator/next.hpp"
24#include "arene/base/iterator/prev.hpp"
25#include "arene/base/math/gcd.hpp"
26#include "arene/base/stdlib_choice/declval.hpp"
27#include "arene/base/stdlib_choice/enable_if.hpp"
28#include "arene/base/stdlib_choice/ignore.hpp"
29#include "arene/base/stdlib_choice/is_copy_assignable.hpp"
30#include "arene/base/stdlib_choice/is_copy_constructible.hpp"
31#include "arene/base/stdlib_choice/is_move_assignable.hpp"
32#include "arene/base/stdlib_choice/is_move_constructible.hpp"
33#include "arene/base/stdlib_choice/move.hpp"
34#include "arene/base/type_traits/comparison_traits.hpp"
35#include "arene/base/type_traits/denotes_range.hpp"
36#include "arene/base/type_traits/is_movable.hpp"
37#include "arene/base/type_traits/is_swappable.hpp"
38#include "arene/base/type_traits/iterator_category_traits.hpp"
39#include "arene/base/type_traits/remove_cvref.hpp"
48namespace algorithm_detail {
49namespace rotate_detail {
61 template <
class Iterator, constraints<std::enable_if_t<base::is_forward_iterator_v<Iterator>>> =
nullptr>
62 static constexpr auto rotate_left(Iterator first, Iterator last) -> Iterator {
63 auto tmp = std::move(*first);
64 auto lm1 = ::arene::base::move(::arene::base::next(first), last, first);
65 *lm1 = std::move(tmp);
76 template <
class Iterator, constraints<std::enable_if_t<base::is_forward_iterator_v<Iterator>>> =
nullptr>
77 static constexpr auto rotate_right(Iterator first, Iterator last) -> Iterator {
78 Iterator lm1{arene::base::prev(last)};
79 auto tmp = std::move(*lm1);
80 auto fp1 = ::arene::base::move_backward(first, lm1, last);
81 *first = std::move(tmp);
95 template <
class Iterator, constraints<std::enable_if_t<base::is_forward_iterator_v<Iterator>>> =
nullptr>
96 static constexpr auto rotate_forward(Iterator first, Iterator middle, Iterator last) -> Iterator {
97 Iterator iter{middle};
99 ::arene::base::iter_swap(first, iter);
100 arene::base::advance(first, 1);
101 arene::base::advance(iter, 1);
105 if (first == middle) {
109 Iterator
const result{first};
110 if (first != middle) {
113 ::arene::base::iter_swap(first, iter);
114 arene::base::advance(first, 1);
115 arene::base::advance(iter, 1);
117 if (first == middle) {
121 }
else if (first == middle) {
140 template <
typename Iterator, constraints<std::enable_if_t<base::is_random_access_iterator_v<Iterator>>> =
nullptr>
141 static constexpr auto rotate_random_access(Iterator first, Iterator middle, Iterator last)
143 auto const distance_to_middle = arene::base::distance(first, middle);
144 auto const distance_from_middle = arene::base::distance(middle, last);
145 if (distance_to_middle == distance_from_middle) {
146 std::ignore = ::arene::base::swap_ranges(first, middle, middle);
149 auto const gcd_distance = ::arene::base::gcd(distance_to_middle, distance_from_middle);
150 auto pos = ::arene::base::next(first, gcd_distance);
151 while (pos != first) {
152 arene::base::advance(pos, -1);
153 auto temp(std::move(*pos));
155 Iterator pos2{arene::base::next(pos1, distance_to_middle)};
158 *pos1 = std::move(*pos2);
160 auto const distance_to_end = arene::base::distance(pos2, last);
161 if (distance_to_middle < distance_to_end) {
162 arene::base::advance(pos2, distance_to_middle);
164 pos2 = arene::base::next(first, distance_to_middle - distance_to_end);
166 }
while (pos2 != pos);
167 *pos1 = std::move(temp);
169 return arene::base::next(first, distance_from_middle);
186 std::enable_if_t<base::is_forward_iterator_v<Iterator>>,
187 std::enable_if_t<!base::is_bidirectional_iterator_v<Iterator>>> =
nullptr>
188 static constexpr auto impl(Iterator first, Iterator middle, Iterator last) -> Iterator {
189 if (::arene::base::next(first) == middle) {
190 return rotate_left(first, last);
192 return rotate_forward(first, middle, last);
209 std::enable_if_t<base::is_bidirectional_iterator_v<Iterator>>,
210 std::enable_if_t<!base::is_random_access_iterator_v<Iterator>>> =
nullptr>
211 static constexpr auto impl(Iterator first, Iterator middle, Iterator last) -> Iterator {
212 if (::arene::base::next(first) == middle) {
213 return rotate_left(first, last);
215 if (::arene::base::next(middle) == last) {
216 return rotate_right(first, last);
218 return rotate_forward(first, middle, last);
231 template <
class Iterator, constraints<std::enable_if_t<base::is_random_access_iterator_v<Iterator>>> =
nullptr>
232 static constexpr auto impl(Iterator first, Iterator middle, Iterator last) -> Iterator {
233 ARENE_PRECONDITION((::arene::base::distance(first, middle) >= 0) && (::arene::base::distance(middle, last) >= 0));
234 if (::arene::base::next(first) == middle) {
235 return rotate_left(first, last);
237 if (::arene::base::next(middle) == last) {
238 return rotate_right(first, last);
240 return rotate_random_access(first, middle, last);
269 std::enable_if_t<is_forward_iterator_v<Iterator>>,
270 std::enable_if_t<is_swappable_v<iter_reference_t<Iterator>>>,
271 std::enable_if_t<is_movable_v<remove_cvref_t<iter_reference_t<Iterator>>>>> =
nullptr>
272 constexpr auto operator()(Iterator first, Iterator middle, Iterator last)
const noexcept(
273 denotes_nothrow_iterable_range_v<Iterator> &&
274 is_nothrow_equality_comparable_v<Iterator> &&
275 std::is_nothrow_copy_constructible<Iterator>::value &&
276 std::is_nothrow_copy_assignable<Iterator>::value&&
277 noexcept(arene::base::advance(
278 std::declval<Iterator&>(),
279 std::declval<iter_difference_t<Iterator>>()
281 std::is_nothrow_move_constructible<remove_cvref_t<iter_reference_t<Iterator>>>::value &&
282 std::is_nothrow_move_assignable<remove_cvref_t<iter_reference_t<Iterator>>>::value &&
283 (is_random_access_iterator_v<Iterator> ||
284 is_nothrow_swappable_v<remove_cvref_t<iter_reference_t<Iterator>>>)
286 if (first == middle) {
289 if (middle == last) {
292 return impl(first, middle, last);
Definition array_exceptions_disabled.cpp:11
ARENE_CPP14_INLINE_VARIABLE(algorithm_detail::rotate_detail::rotate_impl_fn, rotate)
Copyright 2026, Toyota Motor Corporation.
Definition array_exceptions_disabled.cpp:10