Iros
 
Loading...
Searching...
No Matches
rotate.h
Go to the documentation of this file.
1#pragma once
2
8#include "di/util/move.h"
9
10namespace di::container {
11namespace detail {
13 template<concepts::Permutable Iter, concepts::SentinelFor<Iter> Sent>
14 constexpr auto operator()(Iter first, Iter pivot, Sent last_sentinel) const -> View<Iter> {
15 // Full Rotation: first == pivot
16 if (first == pivot) {
17 auto last = container::next(first, last_sentinel);
18 return { last, last };
19 }
20
21 // No Rotation: pivot == last_sentinel
22 if (pivot == last_sentinel) {
23 return { util::move(first), util::move(pivot) };
24 }
25
26 // Bidirectional Case: reverse the range [first, pivot) and [pivot, last_sentinel).
27 // then, reverse the entire range once to get the result.
29 container::reverse(first, pivot);
30 auto last = container::reverse(pivot, last_sentinel);
31
32 // Random Access Case: simple reverse the entire range and then
33 // reconstruct the correct return value.
35 container::reverse(first, last);
36 return { first + (last - pivot), last };
37 }
38 // Bidirectional Case: manually reverse the whole range, making
39 // sure to remember the new midpoint.
40 else {
41 auto tail = last;
42 do {
43 container::iterator_swap(first, --tail);
44 ++first;
45 } while (first != pivot && tail != pivot);
46
47 // Now, one of { first, tail } points to the new pivot, and the
48 // rest can be reversed normally.
49 if (first == pivot) {
50 container::reverse(pivot, tail);
51 return { tail, last };
52 }
53 container::reverse(first, pivot);
54 return { first, last };
55 }
56 }
57 // Forward case: rotate in blocks, cycles at a time.
58 else {
59 auto next = pivot;
60 do {
62 ++first;
63 ++next;
64 if (first == pivot) {
65 pivot = first;
66 }
67 } while (next != last_sentinel);
68
69 auto first_save = first;
70 while (pivot != last_sentinel) {
71 next = pivot;
72 do {
74 ++first;
75 ++next;
76 if (first == pivot) {
77 pivot == first;
78 }
79 } while (next != last_sentinel);
80 }
81 return { first_save, pivot };
82 }
83 }
84
85 template<concepts::ForwardContainer Con>
87 constexpr auto operator()(Con&& container, meta::ContainerIterator<Con> pivot) const
89 return (*this)(container::begin(container), util::move(pivot), container::end(container));
90 }
91 };
92}
93
94constexpr inline auto rotate = detail::RotateFunction {};
95}
96
97namespace di {
99}
Definition view.h:35
Definition bidirectional_iterator.h:8
Definition permutable.h:9
Definition random_access_iterator.h:12
Definition sequence.h:13
Definition sequence.h:12
constexpr auto next
Definition next.h:35
constexpr auto reverse
Definition reverse.h:28
constexpr auto iterator_swap
Definition iterator_swap.h:49
constexpr auto end
Definition end.h:47
constexpr auto rotate
Definition rotate.h:94
constexpr auto begin
Definition begin.h:44
Conditional< concepts::BorrowedContainer< Con >, container::View< ContainerIterator< Con > >, container::Dangling > BorrowedView
Definition borrowed_view.h:12
decltype(container::begin(util::declval< T & >())) ContainerIterator
Definition container_iterator.h:8
Definition zstring_parser.h:9
constexpr auto operator()(Iter first, Iter pivot, Sent last_sentinel) const -> View< Iter >
Definition rotate.h:14