src/linked_list.c

changeset 638
eafb45eefc51
parent 630
ac5e7f789048
child 639
309e8b08c60e
     1.1 --- a/src/linked_list.c	Mon Jan 23 20:00:26 2023 +0100
     1.2 +++ b/src/linked_list.c	Mon Jan 23 20:22:11 2023 +0100
     1.3 @@ -518,19 +518,47 @@
     1.4      return 0;
     1.5  }
     1.6  
     1.7 +static size_t cx_ll_insert_array(
     1.8 +        struct cx_list_s *list,
     1.9 +        size_t index,
    1.10 +        void const *array,
    1.11 +        size_t n
    1.12 +) {
    1.13 +    // out-of bounds and corner case check
    1.14 +    if (index > list->size || n == 0) return 0;
    1.15 +
    1.16 +    // find position efficiently
    1.17 +    cx_linked_list_node *node = index == 0 ? NULL : cx_ll_node_at((cx_linked_list *) list, index - 1);
    1.18 +
    1.19 +    // perform first insert
    1.20 +    if (0 != cx_ll_insert_at(list, node, array)) {
    1.21 +        return 1;
    1.22 +    }
    1.23 +
    1.24 +    // is there more?
    1.25 +    if (n == 1) return 1;
    1.26 +
    1.27 +    // we now know exactly where we are
    1.28 +    node = node == NULL ? ((cx_linked_list *) list)->begin : node->next;
    1.29 +
    1.30 +    // we can add the remaining nodes and immedately advance to the inserted node
    1.31 +    char const *source = array;
    1.32 +    for (size_t i = 1; i < n; i++) {
    1.33 +        source += list->itemsize;
    1.34 +        if (0 != cx_ll_insert_at(list, node, source)) {
    1.35 +            return i;
    1.36 +        }
    1.37 +        node = node->next;
    1.38 +    }
    1.39 +    return n;
    1.40 +}
    1.41 +
    1.42  static int cx_ll_insert(
    1.43          struct cx_list_s *list,
    1.44          size_t index,
    1.45          void const *elem
    1.46  ) {
    1.47 -    // out-of bounds check
    1.48 -    if (index > list->size) return 1;
    1.49 -
    1.50 -    // find position efficiently
    1.51 -    cx_linked_list_node *node = index == 0 ? NULL : cx_ll_node_at((cx_linked_list *) list, index - 1);
    1.52 -
    1.53 -    // perform insert
    1.54 -    return cx_ll_insert_at(list, node, elem);
    1.55 +    return cx_ll_insert_array(list, index, elem, 1) != 1;
    1.56  }
    1.57  
    1.58  static int cx_ll_add(
    1.59 @@ -545,13 +573,7 @@
    1.60          void const *array,
    1.61          size_t n
    1.62  ) {
    1.63 -    // TODO: redirect to cx_ll_insert_array
    1.64 -    cx_for_n (i, n) {
    1.65 -        if (cx_ll_add(list, ((char const *) array) + i * list->itemsize)) {
    1.66 -            return i;
    1.67 -        }
    1.68 -    }
    1.69 -    return n;
    1.70 +    return cx_ll_insert_array(list, list->size, array, n);
    1.71  }
    1.72  
    1.73  static int cx_pll_insert(
    1.74 @@ -783,6 +805,7 @@
    1.75          cx_ll_add,
    1.76          cx_ll_add_array,
    1.77          cx_ll_insert,
    1.78 +        cx_ll_insert_array,
    1.79          cx_ll_insert_iter,
    1.80          cx_ll_remove,
    1.81          cx_ll_at,
    1.82 @@ -799,6 +822,7 @@
    1.83          cx_pll_add,
    1.84          cx_ll_add_array,
    1.85          cx_pll_insert,
    1.86 +        cx_ll_insert_array,
    1.87          cx_pll_insert_iter,
    1.88          cx_ll_remove,
    1.89          cx_pll_at,

mercurial