diff -r d50b5dc1e058 -r af5bf4603a5d src/linked_list.c --- a/src/linked_list.c Sun Mar 05 10:55:32 2023 +0100 +++ b/src/linked_list.c Tue Mar 14 20:25:24 2023 +0100 @@ -569,6 +569,11 @@ // out-of-bounds check if (node == NULL) return 1; + // element destruction + if (list->content_destructor_type != CX_DESTRUCTOR_NONE) { + cx_list_invoke_destructor(list, node->payload); + } + // remove cx_linked_list_remove((void **) &ll->begin, (void **) &ll->end, CX_LL_LOC_PREV, CX_LL_LOC_NEXT, node); @@ -582,6 +587,48 @@ return 0; } +static void cx_ll_clear(struct cx_list_s *list) { + if (list->size == 0) return; + + cx_linked_list *ll = (cx_linked_list *) list; + cx_linked_list_node *node = ll->begin; + + // looks super redundant, but avoids repeatedly checking + // the destructor type for each element + switch (list->content_destructor_type) { + case CX_DESTRUCTOR_SIMPLE: { + while (node != NULL) { + list->simple_destructor(node->payload); + cx_linked_list_node *next = node->next; + cxFree(list->allocator, node); + node = next; + } + break; + } + case CX_DESTRUCTOR_ADVANCED: { + while (node != NULL) { + list->advanced_destructor.func(list->advanced_destructor.data, + node->payload); + cx_linked_list_node *next = node->next; + cxFree(list->allocator, node); + node = next; + } + break; + } + case CX_DESTRUCTOR_NONE: { + while (node != NULL) { + cx_linked_list_node *next = node->next; + cxFree(list->allocator, node); + node = next; + } + break; + } + } + + ll->begin = ll->end = NULL; + list->size = 0; +} + #ifndef CX_LINKED_LIST_SWAP_SBO_SIZE #define CX_LINKED_LIST_SWAP_SBO_SIZE 16 #endif @@ -753,13 +800,17 @@ if (itbase->remove) { itbase->remove = false; struct cx_mut_iterator_s *iter = it; + struct cx_list_s *list = iter->src_handle; cx_linked_list *ll = iter->src_handle; cx_linked_list_node *node = iter->elem_handle; iter->elem_handle = node->next; + if (list->content_destructor_type != CX_DESTRUCTOR_NONE) { + cx_list_invoke_destructor(list, node->payload); + } cx_linked_list_remove((void **) &ll->begin, (void **) &ll->end, CX_LL_LOC_PREV, CX_LL_LOC_NEXT, node); - ll->base.size--; - cxFree(ll->base.allocator, node); + list->size--; + cxFree(list->allocator, node); } else { struct cx_iterator_s *iter = it; iter->index++; @@ -773,14 +824,18 @@ if (itbase->remove) { itbase->remove = false; struct cx_mut_iterator_s *iter = it; + struct cx_list_s *list = iter->src_handle; cx_linked_list *ll = iter->src_handle; cx_linked_list_node *node = iter->elem_handle; iter->elem_handle = node->prev; iter->index--; + if (list->content_destructor_type != CX_DESTRUCTOR_NONE) { + cx_list_invoke_destructor(list, node->payload); + } cx_linked_list_remove((void **) &ll->begin, (void **) &ll->end, CX_LL_LOC_PREV, CX_LL_LOC_NEXT, node); - ll->base.size--; - cxFree(ll->base.allocator, node); + list->size--; + cxFree(list->allocator, node); } else { struct cx_iterator_s *iter = it; iter->index--; @@ -861,6 +916,7 @@ cx_ll_insert_array, cx_ll_insert_iter, cx_ll_remove, + cx_ll_clear, cx_ll_swap, cx_ll_at, cx_ll_find,