6 changes: 3 additions & 3 deletions libcxx/include/__algorithm/move_backward.h
Original file line number Diff line number Diff line change
Expand Up @@ -108,8 +108,7 @@ struct __move_backward_loop {

struct __move_backward_trivial {
// At this point, the iterators have been unwrapped so any `contiguous_iterator` has been unwrapped to a pointer.
template <class _In, class _Out,
__enable_if_t<__can_lower_move_assignment_to_memmove<_In, _Out>::value, int> = 0>
template <class _In, class _Out, __enable_if_t<__can_lower_move_assignment_to_memmove<_In, _Out>::value, int> = 0>
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 pair<_In*, _Out*>
operator()(_In* __first, _In* __last, _Out* __result) const {
return std::__copy_backward_trivial_impl(__first, __last, __result);
Expand All @@ -120,7 +119,8 @@ template <class _AlgPolicy, class _BidirectionalIterator1, class _Sentinel, clas
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 pair<_BidirectionalIterator1, _BidirectionalIterator2>
__move_backward(_BidirectionalIterator1 __first, _Sentinel __last, _BidirectionalIterator2 __result) {
static_assert(std::is_copy_constructible<_BidirectionalIterator1>::value &&
std::is_copy_constructible<_BidirectionalIterator1>::value, "Iterators must be copy constructible.");
std::is_copy_constructible<_BidirectionalIterator1>::value,
"Iterators must be copy constructible.");

return std::__dispatch_copy_or_move<_AlgPolicy, __move_backward_loop<_AlgPolicy>, __move_backward_trivial>(
std::move(__first), std::move(__last), std::move(__result));
Expand Down
61 changes: 27 additions & 34 deletions libcxx/include/__algorithm/next_permutation.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,50 +26,43 @@ _LIBCPP_BEGIN_NAMESPACE_STD

template <class _AlgPolicy, class _Compare, class _BidirectionalIterator, class _Sentinel>
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 pair<_BidirectionalIterator, bool>
__next_permutation(_BidirectionalIterator __first, _Sentinel __last, _Compare&& __comp)
{
using _Result = pair<_BidirectionalIterator, bool>;
__next_permutation(_BidirectionalIterator __first, _Sentinel __last, _Compare&& __comp) {
using _Result = pair<_BidirectionalIterator, bool>;

_BidirectionalIterator __last_iter = _IterOps<_AlgPolicy>::next(__first, __last);
_BidirectionalIterator __i = __last_iter;
if (__first == __last || __first == --__i)
return _Result(std::move(__last_iter), false);
_BidirectionalIterator __last_iter = _IterOps<_AlgPolicy>::next(__first, __last);
_BidirectionalIterator __i = __last_iter;
if (__first == __last || __first == --__i)
return _Result(std::move(__last_iter), false);

while (true)
{
_BidirectionalIterator __ip1 = __i;
if (__comp(*--__i, *__ip1))
{
_BidirectionalIterator __j = __last_iter;
while (!__comp(*__i, *--__j))
;
_IterOps<_AlgPolicy>::iter_swap(__i, __j);
std::__reverse<_AlgPolicy>(__ip1, __last_iter);
return _Result(std::move(__last_iter), true);
}
if (__i == __first)
{
std::__reverse<_AlgPolicy>(__first, __last_iter);
return _Result(std::move(__last_iter), false);
}
while (true) {
_BidirectionalIterator __ip1 = __i;
if (__comp(*--__i, *__ip1)) {
_BidirectionalIterator __j = __last_iter;
while (!__comp(*__i, *--__j))
;
_IterOps<_AlgPolicy>::iter_swap(__i, __j);
std::__reverse<_AlgPolicy>(__ip1, __last_iter);
return _Result(std::move(__last_iter), true);
}
if (__i == __first) {
std::__reverse<_AlgPolicy>(__first, __last_iter);
return _Result(std::move(__last_iter), false);
}
}
}

template <class _BidirectionalIterator, class _Compare>
inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
bool
next_permutation(_BidirectionalIterator __first, _BidirectionalIterator __last, _Compare __comp)
{
inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 bool
next_permutation(_BidirectionalIterator __first, _BidirectionalIterator __last, _Compare __comp) {
return std::__next_permutation<_ClassicAlgPolicy>(
std::move(__first), std::move(__last), static_cast<__comp_ref_type<_Compare> >(__comp)).second;
std::move(__first), std::move(__last), static_cast<__comp_ref_type<_Compare> >(__comp))
.second;
}

template <class _BidirectionalIterator>
inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
bool
next_permutation(_BidirectionalIterator __first, _BidirectionalIterator __last)
{
return std::next_permutation(__first, __last, __less<>());
inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 bool
next_permutation(_BidirectionalIterator __first, _BidirectionalIterator __last) {
return std::next_permutation(__first, __last, __less<>());
}

_LIBCPP_END_NAMESPACE_STD
Expand Down
386 changes: 184 additions & 202 deletions libcxx/include/__algorithm/nth_element.h

Large diffs are not rendered by default.

39 changes: 15 additions & 24 deletions libcxx/include/__algorithm/partial_sort.h
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,7 @@
_LIBCPP_BEGIN_NAMESPACE_STD

template <class _AlgPolicy, class _Compare, class _RandomAccessIterator, class _Sentinel>
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
_RandomAccessIterator __partial_sort_impl(
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _RandomAccessIterator __partial_sort_impl(
_RandomAccessIterator __first, _RandomAccessIterator __middle, _Sentinel __last, _Compare&& __comp) {
if (__first == __middle) {
return _IterOps<_AlgPolicy>::next(__middle, __last);
Expand All @@ -39,26 +38,23 @@ _RandomAccessIterator __partial_sort_impl(
std::__make_heap<_AlgPolicy>(__first, __middle, __comp);

typename iterator_traits<_RandomAccessIterator>::difference_type __len = __middle - __first;
_RandomAccessIterator __i = __middle;
for (; __i != __last; ++__i)
{
if (__comp(*__i, *__first))
{
_IterOps<_AlgPolicy>::iter_swap(__i, __first);
std::__sift_down<_AlgPolicy>(__first, __comp, __len, __first);
}
_RandomAccessIterator __i = __middle;
for (; __i != __last; ++__i) {
if (__comp(*__i, *__first)) {
_IterOps<_AlgPolicy>::iter_swap(__i, __first);
std::__sift_down<_AlgPolicy>(__first, __comp, __len, __first);
}
}
std::__sort_heap<_AlgPolicy>(std::move(__first), std::move(__middle), __comp);

return __i;
}

template <class _AlgPolicy, class _Compare, class _RandomAccessIterator, class _Sentinel>
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
_RandomAccessIterator __partial_sort(_RandomAccessIterator __first, _RandomAccessIterator __middle, _Sentinel __last,
_Compare& __comp) {
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _RandomAccessIterator
__partial_sort(_RandomAccessIterator __first, _RandomAccessIterator __middle, _Sentinel __last, _Compare& __comp) {
if (__first == __middle)
return _IterOps<_AlgPolicy>::next(__middle, __last);
return _IterOps<_AlgPolicy>::next(__middle, __last);

std::__debug_randomize_range<_AlgPolicy>(__first, __last);

Expand All @@ -71,23 +67,18 @@ _RandomAccessIterator __partial_sort(_RandomAccessIterator __first, _RandomAcces
}

template <class _RandomAccessIterator, class _Compare>
inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
void
partial_sort(_RandomAccessIterator __first, _RandomAccessIterator __middle, _RandomAccessIterator __last,
_Compare __comp)
{
inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void partial_sort(
_RandomAccessIterator __first, _RandomAccessIterator __middle, _RandomAccessIterator __last, _Compare __comp) {
static_assert(std::is_copy_constructible<_RandomAccessIterator>::value, "Iterators must be copy constructible.");
static_assert(std::is_copy_assignable<_RandomAccessIterator>::value, "Iterators must be copy assignable.");

(void)std::__partial_sort<_ClassicAlgPolicy>(std::move(__first), std::move(__middle), std::move(__last), __comp);
}

template <class _RandomAccessIterator>
inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
void
partial_sort(_RandomAccessIterator __first, _RandomAccessIterator __middle, _RandomAccessIterator __last)
{
std::partial_sort(__first, __middle, __last, __less<>());
inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void
partial_sort(_RandomAccessIterator __first, _RandomAccessIterator __middle, _RandomAccessIterator __last) {
std::partial_sort(__first, __middle, __last, __less<>());
}

_LIBCPP_END_NAMESPACE_STD
Expand Down
94 changes: 54 additions & 40 deletions libcxx/include/__algorithm/partial_sort_copy.h
Original file line number Diff line number Diff line change
Expand Up @@ -30,56 +30,70 @@

_LIBCPP_BEGIN_NAMESPACE_STD

template <class _AlgPolicy, class _Compare,
class _InputIterator, class _Sentinel1, class _RandomAccessIterator, class _Sentinel2,
class _Proj1, class _Proj2>
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 pair<_InputIterator, _RandomAccessIterator>
__partial_sort_copy(_InputIterator __first, _Sentinel1 __last,
_RandomAccessIterator __result_first, _Sentinel2 __result_last,
_Compare&& __comp, _Proj1&& __proj1, _Proj2&& __proj2)
{
_RandomAccessIterator __r = __result_first;
auto&& __projected_comp = std::__make_projected(__comp, __proj2);
template <class _AlgPolicy,
class _Compare,
class _InputIterator,
class _Sentinel1,
class _RandomAccessIterator,
class _Sentinel2,
class _Proj1,
class _Proj2>
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 pair<_InputIterator, _RandomAccessIterator> __partial_sort_copy(
_InputIterator __first,
_Sentinel1 __last,
_RandomAccessIterator __result_first,
_Sentinel2 __result_last,
_Compare&& __comp,
_Proj1&& __proj1,
_Proj2&& __proj2) {
_RandomAccessIterator __r = __result_first;
auto&& __projected_comp = std::__make_projected(__comp, __proj2);

if (__r != __result_last)
{
for (; __first != __last && __r != __result_last; ++__first, (void) ++__r)
*__r = *__first;
std::__make_heap<_AlgPolicy>(__result_first, __r, __projected_comp);
typename iterator_traits<_RandomAccessIterator>::difference_type __len = __r - __result_first;
for (; __first != __last; ++__first)
if (std::__invoke(__comp, std::__invoke(__proj1, *__first), std::__invoke(__proj2, *__result_first))) {
*__result_first = *__first;
std::__sift_down<_AlgPolicy>(__result_first, __projected_comp, __len, __result_first);
}
std::__sort_heap<_AlgPolicy>(__result_first, __r, __projected_comp);
}
if (__r != __result_last) {
for (; __first != __last && __r != __result_last; ++__first, (void)++__r)
*__r = *__first;
std::__make_heap<_AlgPolicy>(__result_first, __r, __projected_comp);
typename iterator_traits<_RandomAccessIterator>::difference_type __len = __r - __result_first;
for (; __first != __last; ++__first)
if (std::__invoke(__comp, std::__invoke(__proj1, *__first), std::__invoke(__proj2, *__result_first))) {
*__result_first = *__first;
std::__sift_down<_AlgPolicy>(__result_first, __projected_comp, __len, __result_first);
}
std::__sort_heap<_AlgPolicy>(__result_first, __r, __projected_comp);
}

return pair<_InputIterator, _RandomAccessIterator>(
_IterOps<_AlgPolicy>::next(std::move(__first), std::move(__last)), std::move(__r));
return pair<_InputIterator, _RandomAccessIterator>(
_IterOps<_AlgPolicy>::next(std::move(__first), std::move(__last)), std::move(__r));
}

template <class _InputIterator, class _RandomAccessIterator, class _Compare>
inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
_RandomAccessIterator
partial_sort_copy(_InputIterator __first, _InputIterator __last,
_RandomAccessIterator __result_first, _RandomAccessIterator __result_last, _Compare __comp)
{
static_assert(__is_callable<_Compare, decltype(*__first), decltype(*__result_first)>::value,
"Comparator has to be callable");
inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _RandomAccessIterator partial_sort_copy(
_InputIterator __first,
_InputIterator __last,
_RandomAccessIterator __result_first,
_RandomAccessIterator __result_last,
_Compare __comp) {
static_assert(
__is_callable<_Compare, decltype(*__first), decltype(*__result_first)>::value, "Comparator has to be callable");

auto __result = std::__partial_sort_copy<_ClassicAlgPolicy>(__first, __last, __result_first, __result_last,
static_cast<__comp_ref_type<_Compare> >(__comp), __identity(), __identity());
auto __result = std::__partial_sort_copy<_ClassicAlgPolicy>(
__first,
__last,
__result_first,
__result_last,
static_cast<__comp_ref_type<_Compare> >(__comp),
__identity(),
__identity());
return __result.second;
}

template <class _InputIterator, class _RandomAccessIterator>
inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
_RandomAccessIterator
partial_sort_copy(_InputIterator __first, _InputIterator __last,
_RandomAccessIterator __result_first, _RandomAccessIterator __result_last)
{
return std::partial_sort_copy(__first, __last, __result_first, __result_last, __less<>());
inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _RandomAccessIterator partial_sort_copy(
_InputIterator __first,
_InputIterator __last,
_RandomAccessIterator __result_first,
_RandomAccessIterator __result_last) {
return std::partial_sort_copy(__first, __last, __result_first, __result_last, __less<>());
}

_LIBCPP_END_NAMESPACE_STD
Expand Down
84 changes: 36 additions & 48 deletions libcxx/include/__algorithm/partition.h
Original file line number Diff line number Diff line change
Expand Up @@ -23,70 +23,58 @@ _LIBCPP_BEGIN_NAMESPACE_STD

template <class _Predicate, class _AlgPolicy, class _ForwardIterator, class _Sentinel>
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 pair<_ForwardIterator, _ForwardIterator>
__partition_impl(_ForwardIterator __first, _Sentinel __last, _Predicate __pred, forward_iterator_tag)
{
while (true)
{
if (__first == __last)
return std::make_pair(std::move(__first), std::move(__first));
if (!__pred(*__first))
break;
++__first;
}
__partition_impl(_ForwardIterator __first, _Sentinel __last, _Predicate __pred, forward_iterator_tag) {
while (true) {
if (__first == __last)
return std::make_pair(std::move(__first), std::move(__first));
if (!__pred(*__first))
break;
++__first;
}

_ForwardIterator __p = __first;
while (++__p != __last)
{
if (__pred(*__p))
{
_IterOps<_AlgPolicy>::iter_swap(__first, __p);
++__first;
}
_ForwardIterator __p = __first;
while (++__p != __last) {
if (__pred(*__p)) {
_IterOps<_AlgPolicy>::iter_swap(__first, __p);
++__first;
}
return std::make_pair(std::move(__first), std::move(__p));
}
return std::make_pair(std::move(__first), std::move(__p));
}

template <class _Predicate, class _AlgPolicy, class _BidirectionalIterator, class _Sentinel>
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 pair<_BidirectionalIterator, _BidirectionalIterator>
__partition_impl(_BidirectionalIterator __first, _Sentinel __sentinel, _Predicate __pred,
bidirectional_iterator_tag)
{
_BidirectionalIterator __original_last = _IterOps<_AlgPolicy>::next(__first, __sentinel);
_BidirectionalIterator __last = __original_last;
__partition_impl(_BidirectionalIterator __first, _Sentinel __sentinel, _Predicate __pred, bidirectional_iterator_tag) {
_BidirectionalIterator __original_last = _IterOps<_AlgPolicy>::next(__first, __sentinel);
_BidirectionalIterator __last = __original_last;

while (true)
{
while (true)
{
if (__first == __last)
return std::make_pair(std::move(__first), std::move(__original_last));
if (!__pred(*__first))
break;
++__first;
}
do
{
if (__first == --__last)
return std::make_pair(std::move(__first), std::move(__original_last));
} while (!__pred(*__last));
_IterOps<_AlgPolicy>::iter_swap(__first, __last);
++__first;
while (true) {
while (true) {
if (__first == __last)
return std::make_pair(std::move(__first), std::move(__original_last));
if (!__pred(*__first))
break;
++__first;
}
do {
if (__first == --__last)
return std::make_pair(std::move(__first), std::move(__original_last));
} while (!__pred(*__last));
_IterOps<_AlgPolicy>::iter_swap(__first, __last);
++__first;
}
}

template <class _AlgPolicy, class _ForwardIterator, class _Sentinel, class _Predicate, class _IterCategory>
inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
pair<_ForwardIterator, _ForwardIterator> __partition(
_ForwardIterator __first, _Sentinel __last, _Predicate&& __pred, _IterCategory __iter_category) {
inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 pair<_ForwardIterator, _ForwardIterator>
__partition(_ForwardIterator __first, _Sentinel __last, _Predicate&& __pred, _IterCategory __iter_category) {
return std::__partition_impl<__remove_cvref_t<_Predicate>&, _AlgPolicy>(
std::move(__first), std::move(__last), __pred, __iter_category);
}

template <class _ForwardIterator, class _Predicate>
inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
_ForwardIterator
partition(_ForwardIterator __first, _ForwardIterator __last, _Predicate __pred)
{
inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _ForwardIterator
partition(_ForwardIterator __first, _ForwardIterator __last, _Predicate __pred) {
using _IterCategory = typename iterator_traits<_ForwardIterator>::iterator_category;
auto __result = std::__partition<_ClassicAlgPolicy>(std::move(__first), std::move(__last), __pred, _IterCategory());
return __result.first;
Expand Down
36 changes: 16 additions & 20 deletions libcxx/include/__algorithm/partition_copy.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,27 +19,23 @@

_LIBCPP_BEGIN_NAMESPACE_STD

template <class _InputIterator, class _OutputIterator1,
class _OutputIterator2, class _Predicate>
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 pair<_OutputIterator1, _OutputIterator2>
partition_copy(_InputIterator __first, _InputIterator __last,
_OutputIterator1 __out_true, _OutputIterator2 __out_false,
_Predicate __pred)
{
for (; __first != __last; ++__first)
{
if (__pred(*__first))
{
*__out_true = *__first;
++__out_true;
}
else
{
*__out_false = *__first;
++__out_false;
}
template <class _InputIterator, class _OutputIterator1, class _OutputIterator2, class _Predicate>
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 pair<_OutputIterator1, _OutputIterator2> partition_copy(
_InputIterator __first,
_InputIterator __last,
_OutputIterator1 __out_true,
_OutputIterator2 __out_false,
_Predicate __pred) {
for (; __first != __last; ++__first) {
if (__pred(*__first)) {
*__out_true = *__first;
++__out_true;
} else {
*__out_false = *__first;
++__out_false;
}
return pair<_OutputIterator1, _OutputIterator2>(__out_true, __out_false);
}
return pair<_OutputIterator1, _OutputIterator2>(__out_true, __out_false);
}

_LIBCPP_END_NAMESPACE_STD
Expand Down
34 changes: 15 additions & 19 deletions libcxx/include/__algorithm/partition_point.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,26 +21,22 @@

_LIBCPP_BEGIN_NAMESPACE_STD

template<class _ForwardIterator, class _Predicate>
template <class _ForwardIterator, class _Predicate>
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _ForwardIterator
partition_point(_ForwardIterator __first, _ForwardIterator __last, _Predicate __pred)
{
typedef typename iterator_traits<_ForwardIterator>::difference_type difference_type;
difference_type __len = std::distance(__first, __last);
while (__len != 0)
{
difference_type __l2 = std::__half_positive(__len);
_ForwardIterator __m = __first;
std::advance(__m, __l2);
if (__pred(*__m))
{
__first = ++__m;
__len -= __l2 + 1;
}
else
__len = __l2;
}
return __first;
partition_point(_ForwardIterator __first, _ForwardIterator __last, _Predicate __pred) {
typedef typename iterator_traits<_ForwardIterator>::difference_type difference_type;
difference_type __len = std::distance(__first, __last);
while (__len != 0) {
difference_type __l2 = std::__half_positive(__len);
_ForwardIterator __m = __first;
std::advance(__m, __l2);
if (__pred(*__m)) {
__first = ++__m;
__len -= __l2 + 1;
} else
__len = __l2;
}
return __first;
}

_LIBCPP_END_NAMESPACE_STD
Expand Down
18 changes: 10 additions & 8 deletions libcxx/include/__algorithm/pop_heap.h
Original file line number Diff line number Diff line change
Expand Up @@ -31,16 +31,18 @@ _LIBCPP_PUSH_MACROS
_LIBCPP_BEGIN_NAMESPACE_STD

template <class _AlgPolicy, class _Compare, class _RandomAccessIterator>
inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14
void __pop_heap(_RandomAccessIterator __first, _RandomAccessIterator __last, _Compare& __comp,
typename iterator_traits<_RandomAccessIterator>::difference_type __len) {
inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 void
__pop_heap(_RandomAccessIterator __first,
_RandomAccessIterator __last,
_Compare& __comp,
typename iterator_traits<_RandomAccessIterator>::difference_type __len) {
_LIBCPP_ASSERT_UNCATEGORIZED(__len > 0, "The heap given to pop_heap must be non-empty");

__comp_ref_type<_Compare> __comp_ref = __comp;

using value_type = typename iterator_traits<_RandomAccessIterator>::value_type;
if (__len > 1) {
value_type __top = _IterOps<_AlgPolicy>::__iter_move(__first); // create a hole at __first
value_type __top = _IterOps<_AlgPolicy>::__iter_move(__first); // create a hole at __first
_RandomAccessIterator __hole = std::__floyd_sift_down<_AlgPolicy>(__first, __comp_ref, __len);
--__last;

Expand All @@ -56,8 +58,8 @@ void __pop_heap(_RandomAccessIterator __first, _RandomAccessIterator __last, _Co
}

template <class _RandomAccessIterator, class _Compare>
inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
void pop_heap(_RandomAccessIterator __first, _RandomAccessIterator __last, _Compare __comp) {
inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void
pop_heap(_RandomAccessIterator __first, _RandomAccessIterator __last, _Compare __comp) {
static_assert(std::is_copy_constructible<_RandomAccessIterator>::value, "Iterators must be copy constructible.");
static_assert(std::is_copy_assignable<_RandomAccessIterator>::value, "Iterators must be copy assignable.");

Expand All @@ -66,8 +68,8 @@ void pop_heap(_RandomAccessIterator __first, _RandomAccessIterator __last, _Comp
}

template <class _RandomAccessIterator>
inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
void pop_heap(_RandomAccessIterator __first, _RandomAccessIterator __last) {
inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void
pop_heap(_RandomAccessIterator __first, _RandomAccessIterator __last) {
std::pop_heap(std::move(__first), std::move(__last), __less<>());
}

Expand Down
64 changes: 28 additions & 36 deletions libcxx/include/__algorithm/prev_permutation.h
Original file line number Diff line number Diff line change
Expand Up @@ -25,52 +25,44 @@
_LIBCPP_BEGIN_NAMESPACE_STD

template <class _AlgPolicy, class _Compare, class _BidirectionalIterator, class _Sentinel>
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
pair<_BidirectionalIterator, bool>
__prev_permutation(_BidirectionalIterator __first, _Sentinel __last, _Compare&& __comp)
{
using _Result = pair<_BidirectionalIterator, bool>;
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 pair<_BidirectionalIterator, bool>
__prev_permutation(_BidirectionalIterator __first, _Sentinel __last, _Compare&& __comp) {
using _Result = pair<_BidirectionalIterator, bool>;

_BidirectionalIterator __last_iter = _IterOps<_AlgPolicy>::next(__first, __last);
_BidirectionalIterator __i = __last_iter;
if (__first == __last || __first == --__i)
return _Result(std::move(__last_iter), false);
_BidirectionalIterator __last_iter = _IterOps<_AlgPolicy>::next(__first, __last);
_BidirectionalIterator __i = __last_iter;
if (__first == __last || __first == --__i)
return _Result(std::move(__last_iter), false);

while (true)
{
_BidirectionalIterator __ip1 = __i;
if (__comp(*__ip1, *--__i))
{
_BidirectionalIterator __j = __last_iter;
while (!__comp(*--__j, *__i))
;
_IterOps<_AlgPolicy>::iter_swap(__i, __j);
std::__reverse<_AlgPolicy>(__ip1, __last_iter);
return _Result(std::move(__last_iter), true);
}
if (__i == __first)
{
std::__reverse<_AlgPolicy>(__first, __last_iter);
return _Result(std::move(__last_iter), false);
}
while (true) {
_BidirectionalIterator __ip1 = __i;
if (__comp(*__ip1, *--__i)) {
_BidirectionalIterator __j = __last_iter;
while (!__comp(*--__j, *__i))
;
_IterOps<_AlgPolicy>::iter_swap(__i, __j);
std::__reverse<_AlgPolicy>(__ip1, __last_iter);
return _Result(std::move(__last_iter), true);
}
if (__i == __first) {
std::__reverse<_AlgPolicy>(__first, __last_iter);
return _Result(std::move(__last_iter), false);
}
}
}

template <class _BidirectionalIterator, class _Compare>
inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
bool
prev_permutation(_BidirectionalIterator __first, _BidirectionalIterator __last, _Compare __comp)
{
inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 bool
prev_permutation(_BidirectionalIterator __first, _BidirectionalIterator __last, _Compare __comp) {
return std::__prev_permutation<_ClassicAlgPolicy>(
std::move(__first), std::move(__last), static_cast<__comp_ref_type<_Compare> >(__comp)).second;
std::move(__first), std::move(__last), static_cast<__comp_ref_type<_Compare> >(__comp))
.second;
}

template <class _BidirectionalIterator>
inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
bool
prev_permutation(_BidirectionalIterator __first, _BidirectionalIterator __last)
{
return std::prev_permutation(__first, __last, __less<>());
inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 bool
prev_permutation(_BidirectionalIterator __first, _BidirectionalIterator __last) {
return std::prev_permutation(__first, __last, __less<>());
}

_LIBCPP_END_NAMESPACE_STD
Expand Down
24 changes: 13 additions & 11 deletions libcxx/include/__algorithm/push_heap.h
Original file line number Diff line number Diff line change
Expand Up @@ -28,20 +28,22 @@ _LIBCPP_PUSH_MACROS
_LIBCPP_BEGIN_NAMESPACE_STD

template <class _AlgPolicy, class _Compare, class _RandomAccessIterator>
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14
void __sift_up(_RandomAccessIterator __first, _RandomAccessIterator __last, _Compare&& __comp,
typename iterator_traits<_RandomAccessIterator>::difference_type __len) {
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 void
__sift_up(_RandomAccessIterator __first,
_RandomAccessIterator __last,
_Compare&& __comp,
typename iterator_traits<_RandomAccessIterator>::difference_type __len) {
using value_type = typename iterator_traits<_RandomAccessIterator>::value_type;

if (__len > 1) {
__len = (__len - 2) / 2;
__len = (__len - 2) / 2;
_RandomAccessIterator __ptr = __first + __len;

if (__comp(*__ptr, *--__last)) {
value_type __t(_IterOps<_AlgPolicy>::__iter_move(__last));
do {
*__last = _IterOps<_AlgPolicy>::__iter_move(__ptr);
__last = __ptr;
__last = __ptr;
if (__len == 0)
break;
__len = (__len - 1) / 2;
Expand All @@ -54,24 +56,24 @@ void __sift_up(_RandomAccessIterator __first, _RandomAccessIterator __last, _Com
}

template <class _AlgPolicy, class _RandomAccessIterator, class _Compare>
inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14
void __push_heap(_RandomAccessIterator __first, _RandomAccessIterator __last, _Compare& __comp) {
inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 void
__push_heap(_RandomAccessIterator __first, _RandomAccessIterator __last, _Compare& __comp) {
typename iterator_traits<_RandomAccessIterator>::difference_type __len = __last - __first;
std::__sift_up<_AlgPolicy, __comp_ref_type<_Compare> >(std::move(__first), std::move(__last), __comp, __len);
}

template <class _RandomAccessIterator, class _Compare>
inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
void push_heap(_RandomAccessIterator __first, _RandomAccessIterator __last, _Compare __comp) {
inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void
push_heap(_RandomAccessIterator __first, _RandomAccessIterator __last, _Compare __comp) {
static_assert(std::is_copy_constructible<_RandomAccessIterator>::value, "Iterators must be copy constructible.");
static_assert(std::is_copy_assignable<_RandomAccessIterator>::value, "Iterators must be copy assignable.");

std::__push_heap<_ClassicAlgPolicy>(std::move(__first), std::move(__last), __comp);
}

template <class _RandomAccessIterator>
inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
void push_heap(_RandomAccessIterator __first, _RandomAccessIterator __last) {
inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void
push_heap(_RandomAccessIterator __first, _RandomAccessIterator __last) {
std::push_heap(std::move(__first), std::move(__last), __less<>());
}

Expand Down
26 changes: 11 additions & 15 deletions libcxx/include/__algorithm/remove.h
Original file line number Diff line number Diff line change
Expand Up @@ -22,22 +22,18 @@ _LIBCPP_BEGIN_NAMESPACE_STD

template <class _ForwardIterator, class _Tp>
_LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _ForwardIterator
remove(_ForwardIterator __first, _ForwardIterator __last, const _Tp& __value)
{
__first = std::find(__first, __last, __value);
if (__first != __last)
{
_ForwardIterator __i = __first;
while (++__i != __last)
{
if (!(*__i == __value))
{
*__first = std::move(*__i);
++__first;
}
}
remove(_ForwardIterator __first, _ForwardIterator __last, const _Tp& __value) {
__first = std::find(__first, __last, __value);
if (__first != __last) {
_ForwardIterator __i = __first;
while (++__i != __last) {
if (!(*__i == __value)) {
*__first = std::move(*__i);
++__first;
}
}
return __first;
}
return __first;
}

_LIBCPP_END_NAMESPACE_STD
Expand Down
20 changes: 8 additions & 12 deletions libcxx/include/__algorithm/remove_copy.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,19 +18,15 @@
_LIBCPP_BEGIN_NAMESPACE_STD

template <class _InputIterator, class _OutputIterator, class _Tp>
inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
_OutputIterator
remove_copy(_InputIterator __first, _InputIterator __last, _OutputIterator __result, const _Tp& __value)
{
for (; __first != __last; ++__first)
{
if (!(*__first == __value))
{
*__result = *__first;
++__result;
}
inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _OutputIterator
remove_copy(_InputIterator __first, _InputIterator __last, _OutputIterator __result, const _Tp& __value) {
for (; __first != __last; ++__first) {
if (!(*__first == __value)) {
*__result = *__first;
++__result;
}
return __result;
}
return __result;
}

_LIBCPP_END_NAMESPACE_STD
Expand Down
20 changes: 8 additions & 12 deletions libcxx/include/__algorithm/remove_copy_if.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,19 +18,15 @@
_LIBCPP_BEGIN_NAMESPACE_STD

template <class _InputIterator, class _OutputIterator, class _Predicate>
inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
_OutputIterator
remove_copy_if(_InputIterator __first, _InputIterator __last, _OutputIterator __result, _Predicate __pred)
{
for (; __first != __last; ++__first)
{
if (!__pred(*__first))
{
*__result = *__first;
++__result;
}
inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _OutputIterator
remove_copy_if(_InputIterator __first, _InputIterator __last, _OutputIterator __result, _Predicate __pred) {
for (; __first != __last; ++__first) {
if (!__pred(*__first)) {
*__result = *__first;
++__result;
}
return __result;
}
return __result;
}

_LIBCPP_END_NAMESPACE_STD
Expand Down
26 changes: 11 additions & 15 deletions libcxx/include/__algorithm/remove_if.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,22 +21,18 @@ _LIBCPP_BEGIN_NAMESPACE_STD

template <class _ForwardIterator, class _Predicate>
_LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _ForwardIterator
remove_if(_ForwardIterator __first, _ForwardIterator __last, _Predicate __pred)
{
__first = std::find_if<_ForwardIterator, _Predicate&>(__first, __last, __pred);
if (__first != __last)
{
_ForwardIterator __i = __first;
while (++__i != __last)
{
if (!__pred(*__i))
{
*__first = std::move(*__i);
++__first;
}
}
remove_if(_ForwardIterator __first, _ForwardIterator __last, _Predicate __pred) {
__first = std::find_if<_ForwardIterator, _Predicate&>(__first, __last, __pred);
if (__first != __last) {
_ForwardIterator __i = __first;
while (++__i != __last) {
if (!__pred(*__i)) {
*__first = std::move(*__i);
++__first;
}
}
return __first;
}
return __first;
}

_LIBCPP_END_NAMESPACE_STD
Expand Down
12 changes: 5 additions & 7 deletions libcxx/include/__algorithm/replace.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,13 +18,11 @@
_LIBCPP_BEGIN_NAMESPACE_STD

template <class _ForwardIterator, class _Tp>
inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
void
replace(_ForwardIterator __first, _ForwardIterator __last, const _Tp& __old_value, const _Tp& __new_value)
{
for (; __first != __last; ++__first)
if (*__first == __old_value)
*__first = __new_value;
inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void
replace(_ForwardIterator __first, _ForwardIterator __last, const _Tp& __old_value, const _Tp& __new_value) {
for (; __first != __last; ++__first)
if (*__first == __old_value)
*__first = __new_value;
}

_LIBCPP_END_NAMESPACE_STD
Expand Down
23 changes: 12 additions & 11 deletions libcxx/include/__algorithm/replace_copy.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,17 +18,18 @@
_LIBCPP_BEGIN_NAMESPACE_STD

template <class _InputIterator, class _OutputIterator, class _Tp>
inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
_OutputIterator
replace_copy(_InputIterator __first, _InputIterator __last, _OutputIterator __result,
const _Tp& __old_value, const _Tp& __new_value)
{
for (; __first != __last; ++__first, (void) ++__result)
if (*__first == __old_value)
*__result = __new_value;
else
*__result = *__first;
return __result;
inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _OutputIterator replace_copy(
_InputIterator __first,
_InputIterator __last,
_OutputIterator __result,
const _Tp& __old_value,
const _Tp& __new_value) {
for (; __first != __last; ++__first, (void)++__result)
if (*__first == __old_value)
*__result = __new_value;
else
*__result = *__first;
return __result;
}

_LIBCPP_END_NAMESPACE_STD
Expand Down
23 changes: 12 additions & 11 deletions libcxx/include/__algorithm/replace_copy_if.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,17 +18,18 @@
_LIBCPP_BEGIN_NAMESPACE_STD

template <class _InputIterator, class _OutputIterator, class _Predicate, class _Tp>
inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
_OutputIterator
replace_copy_if(_InputIterator __first, _InputIterator __last, _OutputIterator __result,
_Predicate __pred, const _Tp& __new_value)
{
for (; __first != __last; ++__first, (void) ++__result)
if (__pred(*__first))
*__result = __new_value;
else
*__result = *__first;
return __result;
inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _OutputIterator replace_copy_if(
_InputIterator __first,
_InputIterator __last,
_OutputIterator __result,
_Predicate __pred,
const _Tp& __new_value) {
for (; __first != __last; ++__first, (void)++__result)
if (__pred(*__first))
*__result = __new_value;
else
*__result = *__first;
return __result;
}

_LIBCPP_END_NAMESPACE_STD
Expand Down
12 changes: 5 additions & 7 deletions libcxx/include/__algorithm/replace_if.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,13 +18,11 @@
_LIBCPP_BEGIN_NAMESPACE_STD

template <class _ForwardIterator, class _Predicate, class _Tp>
inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
void
replace_if(_ForwardIterator __first, _ForwardIterator __last, _Predicate __pred, const _Tp& __new_value)
{
for (; __first != __last; ++__first)
if (__pred(*__first))
*__first = __new_value;
inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void
replace_if(_ForwardIterator __first, _ForwardIterator __last, _Predicate __pred, const _Tp& __new_value) {
for (; __first != __last; ++__first)
if (__pred(*__first))
*__first = __new_value;
}

_LIBCPP_END_NAMESPACE_STD
Expand Down
40 changes: 16 additions & 24 deletions libcxx/include/__algorithm/reverse.h
Original file line number Diff line number Diff line change
Expand Up @@ -22,41 +22,33 @@
_LIBCPP_BEGIN_NAMESPACE_STD

template <class _AlgPolicy, class _BidirectionalIterator>
inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
void
__reverse_impl(_BidirectionalIterator __first, _BidirectionalIterator __last, bidirectional_iterator_tag)
{
while (__first != __last)
{
if (__first == --__last)
break;
_IterOps<_AlgPolicy>::iter_swap(__first, __last);
++__first;
}
inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void
__reverse_impl(_BidirectionalIterator __first, _BidirectionalIterator __last, bidirectional_iterator_tag) {
while (__first != __last) {
if (__first == --__last)
break;
_IterOps<_AlgPolicy>::iter_swap(__first, __last);
++__first;
}
}

template <class _AlgPolicy, class _RandomAccessIterator>
inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
void
__reverse_impl(_RandomAccessIterator __first, _RandomAccessIterator __last, random_access_iterator_tag)
{
if (__first != __last)
for (; __first < --__last; ++__first)
_IterOps<_AlgPolicy>::iter_swap(__first, __last);
inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void
__reverse_impl(_RandomAccessIterator __first, _RandomAccessIterator __last, random_access_iterator_tag) {
if (__first != __last)
for (; __first < --__last; ++__first)
_IterOps<_AlgPolicy>::iter_swap(__first, __last);
}

template <class _AlgPolicy, class _BidirectionalIterator, class _Sentinel>
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
void __reverse(_BidirectionalIterator __first, _Sentinel __last) {
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void __reverse(_BidirectionalIterator __first, _Sentinel __last) {
using _IterCategory = typename _IterOps<_AlgPolicy>::template __iterator_category<_BidirectionalIterator>;
std::__reverse_impl<_AlgPolicy>(std::move(__first), std::move(__last), _IterCategory());
}

template <class _BidirectionalIterator>
inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
void
reverse(_BidirectionalIterator __first, _BidirectionalIterator __last)
{
inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void
reverse(_BidirectionalIterator __first, _BidirectionalIterator __last) {
std::__reverse<_ClassicAlgPolicy>(std::move(__first), std::move(__last));
}

Expand Down
12 changes: 5 additions & 7 deletions libcxx/include/__algorithm/reverse_copy.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,13 +18,11 @@
_LIBCPP_BEGIN_NAMESPACE_STD

template <class _BidirectionalIterator, class _OutputIterator>
inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
_OutputIterator
reverse_copy(_BidirectionalIterator __first, _BidirectionalIterator __last, _OutputIterator __result)
{
for (; __first != __last; ++__result)
*__result = *--__last;
return __result;
inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _OutputIterator
reverse_copy(_BidirectionalIterator __first, _BidirectionalIterator __last, _OutputIterator __result) {
for (; __first != __last; ++__result)
*__result = *--__last;
return __result;
}

_LIBCPP_END_NAMESPACE_STD
Expand Down
264 changes: 118 additions & 146 deletions libcxx/include/__algorithm/rotate.h
Original file line number Diff line number Diff line change
Expand Up @@ -27,193 +27,165 @@ _LIBCPP_BEGIN_NAMESPACE_STD

template <class _AlgPolicy, class _ForwardIterator>
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 _ForwardIterator
__rotate_left(_ForwardIterator __first, _ForwardIterator __last)
{
typedef typename iterator_traits<_ForwardIterator>::value_type value_type;
using _Ops = _IterOps<_AlgPolicy>;

value_type __tmp = _Ops::__iter_move(__first);
_ForwardIterator __lm1 = std::__move<_AlgPolicy>(
_Ops::next(__first), __last, __first).second;
*__lm1 = std::move(__tmp);
return __lm1;
__rotate_left(_ForwardIterator __first, _ForwardIterator __last) {
typedef typename iterator_traits<_ForwardIterator>::value_type value_type;
using _Ops = _IterOps<_AlgPolicy>;

value_type __tmp = _Ops::__iter_move(__first);
_ForwardIterator __lm1 = std::__move<_AlgPolicy>(_Ops::next(__first), __last, __first).second;
*__lm1 = std::move(__tmp);
return __lm1;
}

template <class _AlgPolicy, class _BidirectionalIterator>
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 _BidirectionalIterator
__rotate_right(_BidirectionalIterator __first, _BidirectionalIterator __last)
{
typedef typename iterator_traits<_BidirectionalIterator>::value_type value_type;
using _Ops = _IterOps<_AlgPolicy>;

_BidirectionalIterator __lm1 = _Ops::prev(__last);
value_type __tmp = _Ops::__iter_move(__lm1);
_BidirectionalIterator __fp1 = std::__move_backward<_AlgPolicy>(__first, __lm1, std::move(__last)).second;
*__first = std::move(__tmp);
return __fp1;
__rotate_right(_BidirectionalIterator __first, _BidirectionalIterator __last) {
typedef typename iterator_traits<_BidirectionalIterator>::value_type value_type;
using _Ops = _IterOps<_AlgPolicy>;

_BidirectionalIterator __lm1 = _Ops::prev(__last);
value_type __tmp = _Ops::__iter_move(__lm1);
_BidirectionalIterator __fp1 = std::__move_backward<_AlgPolicy>(__first, __lm1, std::move(__last)).second;
*__first = std::move(__tmp);
return __fp1;
}

template <class _AlgPolicy, class _ForwardIterator>
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 _ForwardIterator
__rotate_forward(_ForwardIterator __first, _ForwardIterator __middle, _ForwardIterator __last)
{
_ForwardIterator __i = __middle;
while (true)
{
_IterOps<_AlgPolicy>::iter_swap(__first, __i);
++__first;
if (++__i == __last)
break;
__rotate_forward(_ForwardIterator __first, _ForwardIterator __middle, _ForwardIterator __last) {
_ForwardIterator __i = __middle;
while (true) {
_IterOps<_AlgPolicy>::iter_swap(__first, __i);
++__first;
if (++__i == __last)
break;
if (__first == __middle)
__middle = __i;
}
_ForwardIterator __r = __first;
if (__first != __middle) {
__i = __middle;
while (true) {
_IterOps<_AlgPolicy>::iter_swap(__first, __i);
++__first;
if (++__i == __last) {
if (__first == __middle)
__middle = __i;
}
_ForwardIterator __r = __first;
if (__first != __middle)
{
break;
__i = __middle;
while (true)
{
_IterOps<_AlgPolicy>::iter_swap(__first, __i);
++__first;
if (++__i == __last)
{
if (__first == __middle)
break;
__i = __middle;
}
else if (__first == __middle)
__middle = __i;
}
} else if (__first == __middle)
__middle = __i;
}
return __r;
}
return __r;
}

template<typename _Integral>
inline _LIBCPP_HIDE_FROM_ABI
_LIBCPP_CONSTEXPR_SINCE_CXX17 _Integral
__algo_gcd(_Integral __x, _Integral __y)
{
do
{
_Integral __t = __x % __y;
__x = __y;
__y = __t;
} while (__y);
return __x;
template <typename _Integral>
inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 _Integral __algo_gcd(_Integral __x, _Integral __y) {
do {
_Integral __t = __x % __y;
__x = __y;
__y = __t;
} while (__y);
return __x;
}

template <class _AlgPolicy, typename _RandomAccessIterator>
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 _RandomAccessIterator
__rotate_gcd(_RandomAccessIterator __first, _RandomAccessIterator __middle, _RandomAccessIterator __last)
{
typedef typename iterator_traits<_RandomAccessIterator>::difference_type difference_type;
typedef typename iterator_traits<_RandomAccessIterator>::value_type value_type;
using _Ops = _IterOps<_AlgPolicy>;

const difference_type __m1 = __middle - __first;
const difference_type __m2 = _Ops::distance(__middle, __last);
if (__m1 == __m2)
{
std::__swap_ranges<_AlgPolicy>(__first, __middle, __middle, __last);
return __middle;
}
const difference_type __g = std::__algo_gcd(__m1, __m2);
for (_RandomAccessIterator __p = __first + __g; __p != __first;)
{
value_type __t(_Ops::__iter_move(--__p));
_RandomAccessIterator __p1 = __p;
_RandomAccessIterator __p2 = __p1 + __m1;
do
{
*__p1 = _Ops::__iter_move(__p2);
__p1 = __p2;
const difference_type __d = _Ops::distance(__p2, __last);
if (__m1 < __d)
__p2 += __m1;
else
__p2 = __first + (__m1 - __d);
} while (__p2 != __p);
*__p1 = std::move(__t);
}
return __first + __m2;
__rotate_gcd(_RandomAccessIterator __first, _RandomAccessIterator __middle, _RandomAccessIterator __last) {
typedef typename iterator_traits<_RandomAccessIterator>::difference_type difference_type;
typedef typename iterator_traits<_RandomAccessIterator>::value_type value_type;
using _Ops = _IterOps<_AlgPolicy>;

const difference_type __m1 = __middle - __first;
const difference_type __m2 = _Ops::distance(__middle, __last);
if (__m1 == __m2) {
std::__swap_ranges<_AlgPolicy>(__first, __middle, __middle, __last);
return __middle;
}
const difference_type __g = std::__algo_gcd(__m1, __m2);
for (_RandomAccessIterator __p = __first + __g; __p != __first;) {
value_type __t(_Ops::__iter_move(--__p));
_RandomAccessIterator __p1 = __p;
_RandomAccessIterator __p2 = __p1 + __m1;
do {
*__p1 = _Ops::__iter_move(__p2);
__p1 = __p2;
const difference_type __d = _Ops::distance(__p2, __last);
if (__m1 < __d)
__p2 += __m1;
else
__p2 = __first + (__m1 - __d);
} while (__p2 != __p);
*__p1 = std::move(__t);
}
return __first + __m2;
}

template <class _AlgPolicy, class _ForwardIterator>
inline _LIBCPP_HIDE_FROM_ABI
_LIBCPP_CONSTEXPR_SINCE_CXX14 _ForwardIterator
__rotate_impl(_ForwardIterator __first, _ForwardIterator __middle, _ForwardIterator __last,
std::forward_iterator_tag)
{
typedef typename iterator_traits<_ForwardIterator>::value_type value_type;
if (is_trivially_move_assignable<value_type>::value)
{
if (_IterOps<_AlgPolicy>::next(__first) == __middle)
return std::__rotate_left<_AlgPolicy>(__first, __last);
}
return std::__rotate_forward<_AlgPolicy>(__first, __middle, __last);
inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 _ForwardIterator
__rotate_impl(_ForwardIterator __first, _ForwardIterator __middle, _ForwardIterator __last, std::forward_iterator_tag) {
typedef typename iterator_traits<_ForwardIterator>::value_type value_type;
if (is_trivially_move_assignable<value_type>::value) {
if (_IterOps<_AlgPolicy>::next(__first) == __middle)
return std::__rotate_left<_AlgPolicy>(__first, __last);
}
return std::__rotate_forward<_AlgPolicy>(__first, __middle, __last);
}

template <class _AlgPolicy, class _BidirectionalIterator>
inline _LIBCPP_HIDE_FROM_ABI
_LIBCPP_CONSTEXPR_SINCE_CXX14 _BidirectionalIterator
__rotate_impl(_BidirectionalIterator __first, _BidirectionalIterator __middle, _BidirectionalIterator __last,
bidirectional_iterator_tag)
{
typedef typename iterator_traits<_BidirectionalIterator>::value_type value_type;
if (is_trivially_move_assignable<value_type>::value)
{
if (_IterOps<_AlgPolicy>::next(__first) == __middle)
return std::__rotate_left<_AlgPolicy>(__first, __last);
if (_IterOps<_AlgPolicy>::next(__middle) == __last)
return std::__rotate_right<_AlgPolicy>(__first, __last);
}
return std::__rotate_forward<_AlgPolicy>(__first, __middle, __last);
inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 _BidirectionalIterator __rotate_impl(
_BidirectionalIterator __first,
_BidirectionalIterator __middle,
_BidirectionalIterator __last,
bidirectional_iterator_tag) {
typedef typename iterator_traits<_BidirectionalIterator>::value_type value_type;
if (is_trivially_move_assignable<value_type>::value) {
if (_IterOps<_AlgPolicy>::next(__first) == __middle)
return std::__rotate_left<_AlgPolicy>(__first, __last);
if (_IterOps<_AlgPolicy>::next(__middle) == __last)
return std::__rotate_right<_AlgPolicy>(__first, __last);
}
return std::__rotate_forward<_AlgPolicy>(__first, __middle, __last);
}

template <class _AlgPolicy, class _RandomAccessIterator>
inline _LIBCPP_HIDE_FROM_ABI
_LIBCPP_CONSTEXPR_SINCE_CXX14 _RandomAccessIterator
__rotate_impl(_RandomAccessIterator __first, _RandomAccessIterator __middle, _RandomAccessIterator __last,
random_access_iterator_tag)
{
typedef typename iterator_traits<_RandomAccessIterator>::value_type value_type;
if (is_trivially_move_assignable<value_type>::value)
{
if (_IterOps<_AlgPolicy>::next(__first) == __middle)
return std::__rotate_left<_AlgPolicy>(__first, __last);
if (_IterOps<_AlgPolicy>::next(__middle) == __last)
return std::__rotate_right<_AlgPolicy>(__first, __last);
return std::__rotate_gcd<_AlgPolicy>(__first, __middle, __last);
}
return std::__rotate_forward<_AlgPolicy>(__first, __middle, __last);
inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 _RandomAccessIterator __rotate_impl(
_RandomAccessIterator __first,
_RandomAccessIterator __middle,
_RandomAccessIterator __last,
random_access_iterator_tag) {
typedef typename iterator_traits<_RandomAccessIterator>::value_type value_type;
if (is_trivially_move_assignable<value_type>::value) {
if (_IterOps<_AlgPolicy>::next(__first) == __middle)
return std::__rotate_left<_AlgPolicy>(__first, __last);
if (_IterOps<_AlgPolicy>::next(__middle) == __last)
return std::__rotate_right<_AlgPolicy>(__first, __last);
return std::__rotate_gcd<_AlgPolicy>(__first, __middle, __last);
}
return std::__rotate_forward<_AlgPolicy>(__first, __middle, __last);
}

template <class _AlgPolicy, class _Iterator, class _Sentinel>
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14
pair<_Iterator, _Iterator>
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 pair<_Iterator, _Iterator>
__rotate(_Iterator __first, _Iterator __middle, _Sentinel __last) {
using _Ret = pair<_Iterator, _Iterator>;
using _Ret = pair<_Iterator, _Iterator>;
_Iterator __last_iter = _IterOps<_AlgPolicy>::next(__middle, __last);

if (__first == __middle)
return _Ret(__last_iter, __last_iter);
return _Ret(__last_iter, __last_iter);
if (__middle == __last)
return _Ret(std::move(__first), std::move(__last_iter));
return _Ret(std::move(__first), std::move(__last_iter));

using _IterCategory = typename _IterOps<_AlgPolicy>::template __iterator_category<_Iterator>;
auto __result = std::__rotate_impl<_AlgPolicy>(
std::move(__first), std::move(__middle), __last_iter, _IterCategory());
auto __result = std::__rotate_impl<_AlgPolicy>(std::move(__first), std::move(__middle), __last_iter, _IterCategory());

return _Ret(std::move(__result), std::move(__last_iter));
}

template <class _ForwardIterator>
inline _LIBCPP_HIDE_FROM_ABI
_LIBCPP_CONSTEXPR_SINCE_CXX20 _ForwardIterator
rotate(_ForwardIterator __first, _ForwardIterator __middle, _ForwardIterator __last)
{
return std::__rotate<_ClassicAlgPolicy>(
std::move(__first), std::move(__middle), std::move(__last)).first;
inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _ForwardIterator
rotate(_ForwardIterator __first, _ForwardIterator __middle, _ForwardIterator __last) {
return std::__rotate<_ClassicAlgPolicy>(std::move(__first), std::move(__middle), std::move(__last)).first;
}

_LIBCPP_END_NAMESPACE_STD
Expand Down
8 changes: 3 additions & 5 deletions libcxx/include/__algorithm/rotate_copy.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,11 +19,9 @@
_LIBCPP_BEGIN_NAMESPACE_STD

template <class _ForwardIterator, class _OutputIterator>
inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
_OutputIterator
rotate_copy(_ForwardIterator __first, _ForwardIterator __middle, _ForwardIterator __last, _OutputIterator __result)
{
return std::copy(__first, __middle, std::copy(__middle, __last, __result));
inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _OutputIterator
rotate_copy(_ForwardIterator __first, _ForwardIterator __middle, _ForwardIterator __last, _OutputIterator __result) {
return std::copy(__first, __middle, std::copy(__middle, __last, __result));
}

_LIBCPP_END_NAMESPACE_STD
Expand Down
81 changes: 46 additions & 35 deletions libcxx/include/__algorithm/sample.h
Original file line number Diff line number Diff line change
Expand Up @@ -29,20 +29,23 @@ _LIBCPP_PUSH_MACROS
_LIBCPP_BEGIN_NAMESPACE_STD

template <class _AlgPolicy,
class _PopulationIterator, class _PopulationSentinel, class _SampleIterator, class _Distance,
class _PopulationIterator,
class _PopulationSentinel,
class _SampleIterator,
class _Distance,
class _UniformRandomNumberGenerator>
_LIBCPP_HIDE_FROM_ABI
_SampleIterator __sample(_PopulationIterator __first,
_PopulationSentinel __last, _SampleIterator __output_iter,
_Distance __n,
_UniformRandomNumberGenerator& __g,
input_iterator_tag) {

_LIBCPP_HIDE_FROM_ABI _SampleIterator __sample(
_PopulationIterator __first,
_PopulationSentinel __last,
_SampleIterator __output_iter,
_Distance __n,
_UniformRandomNumberGenerator& __g,
input_iterator_tag) {
_Distance __k = 0;
for (; __first != __last && __k < __n; ++__first, (void) ++__k)
for (; __first != __last && __k < __n; ++__first, (void)++__k)
__output_iter[__k] = *__first;
_Distance __sz = __k;
for (; __first != __last; ++__first, (void) ++__k) {
for (; __first != __last; ++__first, (void)++__k) {
_Distance __r = uniform_int_distribution<_Distance>(0, __k)(__g);
if (__r < __sz)
__output_iter[__r] = *__first;
Expand All @@ -51,14 +54,18 @@ _SampleIterator __sample(_PopulationIterator __first,
}

template <class _AlgPolicy,
class _PopulationIterator, class _PopulationSentinel, class _SampleIterator, class _Distance,
class _PopulationIterator,
class _PopulationSentinel,
class _SampleIterator,
class _Distance,
class _UniformRandomNumberGenerator>
_LIBCPP_HIDE_FROM_ABI
_SampleIterator __sample(_PopulationIterator __first,
_PopulationSentinel __last, _SampleIterator __output_iter,
_Distance __n,
_UniformRandomNumberGenerator& __g,
forward_iterator_tag) {
_LIBCPP_HIDE_FROM_ABI _SampleIterator __sample(
_PopulationIterator __first,
_PopulationSentinel __last,
_SampleIterator __output_iter,
_Distance __n,
_UniformRandomNumberGenerator& __g,
forward_iterator_tag) {
_Distance __unsampled_sz = _IterOps<_AlgPolicy>::distance(__first, __last);
for (__n = std::min(__n, __unsampled_sz); __n != 0; ++__first) {
_Distance __r = uniform_int_distribution<_Distance>(0, --__unsampled_sz)(__g);
Expand All @@ -71,36 +78,40 @@ _SampleIterator __sample(_PopulationIterator __first,
}

template <class _AlgPolicy,
class _PopulationIterator, class _PopulationSentinel, class _SampleIterator, class _Distance,
class _PopulationIterator,
class _PopulationSentinel,
class _SampleIterator,
class _Distance,
class _UniformRandomNumberGenerator>
_LIBCPP_HIDE_FROM_ABI
_SampleIterator __sample(_PopulationIterator __first,
_PopulationSentinel __last, _SampleIterator __output_iter,
_Distance __n, _UniformRandomNumberGenerator& __g) {
_LIBCPP_HIDE_FROM_ABI _SampleIterator __sample(
_PopulationIterator __first,
_PopulationSentinel __last,
_SampleIterator __output_iter,
_Distance __n,
_UniformRandomNumberGenerator& __g) {
_LIBCPP_ASSERT_UNCATEGORIZED(__n >= 0, "N must be a positive number.");

using _PopIterCategory = typename _IterOps<_AlgPolicy>::template __iterator_category<_PopulationIterator>;
using _Difference = typename _IterOps<_AlgPolicy>::template __difference_type<_PopulationIterator>;
using _CommonType = typename common_type<_Distance, _Difference>::type;
using _Difference = typename _IterOps<_AlgPolicy>::template __difference_type<_PopulationIterator>;
using _CommonType = typename common_type<_Distance, _Difference>::type;

return std::__sample<_AlgPolicy>(
std::move(__first), std::move(__last), std::move(__output_iter), _CommonType(__n),
__g, _PopIterCategory());
std::move(__first), std::move(__last), std::move(__output_iter), _CommonType(__n), __g, _PopIterCategory());
}

#if _LIBCPP_STD_VER >= 17
template <class _PopulationIterator, class _SampleIterator, class _Distance,
class _UniformRandomNumberGenerator>
inline _LIBCPP_HIDE_FROM_ABI
_SampleIterator sample(_PopulationIterator __first,
_PopulationIterator __last, _SampleIterator __output_iter,
_Distance __n, _UniformRandomNumberGenerator&& __g) {
template <class _PopulationIterator, class _SampleIterator, class _Distance, class _UniformRandomNumberGenerator>
inline _LIBCPP_HIDE_FROM_ABI _SampleIterator
sample(_PopulationIterator __first,
_PopulationIterator __last,
_SampleIterator __output_iter,
_Distance __n,
_UniformRandomNumberGenerator&& __g) {
static_assert(__has_forward_iterator_category<_PopulationIterator>::value ||
__has_random_access_iterator_category<_SampleIterator>::value,
__has_random_access_iterator_category<_SampleIterator>::value,
"SampleIterator must meet the requirements of RandomAccessIterator");

return std::__sample<_ClassicAlgPolicy>(
std::move(__first), std::move(__last), std::move(__output_iter), __n, __g);
return std::__sample<_ClassicAlgPolicy>(std::move(__first), std::move(__last), std::move(__output_iter), __n, __g);
}

#endif // _LIBCPP_STD_VER >= 17
Expand Down
123 changes: 55 additions & 68 deletions libcxx/include/__algorithm/search.h
Original file line number Diff line number Diff line change
Expand Up @@ -29,17 +29,15 @@
_LIBCPP_BEGIN_NAMESPACE_STD

template <class _AlgPolicy,
class _Iter1, class _Sent1,
class _Iter2, class _Sent2,
class _Iter1,
class _Sent1,
class _Iter2,
class _Sent2,
class _Pred,
class _Proj1,
class _Proj2>
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14
pair<_Iter1, _Iter1> __search_forward_impl(_Iter1 __first1, _Sent1 __last1,
_Iter2 __first2, _Sent2 __last2,
_Pred& __pred,
_Proj1& __proj1,
_Proj2& __proj2) {
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 pair<_Iter1, _Iter1> __search_forward_impl(
_Iter1 __first1, _Sent1 __last1, _Iter2 __first2, _Sent2 __last2, _Pred& __pred, _Proj1& __proj1, _Proj2& __proj2) {
if (__first2 == __last2)
return std::make_pair(__first1, __first1); // Everything matches an empty sequence
while (true) {
Expand All @@ -64,8 +62,7 @@ pair<_Iter1, _Iter1> __search_forward_impl(_Iter1 __first1, _Sent1 __last1,
}

// if there is a mismatch, restart with a new __first1
if (!std::__invoke(__pred, std::__invoke(__proj1, *__m1), std::__invoke(__proj2, *__m2)))
{
if (!std::__invoke(__pred, std::__invoke(__proj1, *__m1), std::__invoke(__proj2, *__m2))) {
++__first1;
break;
} // else there is a match, check next elements
Expand All @@ -74,21 +71,25 @@ pair<_Iter1, _Iter1> __search_forward_impl(_Iter1 __first1, _Sent1 __last1,
}

template <class _AlgPolicy,
class _Iter1, class _Sent1,
class _Iter2, class _Sent2,
class _Iter1,
class _Sent1,
class _Iter2,
class _Sent2,
class _Pred,
class _Proj1,
class _Proj2,
class _DiffT1,
class _DiffT2>
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14
pair<_Iter1, _Iter1> __search_random_access_impl(_Iter1 __first1, _Sent1 __last1,
_Iter2 __first2, _Sent2 __last2,
_Pred& __pred,
_Proj1& __proj1,
_Proj2& __proj2,
_DiffT1 __size1,
_DiffT2 __size2) {
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 pair<_Iter1, _Iter1> __search_random_access_impl(
_Iter1 __first1,
_Sent1 __last1,
_Iter2 __first2,
_Sent2 __last2,
_Pred& __pred,
_Proj1& __proj1,
_Proj2& __proj2,
_DiffT1 __size1,
_DiffT2 __size2) {
const _Iter1 __s = __first1 + __size1 - _DiffT1(__size2 - 1); // Start of pattern match can't go beyond here

while (true) {
Expand Down Expand Up @@ -116,20 +117,17 @@ pair<_Iter1, _Iter1> __search_random_access_impl(_Iter1 __first1, _Sent1 __last1
}
}

template <class _Iter1, class _Sent1,
class _Iter2, class _Sent2,
class _Pred,
class _Proj1,
class _Proj2>
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14
pair<_Iter1, _Iter1> __search_impl(_Iter1 __first1, _Sent1 __last1,
_Iter2 __first2, _Sent2 __last2,
_Pred& __pred,
_Proj1& __proj1,
_Proj2& __proj2,
__enable_if_t<__has_random_access_iterator_category<_Iter1>::value
&& __has_random_access_iterator_category<_Iter2>::value>* = nullptr) {

template <class _Iter1, class _Sent1, class _Iter2, class _Sent2, class _Pred, class _Proj1, class _Proj2>
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 pair<_Iter1, _Iter1> __search_impl(
_Iter1 __first1,
_Sent1 __last1,
_Iter2 __first2,
_Sent2 __last2,
_Pred& __pred,
_Proj1& __proj1,
_Proj2& __proj2,
__enable_if_t<__has_random_access_iterator_category<_Iter1>::value &&
__has_random_access_iterator_category<_Iter2>::value>* = nullptr) {
auto __size2 = __last2 - __first2;
if (__size2 == 0)
return std::make_pair(__first1, __first1);
Expand All @@ -139,52 +137,41 @@ pair<_Iter1, _Iter1> __search_impl(_Iter1 __first1, _Sent1 __last1,
return std::make_pair(__last1, __last1);
}

return std::__search_random_access_impl<_ClassicAlgPolicy>(__first1, __last1,
__first2, __last2,
__pred,
__proj1,
__proj2,
__size1,
__size2);
return std::__search_random_access_impl<_ClassicAlgPolicy>(
__first1, __last1, __first2, __last2, __pred, __proj1, __proj2, __size1, __size2);
}

template <class _Iter1, class _Sent1,
class _Iter2, class _Sent2,
class _Pred,
class _Proj1,
class _Proj2>
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14
pair<_Iter1, _Iter1> __search_impl(_Iter1 __first1, _Sent1 __last1,
_Iter2 __first2, _Sent2 __last2,
_Pred& __pred,
_Proj1& __proj1,
_Proj2& __proj2,
__enable_if_t<__has_forward_iterator_category<_Iter1>::value
&& __has_forward_iterator_category<_Iter2>::value
&& !(__has_random_access_iterator_category<_Iter1>::value
&& __has_random_access_iterator_category<_Iter2>::value)>* = nullptr) {
return std::__search_forward_impl<_ClassicAlgPolicy>(__first1, __last1,
__first2, __last2,
__pred,
__proj1,
__proj2);
template <class _Iter1, class _Sent1, class _Iter2, class _Sent2, class _Pred, class _Proj1, class _Proj2>
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 pair<_Iter1, _Iter1> __search_impl(
_Iter1 __first1,
_Sent1 __last1,
_Iter2 __first2,
_Sent2 __last2,
_Pred& __pred,
_Proj1& __proj1,
_Proj2& __proj2,
__enable_if_t<__has_forward_iterator_category<_Iter1>::value && __has_forward_iterator_category<_Iter2>::value &&
!(__has_random_access_iterator_category<_Iter1>::value &&
__has_random_access_iterator_category<_Iter2>::value)>* = nullptr) {
return std::__search_forward_impl<_ClassicAlgPolicy>(__first1, __last1, __first2, __last2, __pred, __proj1, __proj2);
}

template <class _ForwardIterator1, class _ForwardIterator2, class _BinaryPredicate>
_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
_ForwardIterator1 search(_ForwardIterator1 __first1, _ForwardIterator1 __last1,
_ForwardIterator2 __first2, _ForwardIterator2 __last2,
_BinaryPredicate __pred) {
_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _ForwardIterator1
search(_ForwardIterator1 __first1,
_ForwardIterator1 __last1,
_ForwardIterator2 __first2,
_ForwardIterator2 __last2,
_BinaryPredicate __pred) {
static_assert(__is_callable<_BinaryPredicate, decltype(*__first1), decltype(*__first2)>::value,
"BinaryPredicate has to be callable");
auto __proj = __identity();
return std::__search_impl(__first1, __last1, __first2, __last2, __pred, __proj, __proj).first;
}

template <class _ForwardIterator1, class _ForwardIterator2>
_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
_ForwardIterator1 search(_ForwardIterator1 __first1, _ForwardIterator1 __last1,
_ForwardIterator2 __first2, _ForwardIterator2 __last2) {
_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _ForwardIterator1
search(_ForwardIterator1 __first1, _ForwardIterator1 __last1, _ForwardIterator2 __first2, _ForwardIterator2 __last2) {
return std::search(__first1, __last1, __first2, __last2, __equal_to());
}

Expand Down
96 changes: 34 additions & 62 deletions libcxx/include/__algorithm/search_n.h
Original file line number Diff line number Diff line change
Expand Up @@ -31,12 +31,8 @@
_LIBCPP_BEGIN_NAMESPACE_STD

template <class _AlgPolicy, class _Pred, class _Iter, class _Sent, class _SizeT, class _Type, class _Proj>
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14
pair<_Iter, _Iter> __search_n_forward_impl(_Iter __first, _Sent __last,
_SizeT __count,
const _Type& __value,
_Pred& __pred,
_Proj& __proj) {
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 pair<_Iter, _Iter> __search_n_forward_impl(
_Iter __first, _Sent __last, _SizeT __count, const _Type& __value, _Pred& __pred, _Proj& __proj) {
if (__count <= 0)
return std::make_pair(__first, __first);
while (true) {
Expand All @@ -62,8 +58,7 @@ pair<_Iter, _Iter> __search_n_forward_impl(_Iter __first, _Sent __last,
}

// if there is a mismatch, restart with a new __first
if (!std::__invoke(__pred, std::__invoke(__proj, *__m), __value))
{
if (!std::__invoke(__pred, std::__invoke(__proj, *__m), __value)) {
__first = __m;
++__first;
break;
Expand All @@ -73,13 +68,8 @@ pair<_Iter, _Iter> __search_n_forward_impl(_Iter __first, _Sent __last,
}

template <class _AlgPolicy, class _Pred, class _Iter, class _Sent, class _SizeT, class _Type, class _Proj, class _DiffT>
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14
std::pair<_Iter, _Iter> __search_n_random_access_impl(_Iter __first, _Sent __last,
_SizeT __count,
const _Type& __value,
_Pred& __pred,
_Proj& __proj,
_DiffT __size1) {
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 std::pair<_Iter, _Iter> __search_n_random_access_impl(
_Iter __first, _Sent __last, _SizeT __count, const _Type& __value, _Pred& __pred, _Proj& __proj, _DiffT __size1) {
using difference_type = typename iterator_traits<_Iter>::difference_type;
if (__count == 0)
return std::make_pair(__first, __first);
Expand Down Expand Up @@ -109,8 +99,7 @@ std::pair<_Iter, _Iter> __search_n_random_access_impl(_Iter __first, _Sent __las
++__m; // no need to check range on __m because __s guarantees we have enough source

// if there is a mismatch, restart with a new __first
if (!std::__invoke(__pred, std::__invoke(__proj, *__m), __value))
{
if (!std::__invoke(__pred, std::__invoke(__proj, *__m), __value)) {
__first = __m;
++__first;
break;
Expand All @@ -119,61 +108,44 @@ std::pair<_Iter, _Iter> __search_n_random_access_impl(_Iter __first, _Sent __las
}
}

template <class _Iter, class _Sent,
class _DiffT,
class _Type,
class _Pred,
class _Proj>
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14
pair<_Iter, _Iter> __search_n_impl(_Iter __first, _Sent __last,
_DiffT __count,
const _Type& __value,
_Pred& __pred,
_Proj& __proj,
__enable_if_t<__has_random_access_iterator_category<_Iter>::value>* = nullptr) {
return std::__search_n_random_access_impl<_ClassicAlgPolicy>(__first, __last,
__count,
__value,
__pred,
__proj,
__last - __first);
template <class _Iter, class _Sent, class _DiffT, class _Type, class _Pred, class _Proj>
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 pair<_Iter, _Iter> __search_n_impl(
_Iter __first,
_Sent __last,
_DiffT __count,
const _Type& __value,
_Pred& __pred,
_Proj& __proj,
__enable_if_t<__has_random_access_iterator_category<_Iter>::value>* = nullptr) {
return std::__search_n_random_access_impl<_ClassicAlgPolicy>(
__first, __last, __count, __value, __pred, __proj, __last - __first);
}

template <class _Iter1, class _Sent1,
class _DiffT,
class _Type,
class _Pred,
class _Proj>
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14
pair<_Iter1, _Iter1> __search_n_impl(_Iter1 __first, _Sent1 __last,
_DiffT __count,
const _Type& __value,
_Pred& __pred,
_Proj& __proj,
__enable_if_t<__has_forward_iterator_category<_Iter1>::value
&& !__has_random_access_iterator_category<_Iter1>::value>* = nullptr) {
return std::__search_n_forward_impl<_ClassicAlgPolicy>(__first, __last,
__count,
__value,
__pred,
__proj);
template <class _Iter1, class _Sent1, class _DiffT, class _Type, class _Pred, class _Proj>
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 pair<_Iter1, _Iter1> __search_n_impl(
_Iter1 __first,
_Sent1 __last,
_DiffT __count,
const _Type& __value,
_Pred& __pred,
_Proj& __proj,
__enable_if_t<__has_forward_iterator_category<_Iter1>::value &&
!__has_random_access_iterator_category<_Iter1>::value>* = nullptr) {
return std::__search_n_forward_impl<_ClassicAlgPolicy>(__first, __last, __count, __value, __pred, __proj);
}

template <class _ForwardIterator, class _Size, class _Tp, class _BinaryPredicate>
_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
_ForwardIterator search_n(_ForwardIterator __first, _ForwardIterator __last,
_Size __count,
const _Tp& __value,
_BinaryPredicate __pred) {
static_assert(__is_callable<_BinaryPredicate, decltype(*__first), const _Tp&>::value,
"BinaryPredicate has to be callable");
_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _ForwardIterator search_n(
_ForwardIterator __first, _ForwardIterator __last, _Size __count, const _Tp& __value, _BinaryPredicate __pred) {
static_assert(
__is_callable<_BinaryPredicate, decltype(*__first), const _Tp&>::value, "BinaryPredicate has to be callable");
auto __proj = __identity();
return std::__search_n_impl(__first, __last, std::__convert_to_integral(__count), __value, __pred, __proj).first;
}

template <class _ForwardIterator, class _Size, class _Tp>
_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
_ForwardIterator search_n(_ForwardIterator __first, _ForwardIterator __last, _Size __count, const _Tp& __value) {
_LIBCPP_NODISCARD_EXT inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _ForwardIterator
search_n(_ForwardIterator __first, _ForwardIterator __last, _Size __count, const _Tp& __value) {
return std::search_n(__first, __last, std::__convert_to_integral(__count), __value, __equal_to());
}

Expand Down
2 changes: 1 addition & 1 deletion libcxx/include/__algorithm/set_difference.h
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _OutputIterator set_d
_OutputIterator __result,
_Compare __comp) {
return std::__set_difference<_ClassicAlgPolicy, __comp_ref_type<_Compare> >(
__first1, __last1, __first2, __last2, __result, __comp)
__first1, __last1, __first2, __last2, __result, __comp)
.second;
}

Expand Down
43 changes: 21 additions & 22 deletions libcxx/include/__algorithm/shift_left.h
Original file line number Diff line number Diff line change
Expand Up @@ -22,30 +22,29 @@ _LIBCPP_BEGIN_NAMESPACE_STD
#if _LIBCPP_STD_VER >= 20

template <class _ForwardIterator>
inline _LIBCPP_HIDE_FROM_ABI constexpr
_ForwardIterator
shift_left(_ForwardIterator __first, _ForwardIterator __last,
typename iterator_traits<_ForwardIterator>::difference_type __n)
{
if (__n == 0) {
return __last;
inline _LIBCPP_HIDE_FROM_ABI constexpr _ForwardIterator
shift_left(_ForwardIterator __first,
_ForwardIterator __last,
typename iterator_traits<_ForwardIterator>::difference_type __n) {
if (__n == 0) {
return __last;
}

_ForwardIterator __m = __first;
if constexpr (__has_random_access_iterator_category<_ForwardIterator>::value) {
if (__n >= __last - __first) {
return __first;
}

_ForwardIterator __m = __first;
if constexpr (__has_random_access_iterator_category<_ForwardIterator>::value) {
if (__n >= __last - __first) {
return __first;
}
__m += __n;
} else {
for (; __n > 0; --__n) {
if (__m == __last) {
return __first;
}
++__m;
}
__m += __n;
} else {
for (; __n > 0; --__n) {
if (__m == __last) {
return __first;
}
++__m;
}
return std::move(__m, __last, __first);
}
return std::move(__m, __last, __first);
}

#endif // _LIBCPP_STD_VER >= 20
Expand Down
123 changes: 61 additions & 62 deletions libcxx/include/__algorithm/shift_right.h
Original file line number Diff line number Diff line change
Expand Up @@ -25,73 +25,72 @@ _LIBCPP_BEGIN_NAMESPACE_STD
#if _LIBCPP_STD_VER >= 20

template <class _ForwardIterator>
inline _LIBCPP_HIDE_FROM_ABI constexpr
_ForwardIterator
shift_right(_ForwardIterator __first, _ForwardIterator __last,
typename iterator_traits<_ForwardIterator>::difference_type __n)
{
if (__n == 0) {
return __first;
}
inline _LIBCPP_HIDE_FROM_ABI constexpr _ForwardIterator
shift_right(_ForwardIterator __first,
_ForwardIterator __last,
typename iterator_traits<_ForwardIterator>::difference_type __n) {
if (__n == 0) {
return __first;
}

if constexpr (__has_random_access_iterator_category<_ForwardIterator>::value) {
decltype(__n) __d = __last - __first;
if (__n >= __d) {
return __last;
}
_ForwardIterator __m = __first + (__d - __n);
return std::move_backward(__first, __m, __last);
} else if constexpr (__has_bidirectional_iterator_category<_ForwardIterator>::value) {
_ForwardIterator __m = __last;
for (; __n > 0; --__n) {
if (__m == __first) {
return __last;
}
--__m;
}
return std::move_backward(__first, __m, __last);
} else {
_ForwardIterator __ret = __first;
for (; __n > 0; --__n) {
if (__ret == __last) {
return __last;
}
++__ret;
}
if constexpr (__has_random_access_iterator_category<_ForwardIterator>::value) {
decltype(__n) __d = __last - __first;
if (__n >= __d) {
return __last;
}
_ForwardIterator __m = __first + (__d - __n);
return std::move_backward(__first, __m, __last);
} else if constexpr (__has_bidirectional_iterator_category<_ForwardIterator>::value) {
_ForwardIterator __m = __last;
for (; __n > 0; --__n) {
if (__m == __first) {
return __last;
}
--__m;
}
return std::move_backward(__first, __m, __last);
} else {
_ForwardIterator __ret = __first;
for (; __n > 0; --__n) {
if (__ret == __last) {
return __last;
}
++__ret;
}

// We have an __n-element scratch space from __first to __ret.
// Slide an __n-element window [__trail, __lead) from left to right.
// We're essentially doing swap_ranges(__first, __ret, __trail, __lead)
// over and over; but once __lead reaches __last we needn't bother
// to save the values of elements [__trail, __last).
// We have an __n-element scratch space from __first to __ret.
// Slide an __n-element window [__trail, __lead) from left to right.
// We're essentially doing swap_ranges(__first, __ret, __trail, __lead)
// over and over; but once __lead reaches __last we needn't bother
// to save the values of elements [__trail, __last).

auto __trail = __first;
auto __lead = __ret;
while (__trail != __ret) {
if (__lead == __last) {
std::move(__first, __trail, __ret);
return __ret;
}
++__trail;
++__lead;
}
auto __trail = __first;
auto __lead = __ret;
while (__trail != __ret) {
if (__lead == __last) {
std::move(__first, __trail, __ret);
return __ret;
}
++__trail;
++__lead;
}

_ForwardIterator __mid = __first;
while (true) {
if (__lead == __last) {
__trail = std::move(__mid, __ret, __trail);
std::move(__first, __mid, __trail);
return __ret;
}
swap(*__mid, *__trail);
++__mid;
++__trail;
++__lead;
if (__mid == __ret) {
__mid = __first;
}
}
_ForwardIterator __mid = __first;
while (true) {
if (__lead == __last) {
__trail = std::move(__mid, __ret, __trail);
std::move(__first, __mid, __trail);
return __ret;
}
swap(*__mid, *__trail);
++__mid;
++__trail;
++__lead;
if (__mid == __ret) {
__mid = __first;
}
}
}
}

#endif // _LIBCPP_STD_VER >= 20
Expand Down
127 changes: 60 additions & 67 deletions libcxx/include/__algorithm/shuffle.h
Original file line number Diff line number Diff line change
Expand Up @@ -32,8 +32,8 @@ class _LIBCPP_EXPORTED_FROM_ABI __libcpp_debug_randomizer {
public:
_LIBCPP_HIDE_FROM_ABI __libcpp_debug_randomizer() {
__state_ = __seed();
__inc_ = __state_ + 0xda3e39cb94b95bdbULL;
__inc_ = (__inc_ << 1) | 1;
__inc_ = __state_ + 0xda3e39cb94b95bdbULL;
__inc_ = (__inc_ << 1) | 1;
}
typedef uint_fast32_t result_type;

Expand All @@ -42,7 +42,7 @@ class _LIBCPP_EXPORTED_FROM_ABI __libcpp_debug_randomizer {

_LIBCPP_HIDE_FROM_ABI result_type operator()() {
uint_fast64_t __oldstate = __state_;
__state_ = __oldstate * 6364136223846793005ULL + __inc_;
__state_ = __oldstate * 6364136223846793005ULL + __inc_;
return __oldstate >> 32;
}

Expand All @@ -62,102 +62,95 @@ class _LIBCPP_EXPORTED_FROM_ABI __libcpp_debug_randomizer {
}
};

#if _LIBCPP_STD_VER <= 14 || defined(_LIBCPP_ENABLE_CXX17_REMOVED_RANDOM_SHUFFLE) \
|| defined(_LIBCPP_BUILDING_LIBRARY)
#if _LIBCPP_STD_VER <= 14 || defined(_LIBCPP_ENABLE_CXX17_REMOVED_RANDOM_SHUFFLE) || defined(_LIBCPP_BUILDING_LIBRARY)
class _LIBCPP_EXPORTED_FROM_ABI __rs_default;

_LIBCPP_EXPORTED_FROM_ABI __rs_default __rs_get();

class _LIBCPP_EXPORTED_FROM_ABI __rs_default
{
static unsigned __c_;
class _LIBCPP_EXPORTED_FROM_ABI __rs_default {
static unsigned __c_;

__rs_default();

__rs_default();
public:
typedef uint_fast32_t result_type;
typedef uint_fast32_t result_type;

static const result_type _Min = 0;
static const result_type _Max = 0xFFFFFFFF;
static const result_type _Min = 0;
static const result_type _Max = 0xFFFFFFFF;

__rs_default(const __rs_default&);
~__rs_default();
__rs_default(const __rs_default&);
~__rs_default();

result_type operator()();
result_type operator()();

static _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR result_type min() {return _Min;}
static _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR result_type max() {return _Max;}
static _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR result_type min() { return _Min; }
static _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR result_type max() { return _Max; }

friend _LIBCPP_EXPORTED_FROM_ABI __rs_default __rs_get();
friend _LIBCPP_EXPORTED_FROM_ABI __rs_default __rs_get();
};

_LIBCPP_EXPORTED_FROM_ABI __rs_default __rs_get();

template <class _RandomAccessIterator>
_LIBCPP_HIDE_FROM_ABI _LIBCPP_DEPRECATED_IN_CXX14 void
random_shuffle(_RandomAccessIterator __first, _RandomAccessIterator __last)
{
typedef typename iterator_traits<_RandomAccessIterator>::difference_type difference_type;
typedef uniform_int_distribution<ptrdiff_t> _Dp;
typedef typename _Dp::param_type _Pp;
difference_type __d = __last - __first;
if (__d > 1)
{
_Dp __uid;
__rs_default __g = __rs_get();
for (--__last, (void) --__d; __first < __last; ++__first, (void) --__d)
{
difference_type __i = __uid(__g, _Pp(0, __d));
if (__i != difference_type(0))
swap(*__first, *(__first + __i));
}
random_shuffle(_RandomAccessIterator __first, _RandomAccessIterator __last) {
typedef typename iterator_traits<_RandomAccessIterator>::difference_type difference_type;
typedef uniform_int_distribution<ptrdiff_t> _Dp;
typedef typename _Dp::param_type _Pp;
difference_type __d = __last - __first;
if (__d > 1) {
_Dp __uid;
__rs_default __g = __rs_get();
for (--__last, (void)--__d; __first < __last; ++__first, (void)--__d) {
difference_type __i = __uid(__g, _Pp(0, __d));
if (__i != difference_type(0))
swap(*__first, *(__first + __i));
}
}
}

template <class _RandomAccessIterator, class _RandomNumberGenerator>
_LIBCPP_HIDE_FROM_ABI _LIBCPP_DEPRECATED_IN_CXX14 void
random_shuffle(_RandomAccessIterator __first, _RandomAccessIterator __last,
#ifndef _LIBCPP_CXX03_LANG
random_shuffle(_RandomAccessIterator __first,
_RandomAccessIterator __last,
# ifndef _LIBCPP_CXX03_LANG
_RandomNumberGenerator&& __rand)
#else
# else
_RandomNumberGenerator& __rand)
#endif
# endif
{
typedef typename iterator_traits<_RandomAccessIterator>::difference_type difference_type;
difference_type __d = __last - __first;
if (__d > 1)
{
for (--__last; __first < __last; ++__first, (void) --__d)
{
difference_type __i = __rand(__d);
if (__i != difference_type(0))
swap(*__first, *(__first + __i));
}
typedef typename iterator_traits<_RandomAccessIterator>::difference_type difference_type;
difference_type __d = __last - __first;
if (__d > 1) {
for (--__last; __first < __last; ++__first, (void)--__d) {
difference_type __i = __rand(__d);
if (__i != difference_type(0))
swap(*__first, *(__first + __i));
}
}
}
#endif

template <class _AlgPolicy, class _RandomAccessIterator, class _Sentinel, class _UniformRandomNumberGenerator>
_LIBCPP_HIDE_FROM_ABI _RandomAccessIterator __shuffle(
_RandomAccessIterator __first, _Sentinel __last_sentinel, _UniformRandomNumberGenerator&& __g) {
typedef typename iterator_traits<_RandomAccessIterator>::difference_type difference_type;
typedef uniform_int_distribution<ptrdiff_t> _Dp;
typedef typename _Dp::param_type _Pp;

auto __original_last = _IterOps<_AlgPolicy>::next(__first, __last_sentinel);
auto __last = __original_last;
difference_type __d = __last - __first;
if (__d > 1)
{
_Dp __uid;
for (--__last, (void) --__d; __first < __last; ++__first, (void) --__d)
{
difference_type __i = __uid(__g, _Pp(0, __d));
if (__i != difference_type(0))
_IterOps<_AlgPolicy>::iter_swap(__first, __first + __i);
}
_LIBCPP_HIDE_FROM_ABI _RandomAccessIterator
__shuffle(_RandomAccessIterator __first, _Sentinel __last_sentinel, _UniformRandomNumberGenerator&& __g) {
typedef typename iterator_traits<_RandomAccessIterator>::difference_type difference_type;
typedef uniform_int_distribution<ptrdiff_t> _Dp;
typedef typename _Dp::param_type _Pp;

auto __original_last = _IterOps<_AlgPolicy>::next(__first, __last_sentinel);
auto __last = __original_last;
difference_type __d = __last - __first;
if (__d > 1) {
_Dp __uid;
for (--__last, (void)--__d; __first < __last; ++__first, (void)--__d) {
difference_type __i = __uid(__g, _Pp(0, __d));
if (__i != difference_type(0))
_IterOps<_AlgPolicy>::iter_swap(__first, __first + __i);
}
}

return __original_last;
return __original_last;
}

template <class _RandomAccessIterator, class _UniformRandomNumberGenerator>
Expand Down
141 changes: 70 additions & 71 deletions libcxx/include/__algorithm/sift_down.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,90 +26,89 @@ _LIBCPP_BEGIN_NAMESPACE_STD

template <class _AlgPolicy, class _Compare, class _RandomAccessIterator>
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 void
__sift_down(_RandomAccessIterator __first, _Compare&& __comp,
__sift_down(_RandomAccessIterator __first,
_Compare&& __comp,
typename iterator_traits<_RandomAccessIterator>::difference_type __len,
_RandomAccessIterator __start)
{
using _Ops = _IterOps<_AlgPolicy>;
_RandomAccessIterator __start) {
using _Ops = _IterOps<_AlgPolicy>;

typedef typename iterator_traits<_RandomAccessIterator>::difference_type difference_type;
typedef typename iterator_traits<_RandomAccessIterator>::value_type value_type;
// left-child of __start is at 2 * __start + 1
// right-child of __start is at 2 * __start + 2
difference_type __child = __start - __first;
typedef typename iterator_traits<_RandomAccessIterator>::difference_type difference_type;
typedef typename iterator_traits<_RandomAccessIterator>::value_type value_type;
// left-child of __start is at 2 * __start + 1
// right-child of __start is at 2 * __start + 2
difference_type __child = __start - __first;

if (__len < 2 || (__len - 2) / 2 < __child)
return;
if (__len < 2 || (__len - 2) / 2 < __child)
return;

__child = 2 * __child + 1;
_RandomAccessIterator __child_i = __first + __child;
__child = 2 * __child + 1;
_RandomAccessIterator __child_i = __first + __child;

if ((__child + 1) < __len && __comp(*__child_i, *(__child_i + difference_type(1)))) {
// right-child exists and is greater than left-child
++__child_i;
++__child;
}

// check if we are in heap-order
if (__comp(*__child_i, *__start))
// we are, __start is larger than its largest child
return;

value_type __top(_Ops::__iter_move(__start));
do {
// we are not in heap-order, swap the parent with its largest child
*__start = _Ops::__iter_move(__child_i);
__start = __child_i;

if ((__len - 2) / 2 < __child)
break;

// recompute the child based off of the updated parent
__child = 2 * __child + 1;
__child_i = __first + __child;

if ((__child + 1) < __len && __comp(*__child_i, *(__child_i + difference_type(1)))) {
// right-child exists and is greater than left-child
++__child_i;
++__child;
// right-child exists and is greater than left-child
++__child_i;
++__child;
}

// check if we are in heap-order
if (__comp(*__child_i, *__start))
// we are, __start is larger than its largest child
return;

value_type __top(_Ops::__iter_move(__start));
do
{
// we are not in heap-order, swap the parent with its largest child
*__start = _Ops::__iter_move(__child_i);
__start = __child_i;

if ((__len - 2) / 2 < __child)
break;

// recompute the child based off of the updated parent
__child = 2 * __child + 1;
__child_i = __first + __child;

if ((__child + 1) < __len && __comp(*__child_i, *(__child_i + difference_type(1)))) {
// right-child exists and is greater than left-child
++__child_i;
++__child;
}

// check if we are in heap-order
} while (!__comp(*__child_i, __top));
*__start = std::move(__top);
} while (!__comp(*__child_i, __top));
*__start = std::move(__top);
}

template <class _AlgPolicy, class _Compare, class _RandomAccessIterator>
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 _RandomAccessIterator
__floyd_sift_down(_RandomAccessIterator __first, _Compare&& __comp,
typename iterator_traits<_RandomAccessIterator>::difference_type __len)
{
using difference_type = typename iterator_traits<_RandomAccessIterator>::difference_type;
_LIBCPP_ASSERT_UNCATEGORIZED(__len >= 2, "shouldn't be called unless __len >= 2");

_RandomAccessIterator __hole = __first;
_RandomAccessIterator __child_i = __first;
difference_type __child = 0;

while (true) {
__child_i += difference_type(__child + 1);
__child = 2 * __child + 1;

if ((__child + 1) < __len && __comp(*__child_i, *(__child_i + difference_type(1)))) {
// right-child exists and is greater than left-child
++__child_i;
++__child;
}

// swap __hole with its largest child
*__hole = _IterOps<_AlgPolicy>::__iter_move(__child_i);
__hole = __child_i;

// if __hole is now a leaf, we're done
if (__child > (__len - 2) / 2)
return __hole;
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 _RandomAccessIterator __floyd_sift_down(
_RandomAccessIterator __first,
_Compare&& __comp,
typename iterator_traits<_RandomAccessIterator>::difference_type __len) {
using difference_type = typename iterator_traits<_RandomAccessIterator>::difference_type;
_LIBCPP_ASSERT_UNCATEGORIZED(__len >= 2, "shouldn't be called unless __len >= 2");

_RandomAccessIterator __hole = __first;
_RandomAccessIterator __child_i = __first;
difference_type __child = 0;

while (true) {
__child_i += difference_type(__child + 1);
__child = 2 * __child + 1;

if ((__child + 1) < __len && __comp(*__child_i, *(__child_i + difference_type(1)))) {
// right-child exists and is greater than left-child
++__child_i;
++__child;
}

// swap __hole with its largest child
*__hole = _IterOps<_AlgPolicy>::__iter_move(__child_i);
__hole = __child_i;

// if __hole is now a leaf, we're done
if (__child > (__len - 2) / 2)
return __hole;
}
}

_LIBCPP_END_NAMESPACE_STD
Expand Down
Loading