diff -r ec1f2015ec79 -r 75da57d4634e src/array_list.c --- a/src/array_list.c Sun Oct 06 19:17:41 2024 +0200 +++ b/src/array_list.c Mon Oct 07 20:20:21 2024 +0200 @@ -494,35 +494,58 @@ } } -static int cx_arl_remove( +static size_t cx_arl_remove( struct cx_list_s *list, - size_t index + size_t index, + size_t num, + void *targetbuf ) { cx_array_list *arl = (cx_array_list *) list; // out-of-bounds check + size_t remove; if (index >= list->collection.size) { - return 1; + remove = 0; + } else if (index + num > list->collection.size) { + remove = list->collection.size - index; + } else { + remove = num; } - // content destruction - cx_invoke_destructor(list, ((char *) arl->data) + index * list->collection.elem_size); + // easy exit + if (remove == 0) return 0; - // short-circuit removal of last element - if (index == list->collection.size - 1) { - list->collection.size--; - return 0; + // destroy or copy contents + if (targetbuf == NULL) { + for (size_t idx = index; idx < index + remove; idx++) { + cx_invoke_destructor( + list, + ((char *) arl->data) + idx * list->collection.elem_size + ); + } + } else { + memcpy( + targetbuf, + ((char *) arl->data) + index * list->collection.elem_size, + remove * list->collection.elem_size + ); } - // just move the elements starting at index to the left + // short-circuit removal of last elements + if (index + remove == list->collection.size) { + list->collection.size -= remove; + return remove; + } + + // just move the elements to the left int result = cx_array_copy( &arl->data, &list->collection.size, &arl->capacity, index, - ((char *) arl->data) + (index + 1) * list->collection.elem_size, + ((char *) arl->data) + (index + remove) * list->collection.elem_size, list->collection.elem_size, - list->collection.size - index - 1, + list->collection.size - index - remove, &arl->reallocator ); @@ -530,9 +553,9 @@ assert(result == 0); // decrease the size - list->collection.size--; + list->collection.size -= remove; - return 0; + return remove; } static void cx_arl_clear(struct cx_list_s *list) { @@ -594,7 +617,7 @@ for (ssize_t i = 0; i < (ssize_t) list->collection.size; i++) { if (0 == list->collection.cmpfunc(elem, cur)) { if (remove) { - if (0 == cx_arl_remove(list, i)) { + if (1 == cx_arl_remove(list, i, 1, NULL)) { return i; } else { return -1; @@ -664,7 +687,7 @@ struct cx_iterator_s *iter = it; if (iter->base.remove) { iter->base.remove = false; - cx_arl_remove(iter->src_handle.m, iter->index); + cx_arl_remove(iter->src_handle.m, iter->index, 1, NULL); } else { iter->index++; iter->elem_handle = @@ -678,7 +701,7 @@ const cx_array_list *list = iter->src_handle.c; if (iter->base.remove) { iter->base.remove = false; - cx_arl_remove(iter->src_handle.m, iter->index); + cx_arl_remove(iter->src_handle.m, iter->index, 1, NULL); } iter->index--; if (iter->index < list->base.collection.size) {