#include /** * Internal macro helper to swap two arbitrary blocks of memory of given size. */ C_STATIC_FORCE_INLINE void c_SwapInternal(char* a, char* b, c_size_t size, void* temp) { if (a == b) return; memcpy(temp, a, size); memcpy(a, b, size); memcpy(b, temp, size); } /** * Chooses the median of left, center, and right elements as the pivot, * hides it at (right - 1), and returns a pointer to it. */ C_STATIC_FORCE_INLINE void* c_MedianOfThree(char* arr, long long left, long long right, c_size_t size, void* temp, int (*compar)(const void*, const void*)) { long long center = left + (right - left) / 2; // Order left, center, right if (compar(arr + (left * size), arr + (center * size)) > 0) { c_SwapInternal(arr + (left * size), arr + (center * size), size, temp); } if (compar(arr + (left * size), arr + (right * size)) > 0) { c_SwapInternal(arr + (left * size), arr + (right * size), size, temp); } if (compar(arr + (center * size), arr + (right * size)) > 0) { c_SwapInternal(arr + (center * size), arr + (right * size), size, temp); } // Place pivot at position (right - 1) c_SwapInternal(arr + (center * size), arr + ((right - 1) * size), size, temp); return arr + ((right - 1) * size); } /* ------------------------------------------------------------------------------------------------------------------ */ /* */ void c_QuickSortSub(char* arr, long long left, long long right, c_size_t size, void* temp, int (*compar)(const void*, const void*)) { // Optimization: Fallback to manual insertion sort for tiny arrays to prune deep recursion if (left + 10 > right) { // Basic Inline Insertion Sort boundary loop for (long long i = left + 1; i <= right; i++) { memcpy(temp, arr + (i * size), size); long long j = i; while (j > left && compar(arr + ((j - 1) * size), temp) > 0) { memcpy(arr + (j * size), arr + ((j - 1) * size), size); j--; } memcpy(arr + (j * size), temp, size); } return; } // Retrieve Median Pivot c_MedianOfThree(arr, left, right, size, temp, compar); long long i = left; long long j = right - 1; // Hoare Partitioning Loop while (1) { while (compar(arr + ((++i) * size), arr + ((right - 1) * size)) < 0); while (compar(arr + ((--j) * size), arr + ((right - 1) * size)) > 0); if (i < j) { c_SwapInternal(arr + (i * size), arr + (j * size), size, temp); } else { break; } } // Restore pivot to its correct final slot c_SwapInternal(arr + (i * size), arr + ((right - 1) * size), size, temp); // Recursively execute left and right segments c_QuickSortSub(arr, left, i - 1, size, temp, compar); c_QuickSortSub(arr, i + 1, right, size, temp, compar); }