src/linked_list.c

changeset 499
3dc9075df822
parent 495
2856c74e18ba
child 500
eb9e7bd40a8e
     1.1 --- a/src/linked_list.c	Sat Jan 29 12:46:07 2022 +0100
     1.2 +++ b/src/linked_list.c	Sat Jan 29 14:32:04 2022 +0100
     1.3 @@ -481,16 +481,11 @@
     1.4      }
     1.5  }
     1.6  
     1.7 -static int cx_ll_insert(
     1.8 +static int cx_ll_insert_at(
     1.9          cx_list_s *list,
    1.10 -        size_t index,
    1.11 +        cx_linked_list_node *node,
    1.12          void const *elem
    1.13  ) {
    1.14 -    // out-of bounds check
    1.15 -    if (index > list->size) return 1;
    1.16 -
    1.17 -    // cast a linked list pointer
    1.18 -    cx_linked_list *ll = (cx_linked_list *) list;
    1.19  
    1.20      // create the new new_node
    1.21      cx_linked_list_node *new_node = cxMalloc(list->allocator,
    1.22 @@ -503,10 +498,8 @@
    1.23      new_node->prev = new_node->next = NULL;
    1.24      memcpy(new_node->payload, elem, list->itemsize);
    1.25  
    1.26 -    // find position efficiently
    1.27 -    cx_linked_list_node *node = index == 0 ? NULL : cx_ll_node_at(ll, index - 1);
    1.28 -
    1.29      // insert
    1.30 +    cx_linked_list *ll = (cx_linked_list *) list;
    1.31      cx_linked_list_insert_chain(
    1.32              (void **) &ll->begin, (void **) &ll->end,
    1.33              CX_LL_LOC_PREV, CX_LL_LOC_NEXT,
    1.34 @@ -518,6 +511,21 @@
    1.35      return 0;
    1.36  }
    1.37  
    1.38 +static int cx_ll_insert(
    1.39 +        cx_list_s *list,
    1.40 +        size_t index,
    1.41 +        void const *elem
    1.42 +) {
    1.43 +    // out-of bounds check
    1.44 +    if (index > list->size) return 1;
    1.45 +
    1.46 +    // find position efficiently
    1.47 +    cx_linked_list_node *node = index == 0 ? NULL : cx_ll_node_at((cx_linked_list *) list, index - 1);
    1.48 +
    1.49 +    // perform insert
    1.50 +    return cx_ll_insert_at(list, node, elem);
    1.51 +}
    1.52 +
    1.53  static int cx_ll_add(
    1.54          cx_list_s *list,
    1.55          void const *elem
    1.56 @@ -695,21 +703,51 @@
    1.57      return iter;
    1.58  }
    1.59  
    1.60 +static int cx_ll_insert_iter(
    1.61 +        CxIterator *iter,
    1.62 +        void const *elem,
    1.63 +        int prepend
    1.64 +) {
    1.65 +    cx_list_s *list = iter->src_handle;
    1.66 +    cx_linked_list_node *node = iter->elem_handle;
    1.67 +    if (node != NULL) {
    1.68 +        assert(prepend >= 0 && prepend <= 1);
    1.69 +        cx_linked_list_node *choice[2] = {node, node->prev};
    1.70 +        int result = cx_ll_insert_at(list, choice[prepend], elem);
    1.71 +        iter->index += prepend * (0 == result);
    1.72 +        return result;
    1.73 +    } else {
    1.74 +        int result = cx_ll_insert(list, list->size, elem);
    1.75 +        iter->index = list->size;
    1.76 +        return result;
    1.77 +    }
    1.78 +}
    1.79 +
    1.80 +static int cx_pll_insert_iter(
    1.81 +        CxIterator *iter,
    1.82 +        void const *elem,
    1.83 +        int prepend
    1.84 +) {
    1.85 +    return cx_ll_insert_iter(iter, &elem, prepend);
    1.86 +}
    1.87 +
    1.88  static cx_list_class cx_linked_list_class = {
    1.89          cx_ll_add,
    1.90          cx_ll_insert,
    1.91 +        cx_ll_insert_iter,
    1.92          cx_ll_remove,
    1.93          cx_ll_at,
    1.94          cx_ll_find,
    1.95          cx_ll_sort,
    1.96          cx_ll_compare,
    1.97          cx_ll_reverse,
    1.98 -        cx_ll_iterator,
    1.99 +        cx_ll_iterator
   1.100  };
   1.101  
   1.102  static cx_list_class cx_pointer_linked_list_class = {
   1.103          cx_pll_add,
   1.104          cx_pll_insert,
   1.105 +        cx_pll_insert_iter,
   1.106          cx_ll_remove,
   1.107          cx_pll_at,
   1.108          cx_pll_find,

mercurial