@@ -82,46 +82,39 @@ __rotate_forward(_ForwardIterator __first, _ForwardIterator __middle, _ForwardIt
8282 return __r;
8383}
8484
85- template <typename _Integral>
86- inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 _Integral __algo_gcd (_Integral __x, _Integral __y) {
87- do {
88- _Integral __t = __x % __y;
89- __x = __y;
90- __y = __t ;
91- } while (__y);
92- return __x;
93- }
85+ template <class _AlgPolicy , class _Iter , class _Sent >
86+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 _Iter __rotate_random (_Iter __first, _Iter __middle, _Sent __last) {
87+ auto __left = _IterOps<_AlgPolicy>::distance (__first, __middle);
88+ auto __right = _IterOps<_AlgPolicy>::distance (__middle, __last);
89+ auto __end = __first + __right;
9490
95- template <class _AlgPolicy , typename _RandomAccessIterator>
96- _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 _RandomAccessIterator
97- __rotate_gcd (_RandomAccessIterator __first, _RandomAccessIterator __middle, _RandomAccessIterator __last) {
98- typedef typename iterator_traits<_RandomAccessIterator>::difference_type difference_type;
99- typedef typename iterator_traits<_RandomAccessIterator>::value_type value_type;
100- using _Ops = _IterOps<_AlgPolicy>;
91+ if (__left == 0 || __first == __last)
92+ return __first;
10193
102- const difference_type __m1 = __middle - __first;
103- const difference_type __m2 = _Ops::distance (__middle, __last);
104- if (__m1 == __m2) {
105- std::__swap_ranges<_AlgPolicy>(__first, __middle, __middle, __last);
94+ if (__left == __right) {
95+ std::__swap_ranges<_AlgPolicy>(__first, __middle, __middle);
10696 return __middle;
10797 }
108- const difference_type __g = std::__algo_gcd (__m1, __m2);
109- for (_RandomAccessIterator __p = __first + __g; __p != __first;) {
110- value_type __t (_Ops::__iter_move (--__p));
111- _RandomAccessIterator __p1 = __p;
112- _RandomAccessIterator __p2 = __p1 + __m1;
113- do {
114- *__p1 = _Ops::__iter_move (__p2);
115- __p1 = __p2;
116- const difference_type __d = _Ops::distance (__p2, __last);
117- if (__m1 < __d)
118- __p2 += __m1;
119- else
120- __p2 = __first + (__m1 - __d);
121- } while (__p2 != __p);
122- *__p1 = std::move (__t );
98+
99+ auto __min_len = std::min (__left, __right);
100+
101+ while (__min_len > 0 ) {
102+ if (__left <= __right) {
103+ do {
104+ std::__swap_ranges<_AlgPolicy>(__first, __first + __left, __first + __left);
105+ __first += __left;
106+ __right -= __left;
107+ } while (__left <= __right);
108+ __min_len = __right;
109+ } else {
110+ do {
111+ std::__swap_ranges<_AlgPolicy>(__first + (__left - __right), __first + __left, __first + __left);
112+ __left -= __right;
113+ } while (__left > __right);
114+ __min_len = __left;
115+ }
123116 }
124- return __first + __m2 ;
117+ return __end ;
125118}
126119
127120template <class _AlgPolicy , class _ForwardIterator >
@@ -163,7 +156,7 @@ inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 _RandomAccessIterator
163156 return std::__rotate_left<_AlgPolicy>(__first, __last);
164157 if (_IterOps<_AlgPolicy>::next (__middle) == __last)
165158 return std::__rotate_right<_AlgPolicy>(__first, __last);
166- return std::__rotate_gcd <_AlgPolicy>(__first, __middle, __last);
159+ return std::__rotate_random <_AlgPolicy>(__first, __middle, __last);
167160 }
168161 return std::__rotate_forward<_AlgPolicy>(__first, __middle, __last);
169162}
0 commit comments