diff -r 435c9965b2dd -r 3dc9075df822 src/linked_list.c --- a/src/linked_list.c Sat Jan 29 12:46:07 2022 +0100 +++ b/src/linked_list.c Sat Jan 29 14:32:04 2022 +0100 @@ -481,16 +481,11 @@ } } -static int cx_ll_insert( +static int cx_ll_insert_at( cx_list_s *list, - size_t index, + cx_linked_list_node *node, void const *elem ) { - // out-of bounds check - if (index > list->size) return 1; - - // cast a linked list pointer - cx_linked_list *ll = (cx_linked_list *) list; // create the new new_node cx_linked_list_node *new_node = cxMalloc(list->allocator, @@ -503,10 +498,8 @@ new_node->prev = new_node->next = NULL; memcpy(new_node->payload, elem, list->itemsize); - // find position efficiently - cx_linked_list_node *node = index == 0 ? NULL : cx_ll_node_at(ll, index - 1); - // insert + cx_linked_list *ll = (cx_linked_list *) list; cx_linked_list_insert_chain( (void **) &ll->begin, (void **) &ll->end, CX_LL_LOC_PREV, CX_LL_LOC_NEXT, @@ -518,6 +511,21 @@ return 0; } +static int cx_ll_insert( + cx_list_s *list, + size_t index, + void const *elem +) { + // out-of bounds check + if (index > list->size) return 1; + + // find position efficiently + cx_linked_list_node *node = index == 0 ? NULL : cx_ll_node_at((cx_linked_list *) list, index - 1); + + // perform insert + return cx_ll_insert_at(list, node, elem); +} + static int cx_ll_add( cx_list_s *list, void const *elem @@ -695,21 +703,51 @@ return iter; } +static int cx_ll_insert_iter( + CxIterator *iter, + void const *elem, + int prepend +) { + cx_list_s *list = iter->src_handle; + cx_linked_list_node *node = iter->elem_handle; + if (node != NULL) { + assert(prepend >= 0 && prepend <= 1); + cx_linked_list_node *choice[2] = {node, node->prev}; + int result = cx_ll_insert_at(list, choice[prepend], elem); + iter->index += prepend * (0 == result); + return result; + } else { + int result = cx_ll_insert(list, list->size, elem); + iter->index = list->size; + return result; + } +} + +static int cx_pll_insert_iter( + CxIterator *iter, + void const *elem, + int prepend +) { + return cx_ll_insert_iter(iter, &elem, prepend); +} + static cx_list_class cx_linked_list_class = { cx_ll_add, cx_ll_insert, + cx_ll_insert_iter, cx_ll_remove, cx_ll_at, cx_ll_find, cx_ll_sort, cx_ll_compare, cx_ll_reverse, - cx_ll_iterator, + cx_ll_iterator }; static cx_list_class cx_pointer_linked_list_class = { cx_pll_add, cx_pll_insert, + cx_pll_insert_iter, cx_ll_remove, cx_pll_at, cx_pll_find,