1.1 --- a/src/linked_list.c Sun Mar 05 10:55:32 2023 +0100 1.2 +++ b/src/linked_list.c Tue Mar 14 20:25:24 2023 +0100 1.3 @@ -569,6 +569,11 @@ 1.4 // out-of-bounds check 1.5 if (node == NULL) return 1; 1.6 1.7 + // element destruction 1.8 + if (list->content_destructor_type != CX_DESTRUCTOR_NONE) { 1.9 + cx_list_invoke_destructor(list, node->payload); 1.10 + } 1.11 + 1.12 // remove 1.13 cx_linked_list_remove((void **) &ll->begin, (void **) &ll->end, 1.14 CX_LL_LOC_PREV, CX_LL_LOC_NEXT, node); 1.15 @@ -582,6 +587,48 @@ 1.16 return 0; 1.17 } 1.18 1.19 +static void cx_ll_clear(struct cx_list_s *list) { 1.20 + if (list->size == 0) return; 1.21 + 1.22 + cx_linked_list *ll = (cx_linked_list *) list; 1.23 + cx_linked_list_node *node = ll->begin; 1.24 + 1.25 + // looks super redundant, but avoids repeatedly checking 1.26 + // the destructor type for each element 1.27 + switch (list->content_destructor_type) { 1.28 + case CX_DESTRUCTOR_SIMPLE: { 1.29 + while (node != NULL) { 1.30 + list->simple_destructor(node->payload); 1.31 + cx_linked_list_node *next = node->next; 1.32 + cxFree(list->allocator, node); 1.33 + node = next; 1.34 + } 1.35 + break; 1.36 + } 1.37 + case CX_DESTRUCTOR_ADVANCED: { 1.38 + while (node != NULL) { 1.39 + list->advanced_destructor.func(list->advanced_destructor.data, 1.40 + node->payload); 1.41 + cx_linked_list_node *next = node->next; 1.42 + cxFree(list->allocator, node); 1.43 + node = next; 1.44 + } 1.45 + break; 1.46 + } 1.47 + case CX_DESTRUCTOR_NONE: { 1.48 + while (node != NULL) { 1.49 + cx_linked_list_node *next = node->next; 1.50 + cxFree(list->allocator, node); 1.51 + node = next; 1.52 + } 1.53 + break; 1.54 + } 1.55 + } 1.56 + 1.57 + ll->begin = ll->end = NULL; 1.58 + list->size = 0; 1.59 +} 1.60 + 1.61 #ifndef CX_LINKED_LIST_SWAP_SBO_SIZE 1.62 #define CX_LINKED_LIST_SWAP_SBO_SIZE 16 1.63 #endif 1.64 @@ -753,13 +800,17 @@ 1.65 if (itbase->remove) { 1.66 itbase->remove = false; 1.67 struct cx_mut_iterator_s *iter = it; 1.68 + struct cx_list_s *list = iter->src_handle; 1.69 cx_linked_list *ll = iter->src_handle; 1.70 cx_linked_list_node *node = iter->elem_handle; 1.71 iter->elem_handle = node->next; 1.72 + if (list->content_destructor_type != CX_DESTRUCTOR_NONE) { 1.73 + cx_list_invoke_destructor(list, node->payload); 1.74 + } 1.75 cx_linked_list_remove((void **) &ll->begin, (void **) &ll->end, 1.76 CX_LL_LOC_PREV, CX_LL_LOC_NEXT, node); 1.77 - ll->base.size--; 1.78 - cxFree(ll->base.allocator, node); 1.79 + list->size--; 1.80 + cxFree(list->allocator, node); 1.81 } else { 1.82 struct cx_iterator_s *iter = it; 1.83 iter->index++; 1.84 @@ -773,14 +824,18 @@ 1.85 if (itbase->remove) { 1.86 itbase->remove = false; 1.87 struct cx_mut_iterator_s *iter = it; 1.88 + struct cx_list_s *list = iter->src_handle; 1.89 cx_linked_list *ll = iter->src_handle; 1.90 cx_linked_list_node *node = iter->elem_handle; 1.91 iter->elem_handle = node->prev; 1.92 iter->index--; 1.93 + if (list->content_destructor_type != CX_DESTRUCTOR_NONE) { 1.94 + cx_list_invoke_destructor(list, node->payload); 1.95 + } 1.96 cx_linked_list_remove((void **) &ll->begin, (void **) &ll->end, 1.97 CX_LL_LOC_PREV, CX_LL_LOC_NEXT, node); 1.98 - ll->base.size--; 1.99 - cxFree(ll->base.allocator, node); 1.100 + list->size--; 1.101 + cxFree(list->allocator, node); 1.102 } else { 1.103 struct cx_iterator_s *iter = it; 1.104 iter->index--; 1.105 @@ -861,6 +916,7 @@ 1.106 cx_ll_insert_array, 1.107 cx_ll_insert_iter, 1.108 cx_ll_remove, 1.109 + cx_ll_clear, 1.110 cx_ll_swap, 1.111 cx_ll_at, 1.112 cx_ll_find,