ucx/array_list.c

changeset 2
fbdfaacc4182
parent 0
2483f517c562
--- a/ucx/array_list.c	Mon Jan 22 17:27:47 2024 +0100
+++ b/ucx/array_list.c	Sat Jan 27 17:50:19 2024 +0100
@@ -27,12 +27,30 @@
  */
 
 #include "cx/array_list.h"
+#include "cx/compare.h"
 #include <assert.h>
 #include <string.h>
 
+// Default array reallocator
+
+static void *cx_array_default_realloc(
+        void *array,
+        size_t capacity,
+        size_t elem_size,
+        __attribute__((__unused__)) struct cx_array_reallocator_s *alloc
+) {
+    return realloc(array, capacity * elem_size);
+}
+
+struct cx_array_reallocator_s cx_array_default_reallocator_impl = {
+        cx_array_default_realloc, NULL, NULL, 0, 0
+};
+
+struct cx_array_reallocator_s *cx_array_default_reallocator = &cx_array_default_reallocator_impl;
+
 // LOW LEVEL ARRAY LIST FUNCTIONS
 
-enum cx_array_copy_result cx_array_copy(
+enum cx_array_result cx_array_copy(
         void **target,
         size_t *size,
         size_t *capacity,
@@ -59,7 +77,7 @@
     if (needrealloc) {
         // a reallocator and a capacity variable must be available
         if (reallocator == NULL || capacity == NULL) {
-            return CX_ARRAY_COPY_REALLOC_NOT_SUPPORTED;
+            return CX_ARRAY_REALLOC_NOT_SUPPORTED;
         }
 
         // check, if we need to repair the src pointer
@@ -77,7 +95,7 @@
                 *target, cap, elem_size, reallocator
         );
         if (newmem == NULL) {
-            return CX_ARRAY_COPY_REALLOC_FAILED;
+            return CX_ARRAY_REALLOC_FAILED;
         }
 
         // repair src pointer, if necessary
@@ -99,12 +117,13 @@
     *size = newsize;
 
     // return successfully
-    return CX_ARRAY_COPY_SUCCESS;
+    return CX_ARRAY_SUCCESS;
 }
 
 #ifndef CX_ARRAY_SWAP_SBO_SIZE
 #define CX_ARRAY_SWAP_SBO_SIZE 128
 #endif
+unsigned cx_array_swap_sbo_size = CX_ARRAY_SWAP_SBO_SIZE;
 
 void cx_array_swap(
         void *arr,
@@ -208,7 +227,7 @@
         size_t elems_to_move = list->size - index;
         size_t start_of_moved = index + n;
 
-        if (CX_ARRAY_COPY_SUCCESS != cx_array_copy(
+        if (CX_ARRAY_SUCCESS != cx_array_copy(
                 &arl->data,
                 &list->size,
                 &arl->capacity,
@@ -228,7 +247,7 @@
     // therefore, it is impossible to leave this function with an invalid array
 
     // place the new elements
-    if (CX_ARRAY_COPY_SUCCESS == cx_array_copy(
+    if (CX_ARRAY_SUCCESS == cx_array_copy(
             &arl->data,
             &list->size,
             &arl->capacity,
@@ -308,11 +327,14 @@
             list->size - index - 1,
             &arl->reallocator
     );
-    if (result == 0) {
-        // decrease the size
-        list->size--;
-    }
-    return result;
+
+    // cx_array_copy cannot fail, array cannot grow
+    assert(result == 0);
+
+    // decrease the size
+    list->size--;
+
+    return 0;
 }
 
 static void cx_arl_clear(struct cx_list_s *list) {
@@ -362,9 +384,10 @@
     }
 }
 
-static ssize_t cx_arl_find(
-        struct cx_list_s const *list,
-        void const *elem
+static ssize_t cx_arl_find_remove(
+        struct cx_list_s *list,
+        void const *elem,
+        bool remove
 ) {
     assert(list->cmpfunc != NULL);
     assert(list->size < SIZE_MAX / 2);
@@ -372,7 +395,15 @@
 
     for (ssize_t i = 0; i < (ssize_t) list->size; i++) {
         if (0 == list->cmpfunc(elem, cur)) {
-            return i;
+            if (remove) {
+                if (0 == cx_arl_remove(list, i)) {
+                    return i;
+                } else {
+                    return -1;
+                }
+            } else {
+                return i;
+            }
         }
         cur += list->item_size;
     }
@@ -500,7 +531,7 @@
         cx_arl_clear,
         cx_arl_swap,
         cx_arl_at,
-        cx_arl_find,
+        cx_arl_find_remove,
         cx_arl_sort,
         cx_arl_compare,
         cx_arl_reverse,
@@ -522,13 +553,14 @@
 
     list->base.cl = &cx_array_list_class;
     list->base.allocator = allocator;
-    list->base.cmpfunc = comparator;
     list->capacity = initial_capacity;
 
     if (item_size > 0) {
         list->base.item_size = item_size;
+        list->base.cmpfunc = comparator;
     } else {
         item_size = sizeof(void *);
+        list->base.cmpfunc = comparator == NULL ? cx_cmp_ptr : comparator;
         cxListStorePointers((CxList *) list);
     }
 

mercurial