diff -r 6c81ee4f11ad -r ac5e7f789048 src/linked_list.c --- a/src/linked_list.c Wed Nov 23 22:40:55 2022 +0100 +++ b/src/linked_list.c Sat Nov 26 16:58:41 2022 +0100 @@ -643,13 +643,16 @@ left->follow_ptr, right->follow_ptr, list->cmpfunc); } -static bool cx_ll_iter_valid(CxIterator const *iter) { +static bool cx_ll_iter_valid(void const *it) { + struct cx_iterator_s const *iter = it; return iter->elem_handle != NULL; } -static void cx_ll_iter_next(CxIterator *iter) { - if (iter->remove) { - iter->remove = false; +static void cx_ll_iter_next(void *it) { + struct cx_iterator_base_s *itbase = it; + if (itbase->remove) { + itbase->remove = false; + struct cx_mut_iterator_s *iter = it; cx_linked_list *ll = iter->src_handle; cx_linked_list_node *node = iter->elem_handle; iter->elem_handle = node->next; @@ -658,48 +661,85 @@ ll->base.size--; cxFree(ll->base.allocator, node); } else { + struct cx_iterator_s *iter = it; iter->index++; cx_linked_list_node *node = iter->elem_handle; iter->elem_handle = node->next; } } -static void *cx_ll_iter_current(CxIterator const *iter) { +static void *cx_ll_iter_current(void const *it) { + struct cx_iterator_s const *iter = it; cx_linked_list_node *node = iter->elem_handle; return node->payload; } -static void *cx_pll_iter_current(CxIterator const *iter) { +static void *cx_pll_iter_current(void const *it) { + struct cx_iterator_s const *iter = it; cx_linked_list_node *node = iter->elem_handle; return *(void **) node->payload; } +static bool cx_ll_iter_flag_rm(void *it) { + struct cx_iterator_base_s *iter = it; + if (iter->mutating) { + iter->remove = true; + return true; + } else { + return false; + } +} + static CxIterator cx_ll_iterator( - struct cx_list_s *list, + struct cx_list_s const *list, size_t index ) { CxIterator iter; iter.index = index; iter.src_handle = list; iter.elem_handle = cx_ll_node_at((cx_linked_list const *) list, index); - iter.valid = cx_ll_iter_valid; - iter.current = cx_ll_iter_current; - iter.next = cx_ll_iter_next; - iter.remove = false; + iter.base.valid = cx_ll_iter_valid; + iter.base.current = cx_ll_iter_current; + iter.base.next = cx_ll_iter_next; + iter.base.flag_removal = cx_ll_iter_flag_rm; + iter.base.mutating = false; + iter.base.remove = false; return iter; } static CxIterator cx_pll_iterator( + struct cx_list_s const *list, + size_t index +) { + CxIterator iter = cx_ll_iterator(list, index); + iter.base.current = cx_pll_iter_current; + return iter; +} + +static CxMutIterator cx_ll_mut_iterator( struct cx_list_s *list, size_t index ) { - CxIterator iter = cx_ll_iterator(list, index); - iter.current = cx_pll_iter_current; + CxIterator it = cx_ll_iterator(list, index); + it.base.mutating = true; + + // we know the iterators share the same memory layout + CxMutIterator iter; + memcpy(&iter, &it, sizeof(CxMutIterator)); + return iter; +} + +static CxMutIterator cx_pll_mut_iterator( + struct cx_list_s *list, + size_t index +) { + CxMutIterator iter = cx_ll_mut_iterator(list, index); + iter.base.current = cx_pll_iter_current; return iter; } static int cx_ll_insert_iter( - CxIterator *iter, + CxMutIterator *iter, void const *elem, int prepend ) { @@ -719,7 +759,7 @@ } static int cx_pll_insert_iter( - CxIterator *iter, + CxMutIterator *iter, void const *elem, int prepend ) { @@ -750,7 +790,8 @@ cx_ll_sort, cx_ll_compare, cx_ll_reverse, - cx_ll_iterator + cx_ll_iterator, + cx_ll_mut_iterator, }; static cx_list_class cx_pointer_linked_list_class = { @@ -766,6 +807,7 @@ cx_ll_compare, cx_ll_reverse, cx_pll_iterator, + cx_pll_mut_iterator, }; CxList *cxLinkedListCreate(