src/cx/list.h

changeset 1419
e46406fd1b3c
parent 1418
5e1579713bcf
--- a/src/cx/list.h	Fri Oct 10 12:26:43 2025 +0200
+++ b/src/cx/list.h	Fri Oct 10 17:24:19 2025 +0200
@@ -115,6 +115,17 @@
     );
 
     /**
+     * Member function for inserting multiple elements if they do not exist.
+     *
+     * @see cx_list_default_insert_unique()
+     */
+    size_t (*insert_unique)(
+            struct cx_list_s *list,
+            const void *sorted_data,
+            size_t n
+    );
+
+    /**
      * Member function for inserting an element relative to an iterator position.
      */
     int (*insert_iter)(
@@ -269,6 +280,31 @@
 );
 
 /**
+ * Default implementation of an array insert where only elements are inserted when they don't exist in the list.
+ *
+ * This function is similar to cx_list_default_insert_sorted(), except it skips elements that are already in the list.
+ * The @p sorted_data itself must not contain duplicates.
+ *
+ * @note The return value of this function denotes the number of elements from the @p sorted_data that are definitely
+ * contained in the list after completing the call. It is @em not the number of elements that were newly inserted.
+ * That means, when no error occurred, the return value should be @p n.
+ *
+ * Use this in your own list class if you do not want to implement an optimized version for your list.
+ *
+ * @param list the list
+ * @param sorted_data a pointer to the array of pre-sorted data to insert
+ * @param n the number of elements to insert
+ * @return the number of elements from the @p sorted_data that are definitely present in the list after this call
+ */
+cx_attr_nonnull
+cx_attr_export
+size_t cx_list_default_insert_unique(
+        struct cx_list_s *list,
+        const void *sorted_data,
+        size_t n
+);
+
+/**
  * Default unoptimized sort implementation.
  *
  * This function will copy all data to an array, sort the array with standard
@@ -490,6 +526,27 @@
 }
 
 /**
+ * Inserts an item into a sorted list if it does not exist.
+ *
+ * If the list is not sorted already, the behavior is undefined.
+ *
+ * @param list the list
+ * @param elem a pointer to the element to add
+ * @retval zero success (also when the element was already in the list)
+ * @retval non-zero memory allocation failure
+ */
+cx_attr_nonnull
+static inline int cxListInsertUnique(
+        CxList *list,
+        const void *elem
+) {
+    assert(list->collection.sorted || list->collection.size == 0);
+    list->collection.sorted = true;
+    const void *data = list->collection.store_pointer ? &elem : elem;
+    return list->cl->insert_unique(list, data, 1) == 0;
+}
+
+/**
  * Inserts multiple items to the list at the specified index.
  * If @p index equals the list size, this is effectively cxListAddArray().
  *
@@ -522,7 +579,7 @@
 /**
  * Inserts a sorted array into a sorted list.
  *
- * This method is usually more efficient than inserting each element separately,
+ * This method is usually more efficient than inserting each element separately
  * because consecutive chunks of sorted data are inserted in one pass.
  *
  * If there is not enough memory to add all elements, the returned value is
@@ -550,6 +607,45 @@
 }
 
 /**
+ * Inserts a sorted array into a sorted list, skipping duplicates.
+ *
+ * This method is usually more efficient than inserting each element separately
+ * because consecutive chunks of sorted data are inserted in one pass.
+ *
+ * If there is not enough memory to add all elements, the returned value is
+ * less than @p n.
+ *
+ * @note The return value of this function denotes the number of elements
+ * from the @p sorted_data that are definitely contained in the list after
+ * completing the call. It is @em not the number of elements that were newly
+ * inserted. That means, when no error occurred, the return value should
+ * be @p n.
+ *
+ * If this list is storing pointers instead of objects @p array is expected to
+ * be an array of pointers.
+ *
+ * If the list is not sorted already, the behavior is undefined.
+ * This is also the case when the @p array is not sorted or already contains duplicates.
+ *
+ * @param list the list
+ * @param array a pointer to the elements to add
+ * @param n the number of elements to add
+ * @return the number of added elements
+ *
+ * @return the number of elements from the @p sorted_data that are definitely present in the list after this call
+ */
+cx_attr_nonnull
+static inline size_t cxListInsertUniqueArray(
+        CxList *list,
+        const void *array,
+        size_t n
+) {
+    assert(list->collection.sorted || list->collection.size == 0);
+    list->collection.sorted = true;
+    return list->cl->insert_unique(list, array, n);
+}
+
+/**
  * Inserts an element after the current location of the specified iterator.
  *
  * The used iterator remains operational, but all other active iterators should

mercurial