@@ -89,46 +89,39 @@ __rotate_forward(_ForwardIterator __first, _ForwardIterator __middle, _ForwardIt
8989 return __r;
9090}
9191
92- template <typename _Integral>
93- inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 _Integral __algo_gcd (_Integral __x, _Integral __y) {
94- do {
95- _Integral __t = __x % __y;
96- __x = __y;
97- __y = __t ;
98- } while (__y);
99- return __x;
100- }
92+ template <class _AlgPolicy , class _Iter , class _Sent >
93+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 _Iter __rotate_random (_Iter __first, _Iter __middle, _Sent __last) {
94+ auto __left = _IterOps<_AlgPolicy>::distance (__first, __middle);
95+ auto __right = _IterOps<_AlgPolicy>::distance (__middle, __last);
96+ auto __end = __first + __right;
10197
102- template <class _AlgPolicy , typename _RandomAccessIterator>
103- _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 _RandomAccessIterator
104- __rotate_gcd (_RandomAccessIterator __first, _RandomAccessIterator __middle, _RandomAccessIterator __last) {
105- typedef typename iterator_traits<_RandomAccessIterator>::difference_type difference_type;
106- typedef typename iterator_traits<_RandomAccessIterator>::value_type value_type;
107- using _Ops = _IterOps<_AlgPolicy>;
98+ if (__left == 0 || __first == __last)
99+ return __first;
108100
109- const difference_type __m1 = __middle - __first;
110- const difference_type __m2 = _Ops::distance (__middle, __last);
111- if (__m1 == __m2) {
112- std::__swap_ranges<_AlgPolicy>(__first, __middle, __middle, __last);
101+ if (__left == __right) {
102+ std::__swap_ranges<_AlgPolicy>(__first, __middle, __middle);
113103 return __middle;
114104 }
115- const difference_type __g = std::__algo_gcd (__m1, __m2);
116- for (_RandomAccessIterator __p = __first + __g; __p != __first;) {
117- value_type __t (_Ops::__iter_move (--__p));
118- _RandomAccessIterator __p1 = __p;
119- _RandomAccessIterator __p2 = __p1 + __m1;
120- do {
121- *__p1 = _Ops::__iter_move (__p2);
122- __p1 = __p2;
123- const difference_type __d = _Ops::distance (__p2, __last);
124- if (__m1 < __d)
125- __p2 += __m1;
126- else
127- __p2 = __first + (__m1 - __d);
128- } while (__p2 != __p);
129- *__p1 = std::move (__t );
105+
106+ auto __min_len = std::min (__left, __right);
107+
108+ while (__min_len > 0 ) {
109+ if (__left <= __right) {
110+ do {
111+ std::__swap_ranges<_AlgPolicy>(__first, __first + __left, __first + __left);
112+ __first += __left;
113+ __right -= __left;
114+ } while (__left <= __right);
115+ __min_len = __right;
116+ } else {
117+ do {
118+ std::__swap_ranges<_AlgPolicy>(__first + (__left - __right), __first + __left, __first + __left);
119+ __left -= __right;
120+ } while (__left > __right);
121+ __min_len = __left;
122+ }
130123 }
131- return __first + __m2 ;
124+ return __end ;
132125}
133126
134127template <class _AlgPolicy , class _ForwardIterator >
@@ -170,7 +163,7 @@ inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 _RandomAccessIterator
170163 return std::__rotate_left<_AlgPolicy>(__first, __last);
171164 if (_IterOps<_AlgPolicy>::next (__middle) == __last)
172165 return std::__rotate_right<_AlgPolicy>(__first, __last);
173- return std::__rotate_gcd <_AlgPolicy>(__first, __middle, __last);
166+ return std::__rotate_random <_AlgPolicy>(__first, __middle, __last);
174167 }
175168 return std::__rotate_forward<_AlgPolicy>(__first, __middle, __last);
176169}
0 commit comments