--- 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;