| 769 | // sorted output. O(M log N). Matches std::partial_sort. |
| 770 | template <typename Compare> |
| 771 | inline void das_partial_sort_r(void *base, size_t nel, size_t n, size_t width, Compare cmp) |
| 772 | { |
| 773 | if (nel <= 1 || n == 0) return; |
| 774 | if (n > nel) n = nel; |
| 775 | unsigned char *data = (unsigned char *)base; |
| 776 | das_make_heap_r(data, n, width, cmp); |
| 777 | for (size_t i = n; i < nel; i++) { |
| 778 | unsigned char *xi = data + i * width; |
| 779 | if (cmp(xi, data)) { // a[i] < heap top (current Nth-smallest) |
| 780 | byte_swap(data, xi, width);// displace top to position i (outside heap; never revisited) |
| 781 | das_sift_down_r(data, 0, n, width, cmp); |
| 782 | } |
| 783 | } |
| 784 | // Drain: pop max repeatedly into positions n-1, n-2, ... |
| 785 | for (size_t len = n; len > 1; len--) { |
| 786 | byte_swap(data, data + (len - 1) * width, width); |
| 787 | das_sift_down_r(data, 0, len - 1, width, cmp); |
| 788 | } |
| 789 | } |
| 790 | |
| 791 | // ============================================================================ |
| 792 | // Stable sort — adaptive natural-run merge (timsort-lite, no galloping). |
no test coverage detected