Revert "[libc++] [P0879] constexpr std::nth_element, and rewrite its tests."
This reverts commit 207d4be4d9d39fbb9aca30e5d5d11245db9bccc1 due to returning incorrect results. Regression test case posted in D96074.
GitOrigin-RevId: b6ffece32035a90d181101f356bd9c04ea1d3122
diff --git a/include/algorithm b/include/algorithm
index 7220585..a6fceaa 100644
--- a/include/algorithm
+++ b/include/algorithm
@@ -385,11 +385,11 @@
RandomAccessIterator result_first, RandomAccessIterator result_last, Compare comp);
template <class RandomAccessIterator>
- constexpr void // constexpr in C++20
+ void
nth_element(RandomAccessIterator first, RandomAccessIterator nth, RandomAccessIterator last);
template <class RandomAccessIterator, class Compare>
- constexpr void // constexpr in C++20
+ void
nth_element(RandomAccessIterator first, RandomAccessIterator nth, RandomAccessIterator last, Compare comp);
template <class ForwardIterator, class T>
@@ -3807,7 +3807,7 @@
// stable, 2-3 compares, 0-2 swaps
template <class _Compare, class _ForwardIterator>
-_LIBCPP_CONSTEXPR_AFTER_CXX11 unsigned
+unsigned
__sort3(_ForwardIterator __x, _ForwardIterator __y, _ForwardIterator __z, _Compare __c)
{
unsigned __r = 0;
@@ -3901,7 +3901,7 @@
// Assumes size > 0
template <class _Compare, class _BidirectionalIterator>
-_LIBCPP_CONSTEXPR_AFTER_CXX11 void
+void
__selection_sort(_BidirectionalIterator __first, _BidirectionalIterator __last, _Compare __comp)
{
_BidirectionalIterator __lm1 = __last;
@@ -5218,70 +5218,8 @@
// nth_element
-template<class _Compare, class _RandomAccessIterator>
-_LIBCPP_CONSTEXPR_AFTER_CXX11 bool
-__nth_element_find_guard(_RandomAccessIterator& __i, _RandomAccessIterator& __j,
- _RandomAccessIterator& __m, _Compare __comp)
-{
- // manually guard downward moving __j against __i
- while (--__j != __i)
- {
- if (__comp(*__j, *__m))
- {
- return true;
- }
- }
- return false;
-}
-
-template<class _Compare, class _RandomAccessIterator>
-_LIBCPP_CONSTEXPR_AFTER_CXX11 bool
-__nth_element_partloop(_RandomAccessIterator __first, _RandomAccessIterator __last,
- _RandomAccessIterator& __i, _RandomAccessIterator& __j,
- unsigned& __n_swaps, _Compare __comp)
-{
- // *__first == *__m, *__m <= all other elements
- // Partition instead into [__first, __i) == *__first and *__first < [__i, __last)
- ++__i; // __first + 1
- __j = __last;
- if (!__comp(*__first, *--__j)) // we need a guard if *__first == *(__last-1)
- {
- while (true)
- {
- if (__i == __j)
- return true; // [__first, __last) all equivalent elements
- if (__comp(*__first, *__i))
- {
- swap(*__i, *__j);
- ++__n_swaps;
- ++__i;
- break;
- }
- ++__i;
- }
- }
- // [__first, __i) == *__first and *__first < [__j, __last) and __j == __last - 1
- if (__i == __j)
- return true;
- while (true)
- {
- while (!__comp(*__first, *__i))
- ++__i;
- while (__comp(*__first, *--__j))
- ;
- if (__i >= __j)
- break;
- swap(*__i, *__j);
- ++__n_swaps;
- ++__i;
- }
- // [__first, __i) == *__first and *__first < [__i, __last)
- // The first part is sorted.
- return false;
-}
-
template <class _Compare, class _RandomAccessIterator>
-_LIBCPP_CONSTEXPR_AFTER_CXX11 void
+void
__nth_element(_RandomAccessIterator __first, _RandomAccessIterator __nth, _RandomAccessIterator __last, _Compare __comp)
{
// _Compare is known to be a reference type
@@ -5289,7 +5227,7 @@
const difference_type __limit = 7;
while (true)
{
- // __restart: -- this is the target of a "continue" below
+ __restart:
if (__nth == __last)
return;
difference_type __len = __last - __first;
@@ -5329,19 +5267,61 @@
if (!__comp(*__i, *__m)) // if *__first == *__m
{
// *__first == *__m, *__first doesn't go in first part
- if (_VSTD::__nth_element_find_guard<_Compare>(__i, __j, __m, __comp)) {
- swap(*__i, *__j);
- ++__n_swaps;
- // found guard for downward moving __j, now use unguarded partition
- } else if (_VSTD::__nth_element_partloop<_Compare>(__first, __last, __i, __j, __n_swaps, __comp)) {
- return;
- } else if (__nth < __i) {
- return;
- } else {
- // __nth_element the second part
- // _VSTD::__nth_element<_Compare>(__i, __nth, __last, __comp);
- __first = __i;
- continue; // i.e., goto __restart
+ // manually guard downward moving __j against __i
+ while (true)
+ {
+ if (__i == --__j)
+ {
+ // *__first == *__m, *__m <= all other elements
+ // Partition instead into [__first, __i) == *__first and *__first < [__i, __last)
+ ++__i; // __first + 1
+ __j = __last;
+ if (!__comp(*__first, *--__j)) // we need a guard if *__first == *(__last-1)
+ {
+ while (true)
+ {
+ if (__i == __j)
+ return; // [__first, __last) all equivalent elements
+ if (__comp(*__first, *__i))
+ {
+ swap(*__i, *__j);
+ ++__n_swaps;
+ ++__i;
+ break;
+ }
+ ++__i;
+ }
+ }
+ // [__first, __i) == *__first and *__first < [__j, __last) and __j == __last - 1
+ if (__i == __j)
+ return;
+ while (true)
+ {
+ while (!__comp(*__first, *__i))
+ ++__i;
+ while (__comp(*__first, *--__j))
+ ;
+ if (__i >= __j)
+ break;
+ swap(*__i, *__j);
+ ++__n_swaps;
+ ++__i;
+ }
+ // [__first, __i) == *__first and *__first < [__i, __last)
+ // The first part is sorted,
+ if (__nth < __i)
+ return;
+ // __nth_element the second part
+ // _VSTD::__nth_element<_Compare>(__i, __nth, __last, __comp);
+ __first = __i;
+ goto __restart;
+ }
+ if (__comp(*__j, *__m))
+ {
+ swap(*__i, *__j);
+ ++__n_swaps;
+ break; // found guard for downward moving __j, now use unguarded partition
+ }
}
}
++__i;
@@ -5385,16 +5365,15 @@
{
// Check for [__first, __i) already sorted
__j = __m = __first;
- while (true)
+ while (++__j != __i)
{
- if (++__j == __i)
- // [__first, __i) sorted
- return;
if (__comp(*__j, *__m))
// not yet sorted, so sort
- break;
+ goto not_sorted;
__m = __j;
}
+ // [__first, __i) sorted
+ return;
}
else
{
@@ -5402,16 +5381,16 @@
__j = __m = __i;
while (++__j != __last)
{
- if (++__j == __last)
- // [__i, __last) sorted
- return;
if (__comp(*__j, *__m))
// not yet sorted, so sort
- break;
+ goto not_sorted;
__m = __j;
}
+ // [__i, __last) sorted
+ return;
}
}
+not_sorted:
// __nth_element on range containing __nth
if (__nth < __i)
{
@@ -5427,7 +5406,7 @@
}
template <class _RandomAccessIterator, class _Compare>
-inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
+inline _LIBCPP_INLINE_VISIBILITY
void
nth_element(_RandomAccessIterator __first, _RandomAccessIterator __nth, _RandomAccessIterator __last, _Compare __comp)
{
@@ -5436,7 +5415,7 @@
}
template <class _RandomAccessIterator>
-inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
+inline _LIBCPP_INLINE_VISIBILITY
void
nth_element(_RandomAccessIterator __first, _RandomAccessIterator __nth, _RandomAccessIterator __last)
{