src/linked_list.c

changeset 764
ccbdbd088455
parent 763
741a2040fa33
child 807
c8d692131b1e
     1.1 --- a/src/linked_list.c	Mon Dec 18 16:14:07 2023 +0100
     1.2 +++ b/src/linked_list.c	Mon Dec 18 18:22:53 2023 +0100
     1.3 @@ -64,6 +64,23 @@
     1.4          cx_compare_func cmp_func,
     1.5          void const *elem
     1.6  ) {
     1.7 +    void *dummy;
     1.8 +    return cx_linked_list_find_node(
     1.9 +            &dummy, start,
    1.10 +            loc_advance, loc_data,
    1.11 +            cmp_func, elem
    1.12 +    );
    1.13 +}
    1.14 +
    1.15 +ssize_t cx_linked_list_find_node(
    1.16 +        void **result,
    1.17 +        void const *start,
    1.18 +        ptrdiff_t loc_advance,
    1.19 +        ptrdiff_t loc_data,
    1.20 +        cx_compare_func cmp_func,
    1.21 +        void const *elem
    1.22 +) {
    1.23 +    assert(result != NULL);
    1.24      assert(start != NULL);
    1.25      assert(loc_advance >= 0);
    1.26      assert(loc_data >= 0);
    1.27 @@ -74,11 +91,13 @@
    1.28      do {
    1.29          void *current = ll_data(node);
    1.30          if (cmp_func(current, elem) == 0) {
    1.31 +            *result = (void*) node;
    1.32              return index;
    1.33          }
    1.34          node = ll_advance(node);
    1.35          index++;
    1.36      } while (node != NULL);
    1.37 +    *result = NULL;
    1.38      return -1;
    1.39  }
    1.40  
    1.41 @@ -736,13 +755,35 @@
    1.42      return node == NULL ? NULL : node->payload;
    1.43  }
    1.44  
    1.45 -static ssize_t cx_ll_find(
    1.46 -        struct cx_list_s const *list,
    1.47 -        void const *elem
    1.48 +static ssize_t cx_ll_find_remove(
    1.49 +        struct cx_list_s *list,
    1.50 +        void const *elem,
    1.51 +        bool remove
    1.52  ) {
    1.53 -    return cx_linked_list_find(((cx_linked_list *) list)->begin,
    1.54 -                               CX_LL_LOC_NEXT, CX_LL_LOC_DATA,
    1.55 -                               list->cmpfunc, elem);
    1.56 +    if (remove) {
    1.57 +        cx_linked_list *ll = ((cx_linked_list *) list);
    1.58 +        cx_linked_list_node *node;
    1.59 +        ssize_t index = cx_linked_list_find_node(
    1.60 +                (void **) &node,
    1.61 +                ll->begin,
    1.62 +                CX_LL_LOC_NEXT, CX_LL_LOC_DATA,
    1.63 +                list->cmpfunc, elem
    1.64 +        );
    1.65 +        if (node != NULL) {
    1.66 +            cx_invoke_destructor(list, node->payload);
    1.67 +            cx_linked_list_remove((void **) &ll->begin, (void **) &ll->end,
    1.68 +                                  CX_LL_LOC_PREV, CX_LL_LOC_NEXT, node);
    1.69 +            list->size--;
    1.70 +            cxFree(list->allocator, node);
    1.71 +        }
    1.72 +        return index;
    1.73 +    } else {
    1.74 +        return cx_linked_list_find(
    1.75 +                ((cx_linked_list *) list)->begin,
    1.76 +                CX_LL_LOC_NEXT, CX_LL_LOC_DATA,
    1.77 +                list->cmpfunc, elem
    1.78 +        );
    1.79 +    }
    1.80  }
    1.81  
    1.82  static void cx_ll_sort(struct cx_list_s *list) {
    1.83 @@ -895,7 +936,7 @@
    1.84          cx_ll_clear,
    1.85          cx_ll_swap,
    1.86          cx_ll_at,
    1.87 -        cx_ll_find,
    1.88 +        cx_ll_find_remove,
    1.89          cx_ll_sort,
    1.90          cx_ll_compare,
    1.91          cx_ll_reverse,

mercurial