| 29 #include "cx/list.h" |
29 #include "cx/list.h" |
| 30 |
30 |
| 31 #include <string.h> |
31 #include <string.h> |
| 32 #include <assert.h> |
32 #include <assert.h> |
| 33 |
33 |
| |
34 // we don't want to include the full array_list.h. |
| |
35 // therefore, we only forward declare the one function we want to use |
| |
36 CX_EXPORT void cx_array_qsort_c(void *array, size_t nmemb, size_t size, |
| |
37 cx_compare_func2 fn, void *context); |
| |
38 |
| |
39 |
| 34 int cx_list_compare_wrapper(const void *l, const void *r, void *c) { |
40 int cx_list_compare_wrapper(const void *l, const void *r, void *c) { |
| 35 CxList *list = c; |
41 CxList *list = c; |
| 36 const void *left; |
42 const void *left; |
| 37 const void *right; |
43 const void *right; |
| 38 if (cxCollectionStoresPointers(list)) { |
44 if (cxCollectionStoresPointers(list)) { |
| 281 size_t n |
287 size_t n |
| 282 ) { |
288 ) { |
| 283 return cx_list_default_insert_sorted_impl(list, sorted_data, n, false); |
289 return cx_list_default_insert_sorted_impl(list, sorted_data, n, false); |
| 284 } |
290 } |
| 285 |
291 |
| 286 // TODO: remove this hack once we have a solution for qsort() / qsort_s() |
|
| 287 static _Thread_local CxList *cx_hack_for_qsort_list; |
|
| 288 static int cx_hack_cmp_for_qsort(const void *l, const void *r) { |
|
| 289 return cx_list_compare_wrapper(l, r, cx_hack_for_qsort_list); |
|
| 290 } |
|
| 291 |
|
| 292 void cx_list_default_sort(struct cx_list_s *list) { |
292 void cx_list_default_sort(struct cx_list_s *list) { |
| 293 size_t elem_size = list->collection.elem_size; |
293 size_t elem_size = list->collection.elem_size; |
| 294 size_t list_size = list->collection.size; |
294 size_t list_size = list->collection.size; |
| 295 void *tmp = cxMallocDefault(elem_size * list_size); |
295 void *tmp = cxMallocDefault(elem_size * list_size); |
| 296 if (tmp == NULL) abort(); // LCOV_EXCL_LINE |
296 if (tmp == NULL) abort(); // LCOV_EXCL_LINE |
| 302 memcpy(loc, src, elem_size); |
302 memcpy(loc, src, elem_size); |
| 303 loc += elem_size; |
303 loc += elem_size; |
| 304 } |
304 } |
| 305 |
305 |
| 306 // qsort |
306 // qsort |
| 307 // TODO: qsort_s() is not as nice as we thought |
307 cx_array_qsort_c(tmp, list_size, elem_size, cx_list_compare_wrapper, list); |
| 308 cx_hack_for_qsort_list = list; |
|
| 309 qsort(tmp, list_size, elem_size, cx_hack_cmp_for_qsort); |
|
| 310 |
308 |
| 311 // copy elements back |
309 // copy elements back |
| 312 loc = tmp; |
310 loc = tmp; |
| 313 for (size_t i = 0; i < list_size; i++) { |
311 for (size_t i = 0; i < list_size; i++) { |
| 314 void *dest = list->cl->at(list, i); |
312 void *dest = list->cl->at(list, i); |