ucx/array_list.c

branch
dav-2
changeset 894
e86049631677
parent 891
4d58cbcc9efa
--- a/ucx/array_list.c	Tue Dec 30 21:39:38 2025 +0100
+++ b/ucx/array_list.c	Wed Dec 31 16:41:16 2025 +0100
@@ -101,11 +101,18 @@
     if (index > array->size) return -1;
     if (n == 0) return 0;
 
+    // calculate required capacity
+    size_t req_capacity = array->size + n;
+    if (req_capacity <= array->size) {
+        errno = EOVERFLOW;
+        return -1;
+    }
+
     // guarantee enough capacity
-    if (array->capacity < array->size + n) {
-        const size_t new_capacity = cx_array_grow_capacity(array->capacity,array->size + n);
+    if (array->capacity < req_capacity) {
+        const size_t new_capacity = cx_array_grow_capacity(array->capacity,req_capacity);
         if (cxReallocateArray(allocator, &array->data, new_capacity, elem_size)) {
-            return -1; // LCOV_EXCL_LINE
+            return -1;
         }
         array->capacity = new_capacity;
     }
@@ -115,8 +122,8 @@
     dst += index * elem_size;
 
     // do we need to move some elements?
-    if (index < array->size) {
-        size_t elems_to_move = array->size - index;
+    size_t elems_to_move = array->size - index;
+    if (elems_to_move > 0) {
         char *target = dst + n * elem_size;
         memmove(target, dst, elems_to_move * elem_size);
     }
@@ -314,7 +321,9 @@
                             left_src += elem_size;
                             skip_len++;
                         } else {
-                            break;
+                            // should be unreachable because the requirement is
+                            // that the source array is sorted
+                            break; // LCOV_EXCL_LINE
                         }
                     }
                 }
@@ -350,22 +359,42 @@
 ) {
     cx_compare_func_wrapper wrapper = {cmp_func};
     return cx_array_insert_sorted_c_(allocator, array, elem_size, sorted_data,
-        n, cx_ccmp_wrap, &wrapper, allow_duplicates);
+        n, cx_cmp_wrap, &wrapper, allow_duplicates);
 }
 
 #ifndef WITH_QSORT_R
-static thread_local cx_compare_func2 cx_array_fn_for_qsort;
-static thread_local void *cx_array_context_for_qsort;
+static cx_thread_local cx_compare_func2 cx_array_fn_for_qsort;
+static cx_thread_local void *cx_array_context_for_qsort;
 static int cx_array_qsort_wrapper(const void *l, const void *r) {
     return cx_array_fn_for_qsort(l, r, cx_array_context_for_qsort);
 }
 #endif
 
+#if defined(WITH_QSORT_R) && defined(__APPLE__)
+// macOS uses a different comparefunc signature for qsort_r
+typedef struct QsortCmpFuncWrapper {
+    cx_compare_func2 fn;
+    void *context;
+} QsortCmpFuncWrapper;
+
+static int sort_comparefunc(void *context, const void *left, const void *right){
+    QsortCmpFuncWrapper *w = context;
+    return w->fn(left, right, w->context);
+}
+#endif
+
 void cx_array_qsort_c(void *array, size_t nmemb, size_t size,
         cx_compare_func2 fn, void *context) {
 #ifdef WITH_QSORT_R
+#ifndef __APPLE__
     qsort_r(array, nmemb, size, fn, context);
 #else
+    QsortCmpFuncWrapper wrapper;
+    wrapper.fn = fn;
+    wrapper.context = context;
+    qsort_r(array, nmemb, size, &wrapper, sort_comparefunc);
+#endif
+#else
     cx_array_fn_for_qsort = fn;
     cx_array_context_for_qsort = context;
     qsort(array, nmemb, size, cx_array_qsort_wrapper);
@@ -578,7 +607,7 @@
         cx_compare_func cmp_func
 ) {
     cx_compare_func_wrapper wrapper = {cmp_func};
-    return cx_array_binary_search_inf_c(arr, size, elem_size, elem, cx_ccmp_wrap, &wrapper);
+    return cx_array_binary_search_inf_c(arr, size, elem_size, elem, cx_cmp_wrap, &wrapper);
 }
 
 size_t cx_array_binary_search(
@@ -589,7 +618,7 @@
         cx_compare_func cmp_func
 ) {
     cx_compare_func_wrapper wrapper = {cmp_func};
-    return cx_array_binary_search_c(arr, size, elem_size, elem, cx_ccmp_wrap, &wrapper);
+    return cx_array_binary_search_c(arr, size, elem_size, elem, cx_cmp_wrap, &wrapper);
 }
 
 size_t cx_array_binary_search_sup(
@@ -600,7 +629,7 @@
         cx_compare_func cmp_func
 ) {
     cx_compare_func_wrapper wrapper = {cmp_func};
-    return cx_array_binary_search_sup_c(arr, size, elem_size, elem, cx_ccmp_wrap, &wrapper);
+    return cx_array_binary_search_sup_c(arr, size, elem_size, elem, cx_cmp_wrap, &wrapper);
 }
 
 #ifndef CX_ARRAY_SWAP_SBO_SIZE
@@ -1064,8 +1093,7 @@
 
     cx_array_list *list = cxCalloc(allocator, 1, sizeof(cx_array_list));
     if (list == NULL) return NULL;
-    cx_list_init((CxList*)list, &cx_array_list_class,
-        allocator, elem_size);
+    cx_list_init((CxList*)list, &cx_array_list_class, allocator, elem_size);
     list->capacity = initial_capacity;
 
     // allocate the array after the real elem_size is known

mercurial