1.1 --- a/src/linked_list.c Wed Nov 23 22:40:55 2022 +0100 1.2 +++ b/src/linked_list.c Sat Nov 26 16:58:41 2022 +0100 1.3 @@ -643,13 +643,16 @@ 1.4 left->follow_ptr, right->follow_ptr, list->cmpfunc); 1.5 } 1.6 1.7 -static bool cx_ll_iter_valid(CxIterator const *iter) { 1.8 +static bool cx_ll_iter_valid(void const *it) { 1.9 + struct cx_iterator_s const *iter = it; 1.10 return iter->elem_handle != NULL; 1.11 } 1.12 1.13 -static void cx_ll_iter_next(CxIterator *iter) { 1.14 - if (iter->remove) { 1.15 - iter->remove = false; 1.16 +static void cx_ll_iter_next(void *it) { 1.17 + struct cx_iterator_base_s *itbase = it; 1.18 + if (itbase->remove) { 1.19 + itbase->remove = false; 1.20 + struct cx_mut_iterator_s *iter = it; 1.21 cx_linked_list *ll = iter->src_handle; 1.22 cx_linked_list_node *node = iter->elem_handle; 1.23 iter->elem_handle = node->next; 1.24 @@ -658,48 +661,85 @@ 1.25 ll->base.size--; 1.26 cxFree(ll->base.allocator, node); 1.27 } else { 1.28 + struct cx_iterator_s *iter = it; 1.29 iter->index++; 1.30 cx_linked_list_node *node = iter->elem_handle; 1.31 iter->elem_handle = node->next; 1.32 } 1.33 } 1.34 1.35 -static void *cx_ll_iter_current(CxIterator const *iter) { 1.36 +static void *cx_ll_iter_current(void const *it) { 1.37 + struct cx_iterator_s const *iter = it; 1.38 cx_linked_list_node *node = iter->elem_handle; 1.39 return node->payload; 1.40 } 1.41 1.42 -static void *cx_pll_iter_current(CxIterator const *iter) { 1.43 +static void *cx_pll_iter_current(void const *it) { 1.44 + struct cx_iterator_s const *iter = it; 1.45 cx_linked_list_node *node = iter->elem_handle; 1.46 return *(void **) node->payload; 1.47 } 1.48 1.49 +static bool cx_ll_iter_flag_rm(void *it) { 1.50 + struct cx_iterator_base_s *iter = it; 1.51 + if (iter->mutating) { 1.52 + iter->remove = true; 1.53 + return true; 1.54 + } else { 1.55 + return false; 1.56 + } 1.57 +} 1.58 + 1.59 static CxIterator cx_ll_iterator( 1.60 - struct cx_list_s *list, 1.61 + struct cx_list_s const *list, 1.62 size_t index 1.63 ) { 1.64 CxIterator iter; 1.65 iter.index = index; 1.66 iter.src_handle = list; 1.67 iter.elem_handle = cx_ll_node_at((cx_linked_list const *) list, index); 1.68 - iter.valid = cx_ll_iter_valid; 1.69 - iter.current = cx_ll_iter_current; 1.70 - iter.next = cx_ll_iter_next; 1.71 - iter.remove = false; 1.72 + iter.base.valid = cx_ll_iter_valid; 1.73 + iter.base.current = cx_ll_iter_current; 1.74 + iter.base.next = cx_ll_iter_next; 1.75 + iter.base.flag_removal = cx_ll_iter_flag_rm; 1.76 + iter.base.mutating = false; 1.77 + iter.base.remove = false; 1.78 return iter; 1.79 } 1.80 1.81 static CxIterator cx_pll_iterator( 1.82 + struct cx_list_s const *list, 1.83 + size_t index 1.84 +) { 1.85 + CxIterator iter = cx_ll_iterator(list, index); 1.86 + iter.base.current = cx_pll_iter_current; 1.87 + return iter; 1.88 +} 1.89 + 1.90 +static CxMutIterator cx_ll_mut_iterator( 1.91 struct cx_list_s *list, 1.92 size_t index 1.93 ) { 1.94 - CxIterator iter = cx_ll_iterator(list, index); 1.95 - iter.current = cx_pll_iter_current; 1.96 + CxIterator it = cx_ll_iterator(list, index); 1.97 + it.base.mutating = true; 1.98 + 1.99 + // we know the iterators share the same memory layout 1.100 + CxMutIterator iter; 1.101 + memcpy(&iter, &it, sizeof(CxMutIterator)); 1.102 + return iter; 1.103 +} 1.104 + 1.105 +static CxMutIterator cx_pll_mut_iterator( 1.106 + struct cx_list_s *list, 1.107 + size_t index 1.108 +) { 1.109 + CxMutIterator iter = cx_ll_mut_iterator(list, index); 1.110 + iter.base.current = cx_pll_iter_current; 1.111 return iter; 1.112 } 1.113 1.114 static int cx_ll_insert_iter( 1.115 - CxIterator *iter, 1.116 + CxMutIterator *iter, 1.117 void const *elem, 1.118 int prepend 1.119 ) { 1.120 @@ -719,7 +759,7 @@ 1.121 } 1.122 1.123 static int cx_pll_insert_iter( 1.124 - CxIterator *iter, 1.125 + CxMutIterator *iter, 1.126 void const *elem, 1.127 int prepend 1.128 ) { 1.129 @@ -750,7 +790,8 @@ 1.130 cx_ll_sort, 1.131 cx_ll_compare, 1.132 cx_ll_reverse, 1.133 - cx_ll_iterator 1.134 + cx_ll_iterator, 1.135 + cx_ll_mut_iterator, 1.136 }; 1.137 1.138 static cx_list_class cx_pointer_linked_list_class = { 1.139 @@ -766,6 +807,7 @@ 1.140 cx_ll_compare, 1.141 cx_ll_reverse, 1.142 cx_pll_iterator, 1.143 + cx_pll_mut_iterator, 1.144 }; 1.145 1.146 CxList *cxLinkedListCreate(