Merge pull request #106661 from KirbyRider1337/dont-compare-the-same-item-with-itself

Prevent comparison of items with themselves while partitioning sort arrays
This commit is contained in:
Thaddeus Crews 2025-05-22 12:14:58 -05:00
commit c3c3657a0d
No known key found for this signature in database
GPG key ID: 8C6E5FEB5FC03CCC

View file

@ -54,21 +54,24 @@ class SortArray {
public: public:
Comparator compare; Comparator compare;
inline const T &median_of_3(const T &a, const T &b, const T &c) const { inline int64_t median_of_3_index(const T *p_ptr, int64_t a_index, int64_t b_index, int64_t c_index) const {
const T &a = p_ptr[a_index];
const T &b = p_ptr[b_index];
const T &c = p_ptr[c_index];
if (compare(a, b)) { if (compare(a, b)) {
if (compare(b, c)) { if (compare(b, c)) {
return b; return b_index;
} else if (compare(a, c)) { } else if (compare(a, c)) {
return c; return c_index;
} else { } else {
return a; return a_index;
} }
} else if (compare(a, c)) { } else if (compare(a, c)) {
return a; return a_index;
} else if (compare(b, c)) { } else if (compare(b, c)) {
return c; return c_index;
} else { } else {
return b; return b_index;
} }
} }
@ -162,26 +165,27 @@ public:
} }
} }
inline int64_t partitioner(int64_t p_first, int64_t p_last, T p_pivot, T *p_array) const { inline int64_t partitioner(int64_t p_first, int64_t p_last, int64_t p_pivot, T *p_array) const {
const int64_t unmodified_first = p_first; const int64_t unmodified_first = p_first;
const int64_t unmodified_last = p_last; const int64_t unmodified_last = p_last;
const T &pivot_element = p_array[p_pivot];
while (true) { while (true) {
while (compare(p_array[p_first], p_pivot)) { while (p_first != p_pivot && compare(p_array[p_first], pivot_element)) {
if constexpr (Validate) { if constexpr (Validate) {
ERR_BAD_COMPARE(p_first == unmodified_last - 1); ERR_BAD_COMPARE(p_first == unmodified_last - 1);
} }
p_first++; p_first++;
} }
p_last--; p_last--;
while (compare(p_pivot, p_array[p_last])) { while (p_last != p_pivot && compare(pivot_element, p_array[p_last])) {
if constexpr (Validate) { if constexpr (Validate) {
ERR_BAD_COMPARE(p_last == unmodified_first); ERR_BAD_COMPARE(p_last == unmodified_first);
} }
p_last--; p_last--;
} }
if (!(p_first < p_last)) { if (p_first >= p_last) {
return p_first; return p_first;
} }
@ -202,10 +206,7 @@ public:
int64_t cut = partitioner( int64_t cut = partitioner(
p_first, p_first,
p_last, p_last,
median_of_3( median_of_3_index(p_array, p_first, p_first + (p_last - p_first) / 2, p_last - 1),
p_array[p_first],
p_array[p_first + (p_last - p_first) / 2],
p_array[p_last - 1]),
p_array); p_array);
introsort(cut, p_last, p_array, p_max_depth); introsort(cut, p_last, p_array, p_max_depth);
@ -226,10 +227,7 @@ public:
int64_t cut = partitioner( int64_t cut = partitioner(
p_first, p_first,
p_last, p_last,
median_of_3( median_of_3_index(p_array, p_first, p_first + (p_last - p_first) / 2, p_last - 1),
p_array[p_first],
p_array[p_first + (p_last - p_first) / 2],
p_array[p_last - 1]),
p_array); p_array);
if (cut <= p_nth) { if (cut <= p_nth) {