src/array_list.c

changeset 638
eafb45eefc51
parent 630
ac5e7f789048
child 640
55cc3b373c5e
     1.1 --- a/src/array_list.c	Mon Jan 23 20:00:26 2023 +0100
     1.2 +++ b/src/array_list.c	Mon Jan 23 20:22:11 2023 +0100
     1.3 @@ -185,17 +185,50 @@
     1.4      );
     1.5  }
     1.6  
     1.7 -static size_t cx_arl_add_array(
     1.8 +static size_t cx_arl_insert_array(
     1.9          struct cx_list_s *list,
    1.10 +        size_t index,
    1.11          void const *array,
    1.12          size_t n
    1.13  ) {
    1.14 +    // out of bounds and special case check
    1.15 +    if (index > list->size || n == 0) return 0;
    1.16 +
    1.17 +    // get a correctly typed pointer to the list
    1.18      cx_array_list *arl = (cx_array_list *) list;
    1.19 +
    1.20 +    // do we need to move some elements?
    1.21 +    if (index < list->size) {
    1.22 +        char const *first_to_move = (char const *) arl->data;
    1.23 +        first_to_move += index * list->itemsize;
    1.24 +        size_t elems_to_move = list->size - index;
    1.25 +        size_t start_of_moved = index + n;
    1.26 +
    1.27 +        if (CX_ARRAY_COPY_SUCCESS != cx_array_copy(
    1.28 +                &arl->data,
    1.29 +                &list->size,
    1.30 +                &list->capacity,
    1.31 +                start_of_moved,
    1.32 +                first_to_move,
    1.33 +                list->itemsize,
    1.34 +                elems_to_move,
    1.35 +                &arl->reallocator
    1.36 +        )) {
    1.37 +            // if moving existing elems is unsuccessful, abort
    1.38 +            return 0;
    1.39 +        }
    1.40 +    }
    1.41 +
    1.42 +    // note that if we had to move the elements, the following operation
    1.43 +    // is guaranteed to succeed, because we have the memory already allocated
    1.44 +    // therefore, it is impossible to leave this function with an invalid array
    1.45 +
    1.46 +    // place the new elements
    1.47      if (CX_ARRAY_COPY_SUCCESS == cx_array_copy(
    1.48              &arl->data,
    1.49              &list->size,
    1.50              &list->capacity,
    1.51 -            list->size,
    1.52 +            index,
    1.53              array,
    1.54              list->itemsize,
    1.55              n,
    1.56 @@ -208,6 +241,14 @@
    1.57      }
    1.58  }
    1.59  
    1.60 +static size_t cx_arl_add_array(
    1.61 +        struct cx_list_s *list,
    1.62 +        void const *array,
    1.63 +        size_t n
    1.64 +) {
    1.65 +    return cx_arl_insert_array(list, list->size, array, n);
    1.66 +}
    1.67 +
    1.68  static int cx_arl_insert(
    1.69          struct cx_list_s *list,
    1.70          size_t index,
    1.71 @@ -440,6 +481,7 @@
    1.72          cx_arl_add,
    1.73          cx_arl_add_array,
    1.74          cx_arl_insert,
    1.75 +        cx_arl_insert_array,
    1.76          cx_arl_insert_iter,
    1.77          cx_arl_remove,
    1.78          cx_arl_at,

mercurial