src/list.c

changeset 1419
e46406fd1b3c
parent 1345
79a865252b16
--- a/src/list.c	Fri Oct 10 12:26:43 2025 +0200
+++ b/src/list.c	Fri Oct 10 17:24:19 2025 +0200
@@ -90,6 +90,17 @@
     return result;
 }
 
+static size_t cx_pl_insert_unique(
+        struct cx_list_s *list,
+        const void *array,
+        size_t n
+) {
+    cx_pl_hack_cmpfunc(list);
+    size_t result = list->climpl->insert_unique(list, array, n);
+    cx_pl_unhack_cmpfunc(list);
+    return result;
+}
+
 static int cx_pl_insert_iter(
         struct cx_iterator_s *iter,
         const void *elem,
@@ -181,6 +192,7 @@
         cx_pl_insert_element,
         cx_pl_insert_array,
         cx_pl_insert_sorted,
+        cx_pl_insert_unique,
         cx_pl_insert_iter,
         cx_pl_remove,
         cx_pl_clear,
@@ -238,6 +250,7 @@
         NULL,
         NULL,
         NULL,
+        NULL,
         cx_emptyl_noop,
         NULL,
         cx_emptyl_at,
@@ -289,10 +302,11 @@
     return i;
 }
 
-size_t cx_list_default_insert_sorted(
+static size_t cx_list_default_insert_sorted_impl(
         struct cx_list_s *list,
         const void *sorted_data,
-        size_t n
+        size_t n,
+        bool allow_duplicates
 ) {
     // corner case
     if (n == 0) return 0;
@@ -310,8 +324,22 @@
 
         // compare current list element with first source element
         // if less or equal, skip
-        if (cmp(list_elm, src) <= 0) {
-            continue;
+        {
+            int d = cmp(list_elm, src);
+            if (d <= 0) {
+                if (!allow_duplicates && d == 0) {
+                    src += elem_size;
+                    si++;
+                    inserted++; // we also count duplicates for the return value
+                    while (si < n && cmp(list_elm, src) == 0) {
+                        src += elem_size;
+                        si++;
+                        inserted++;
+                    }
+                    if (inserted == n) return inserted;
+                }
+                continue;
+            }
         }
 
         // determine number of consecutive elements that can be inserted
@@ -351,6 +379,22 @@
     return inserted;
 }
 
+size_t cx_list_default_insert_sorted(
+        struct cx_list_s *list,
+        const void *sorted_data,
+        size_t n
+) {
+    return cx_list_default_insert_sorted_impl(list, sorted_data, n, true);
+}
+
+size_t cx_list_default_insert_unique(
+        struct cx_list_s *list,
+        const void *sorted_data,
+        size_t n
+) {
+    return cx_list_default_insert_sorted_impl(list, sorted_data, n, false);
+}
+
 void cx_list_default_sort(struct cx_list_s *list) {
     size_t elem_size = list->collection.elem_size;
     size_t list_size = list->collection.size;

mercurial