| 23 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN |
23 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN |
| 24 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) |
24 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) |
| 25 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE |
25 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE |
| 26 * POSSIBILITY OF SUCH DAMAGE. |
26 * POSSIBILITY OF SUCH DAMAGE. |
| 27 */ |
27 */ |
| |
28 |
| |
29 #ifdef WITH_MEMRCHR |
| |
30 #define _GNU_SOURCE |
| |
31 #endif |
| 28 |
32 |
| 29 #include "cx/array_list.h" |
33 #include "cx/array_list.h" |
| 30 #include "cx/compare.h" |
34 #include "cx/compare.h" |
| 31 #include <assert.h> |
35 #include <assert.h> |
| 32 #include <string.h> |
36 #include <string.h> |
| 347 cx_compare_func_wrapper wrapper = {cmp_func}; |
351 cx_compare_func_wrapper wrapper = {cmp_func}; |
| 348 return cx_array_insert_sorted_s_(allocator, array, elem_size, sorted_data, |
352 return cx_array_insert_sorted_s_(allocator, array, elem_size, sorted_data, |
| 349 n, allow_duplicates, cx_acmp_wrap, &wrapper); |
353 n, allow_duplicates, cx_acmp_wrap, &wrapper); |
| 350 } |
354 } |
| 351 |
355 |
| |
356 #ifndef WITH_QSORT_R |
| |
357 static thread_local cx_compare_func2 cx_array_fn_for_qsort; |
| |
358 static thread_local void *cx_array_context_for_qsort; |
| |
359 static int cx_array_qsort_wrapper(const void *l, const void *r) { |
| |
360 return cx_array_fn_for_qsort(l, r, cx_array_context_for_qsort); |
| |
361 } |
| |
362 #endif |
| |
363 |
| |
364 void cx_array_qsort_c(void *array, size_t nmemb, size_t size, |
| |
365 cx_compare_func2 fn, void *context) { |
| |
366 #ifdef WITH_QSORT_R |
| |
367 qsort_r(array, nmemb, size, fn, context); |
| |
368 #else |
| |
369 cx_array_fn_for_qsort = fn; |
| |
370 cx_array_context_for_qsort = context; |
| |
371 qsort(array, nmemb, size, cx_array_qsort_wrapper); |
| |
372 #endif |
| |
373 } |
| |
374 |
| 352 CxIterator cx_array_iterator_(CxArray *array, size_t elem_size) { |
375 CxIterator cx_array_iterator_(CxArray *array, size_t elem_size) { |
| 353 return cxIterator(array->data, elem_size, array->size); |
376 return cxIterator(array->data, elem_size, array->size); |
| 354 } |
377 } |
| 355 |
378 |
| 356 CxIterator cx_array_iterator_ptr_(CxArray *array) { |
379 CxIterator cx_array_iterator_ptr_(CxArray *array) { |
| 847 cur += list->collection.elem_size; |
870 cur += list->collection.elem_size; |
| 848 } |
871 } |
| 849 return list->collection.size; |
872 return list->collection.size; |
| 850 } |
873 } |
| 851 |
874 |
| 852 // TODO: remove this hack once we have a solution for qsort() / qsort_s() |
|
| 853 static _Thread_local CxList *cx_hack_for_qsort_list; |
|
| 854 static int cx_hack_cmp_for_qsort(const void *l, const void *r) { |
|
| 855 return cx_list_compare_wrapper(l, r, cx_hack_for_qsort_list); |
|
| 856 } |
|
| 857 |
|
| 858 static void cx_arl_sort(struct cx_list_s *list) { |
875 static void cx_arl_sort(struct cx_list_s *list) { |
| 859 // TODO: think about if we can somehow use qsort()_s |
876 cx_array_qsort_c(((cx_array_list *) list)->data, |
| 860 cx_hack_for_qsort_list = list; |
|
| 861 qsort(((cx_array_list *) list)->data, |
|
| 862 list->collection.size, |
877 list->collection.size, |
| 863 list->collection.elem_size, |
878 list->collection.elem_size, |
| 864 cx_hack_cmp_for_qsort |
879 cx_list_compare_wrapper, |
| |
880 list |
| 865 ); |
881 ); |
| 866 } |
882 } |
| 867 |
883 |
| 868 static int cx_arl_compare( |
884 static int cx_arl_compare( |
| 869 const struct cx_list_s *list, |
885 const struct cx_list_s *list, |