#224 add cxListAddArray()

Wed, 23 Nov 2022 22:40:55 +0100

author
Mike Becker <universe@uap-core.de>
date
Wed, 23 Nov 2022 22:40:55 +0100
changeset 629
6c81ee4f11ad
parent 628
1e2be40f0cb5
child 630
ac5e7f789048

#224 add cxListAddArray()

This also replaces cxLinkedListFromArray().

src/array_list.c file | annotate | diff | comparison | revisions
src/cx/linked_list.h file | annotate | diff | comparison | revisions
src/cx/list.h file | annotate | diff | comparison | revisions
src/linked_list.c file | annotate | diff | comparison | revisions
test/test_list.cpp file | annotate | diff | comparison | revisions
     1.1 --- a/src/array_list.c	Sun Nov 20 21:08:36 2022 +0100
     1.2 +++ b/src/array_list.c	Wed Nov 23 22:40:55 2022 +0100
     1.3 @@ -185,6 +185,29 @@
     1.4      );
     1.5  }
     1.6  
     1.7 +static size_t cx_arl_add_array(
     1.8 +        struct cx_list_s *list,
     1.9 +        void const *array,
    1.10 +        size_t n
    1.11 +) {
    1.12 +    cx_array_list *arl = (cx_array_list *) list;
    1.13 +    if (CX_ARRAY_COPY_SUCCESS == cx_array_copy(
    1.14 +            &arl->data,
    1.15 +            &list->size,
    1.16 +            &list->capacity,
    1.17 +            list->size,
    1.18 +            array,
    1.19 +            list->itemsize,
    1.20 +            n,
    1.21 +            &arl->reallocator
    1.22 +    )) {
    1.23 +        return n;
    1.24 +    } else {
    1.25 +        // array list implementation is "all or nothing"
    1.26 +        return 0;
    1.27 +    }
    1.28 +}
    1.29 +
    1.30  static int cx_arl_insert(
    1.31          struct cx_list_s *list,
    1.32          size_t index,
    1.33 @@ -385,6 +408,7 @@
    1.34  static cx_list_class cx_array_list_class = {
    1.35          cx_arl_destructor,
    1.36          cx_arl_add,
    1.37 +        cx_arl_add_array,
    1.38          cx_arl_insert,
    1.39          cx_arl_insert_iter,
    1.40          cx_arl_remove,
     2.1 --- a/src/cx/linked_list.h	Sun Nov 20 21:08:36 2022 +0100
     2.2 +++ b/src/cx/linked_list.h	Wed Nov 23 22:40:55 2022 +0100
     2.3 @@ -80,27 +80,6 @@
     2.4  ) __attribute__((__nonnull__));
     2.5  
     2.6  /**
     2.7 - * Creates a linked list using the data from an array.
     2.8 - *
     2.9 - * @remark Elements added to the list are copied, therefore a possible destructor
    2.10 - * MUST NOT free the memory pointed to by its argument.
    2.11 - *
    2.12 - * @param allocator the allocator for allocating the list nodes
    2.13 - * @param comparator the comparator for the elements
    2.14 - * @param item_size the size of one item in the array
    2.15 - * @param num_items the number of items
    2.16 - * @param array the array data
    2.17 - * @return the created list
    2.18 - */
    2.19 -CxList *cxLinkedListFromArray(
    2.20 -        CxAllocator const *allocator,
    2.21 -        CxListComparator comparator,
    2.22 -        size_t item_size,
    2.23 -        size_t num_items,
    2.24 -        void const *array
    2.25 -) __attribute__((__nonnull__));
    2.26 -
    2.27 -/**
    2.28   * Finds the node at a certain index.
    2.29   *
    2.30   * This function can be used to start at an arbitrary position within the list.
     3.1 --- a/src/cx/list.h	Sun Nov 20 21:08:36 2022 +0100
     3.2 +++ b/src/cx/list.h	Wed Nov 23 22:40:55 2022 +0100
     3.3 @@ -130,6 +130,15 @@
     3.4      );
     3.5  
     3.6      /**
     3.7 +     * Member function for adding multiple elements.
     3.8 +     */
     3.9 +    size_t (*add_array)(
    3.10 +            struct cx_list_s *list,
    3.11 +            void const *array,
    3.12 +            size_t n
    3.13 +    );
    3.14 +
    3.15 +    /**
    3.16       * Member function for inserting an element.
    3.17       */
    3.18      int (*insert)(
    3.19 @@ -209,6 +218,7 @@
    3.20   * @param list the list
    3.21   * @param elem a pointer to the element to add
    3.22   * @return zero on success, non-zero on memory allocation failure
    3.23 + * @see cxListAddArray()
    3.24   */
    3.25  __attribute__((__nonnull__))
    3.26  static inline int cxListAdd(
    3.27 @@ -219,6 +229,28 @@
    3.28  }
    3.29  
    3.30  /**
    3.31 + * Adds multiple items to the end of the list.
    3.32 + *
    3.33 + * This method is more efficient than invoking cxListAdd() multiple times.
    3.34 + *
    3.35 + * If there is not enough memory to add all elements, the returned value is
    3.36 + * less than \p n.
    3.37 + *
    3.38 + * @param list the list
    3.39 + * @param array a pointer to the elements to add
    3.40 + * @param n the number of elements to add
    3.41 + * @return the number of added elements
    3.42 + */
    3.43 +__attribute__((__nonnull__))
    3.44 +static inline size_t cxListAddArray(
    3.45 +        CxList *list,
    3.46 +        void const *array,
    3.47 +        size_t n
    3.48 +) {
    3.49 +    return list->cl->add_array(list, array, n);
    3.50 +}
    3.51 +
    3.52 +/**
    3.53   * Inserts an item at the specified index.
    3.54   *
    3.55   * If \p index equals the list \c size, this is effectively cxListAdd().
     4.1 --- a/src/linked_list.c	Sun Nov 20 21:08:36 2022 +0100
     4.2 +++ b/src/linked_list.c	Wed Nov 23 22:40:55 2022 +0100
     4.3 @@ -540,6 +540,20 @@
     4.4      return cx_ll_insert(list, list->size, elem);
     4.5  }
     4.6  
     4.7 +static size_t cx_ll_add_array(
     4.8 +        struct cx_list_s *list,
     4.9 +        void const *array,
    4.10 +        size_t n
    4.11 +) {
    4.12 +    // TODO: redirect to cx_ll_insert_array
    4.13 +    cx_for_n (i, n) {
    4.14 +        if (cx_ll_add(list, ((char const *) array) + i * list->itemsize)) {
    4.15 +            return i;
    4.16 +        }
    4.17 +    }
    4.18 +    return n;
    4.19 +}
    4.20 +
    4.21  static int cx_pll_insert(
    4.22          struct cx_list_s *list,
    4.23          size_t index,
    4.24 @@ -727,6 +741,7 @@
    4.25  static cx_list_class cx_linked_list_class = {
    4.26          cx_ll_destructor,
    4.27          cx_ll_add,
    4.28 +        cx_ll_add_array,
    4.29          cx_ll_insert,
    4.30          cx_ll_insert_iter,
    4.31          cx_ll_remove,
    4.32 @@ -741,6 +756,7 @@
    4.33  static cx_list_class cx_pointer_linked_list_class = {
    4.34          cx_ll_destructor,
    4.35          cx_pll_add,
    4.36 +        cx_ll_add_array,
    4.37          cx_pll_insert,
    4.38          cx_pll_insert_iter,
    4.39          cx_ll_remove,
    4.40 @@ -786,22 +802,3 @@
    4.41  
    4.42      return (CxList *) list;
    4.43  }
    4.44 -
    4.45 -CxList *cxLinkedListFromArray(
    4.46 -        CxAllocator const *allocator,
    4.47 -        CxListComparator comparator,
    4.48 -        size_t item_size,
    4.49 -        size_t num_items,
    4.50 -        void const *array
    4.51 -) {
    4.52 -    CxList *list = cxLinkedListCreate(allocator, comparator, item_size);
    4.53 -    if (list == NULL) return NULL;
    4.54 -    cx_for_n (i, num_items) {
    4.55 -        if (0 != cxListAdd(list, ((const unsigned char *) array) + i * item_size)) {
    4.56 -            cx_ll_destructor(list);
    4.57 -            cxFree(allocator, list);
    4.58 -            return NULL;
    4.59 -        }
    4.60 -    }
    4.61 -    return list;
    4.62 -}
     5.1 --- a/test/test_list.cpp	Sun Nov 20 21:08:36 2022 +0100
     5.2 +++ b/test/test_list.cpp	Wed Nov 23 22:40:55 2022 +0100
     5.3 @@ -569,28 +569,21 @@
     5.4      }
     5.5  
     5.6      auto linkedListFromTestData() const -> CxList * {
     5.7 -        // TODO: replace with cxListAddArray
     5.8 -        return autofree(
     5.9 -                cxLinkedListFromArray(
    5.10 -                        &testingAllocator,
    5.11 -                        cx_cmp_int,
    5.12 -                        sizeof(int),
    5.13 -                        testdata_len,
    5.14 -                        testdata.data.data()
    5.15 -                )
    5.16 -        );
    5.17 +        auto list = autofree(cxLinkedListCreate(&testingAllocator, cx_cmp_int, sizeof(int)));
    5.18 +        cxListAddArray(list, testdata.data.data(), testdata_len);
    5.19 +        return list;
    5.20      }
    5.21  
    5.22      auto pointerLinkedListFromTestData() const -> CxList * {
    5.23          auto list = autofree(cxPointerLinkedListCreate(&testingAllocator, cx_cmp_int));
    5.24 +        // note: cannot use cxListAddArray() because we don't have a list of pointers
    5.25          cx_for_n(i, testdata_len) cxListAdd(list, &testdata.data[i]);
    5.26          return list;
    5.27      }
    5.28  
    5.29      auto arrayListFromTestData() const -> CxList * {
    5.30          auto list = autofree(cxArrayListCreate(&testingAllocator, cx_cmp_int, sizeof(int), testdata_len));
    5.31 -        // TODO: replace with cxListAddArray
    5.32 -        cx_for_n(i, testdata_len) cxListAdd(list, &testdata.data[i]);
    5.33 +        cxListAddArray(list, testdata.data.data(), testdata_len);
    5.34          return list;
    5.35      }
    5.36  
    5.37 @@ -796,18 +789,6 @@
    5.38      verifyCreate(list);
    5.39  }
    5.40  
    5.41 -TEST_F(LinkedList, cxLinkedListFromArray) {
    5.42 -    CxList *expected = autofree(cxLinkedListCreate(&testingAllocator, cx_cmp_int, sizeof(int)));
    5.43 -    cx_for_n (i, testdata_len) cxListAdd(expected, &testdata.data[i]);
    5.44 -    CxList *list = autofree(cxLinkedListFromArray(&testingAllocator, cx_cmp_int, sizeof(int),
    5.45 -                                                  testdata_len, testdata.data.data()));
    5.46 -    ASSERT_NE(list, nullptr);
    5.47 -    EXPECT_EQ(list->itemsize, sizeof(int));
    5.48 -    EXPECT_EQ(list->capacity, (size_t) -1);
    5.49 -    EXPECT_EQ(list->size, testdata_len);
    5.50 -    EXPECT_EQ(cxListCompare(list, expected), 0);
    5.51 -}
    5.52 -
    5.53  TEST_F(ArrayList, cxArrayListCreate) {
    5.54      CxList *list = autofree(cxArrayListCreate(&testingAllocator, cx_cmp_int, sizeof(int), 8));
    5.55      ASSERT_NE(list, nullptr);
    5.56 @@ -905,13 +886,15 @@
    5.57  
    5.58  TEST_F(LinkedList, InsertViaIterator) {
    5.59      int fivenums[] = {0, 1, 2, 3, 4, 5};
    5.60 -    CxList *list = autofree(cxLinkedListFromArray(&testingAllocator, cx_cmp_int, sizeof(int), 5, fivenums));
    5.61 +    CxList *list = autofree(cxLinkedListCreate(&testingAllocator, cx_cmp_int, sizeof(int)));
    5.62 +    cxListAddArray(list, fivenums, 5);
    5.63      verifyInsertViaIterator(list);
    5.64  }
    5.65  
    5.66  TEST_F(PointerLinkedList, InsertViaIterator) {
    5.67      int fivenums[] = {0, 1, 2, 3, 4, 5};
    5.68      CxList *list = autofree(cxPointerLinkedListCreate(&testingAllocator, cx_cmp_int));
    5.69 +    // note: don't use cxListAddArray() here, because we don't have a list of pointers
    5.70      cx_for_n (i, 5) cxListAdd(list, &fivenums[i]);
    5.71      verifyInsertViaIterator(list);
    5.72  }
    5.73 @@ -919,8 +902,7 @@
    5.74  TEST_F(ArrayList, InsertViaIterator) {
    5.75      int fivenums[] = {0, 1, 2, 3, 4, 5};
    5.76      CxList *list = autofree(cxArrayListCreate(&testingAllocator, cx_cmp_int, sizeof(int), 4));
    5.77 -    // TODO: replace with cxListAddArray
    5.78 -    cx_for_n (i, 5) cxListAdd(list, &fivenums[i]);
    5.79 +    cxListAddArray(list, fivenums, 5);
    5.80      verifyInsertViaIterator(list);
    5.81  }
    5.82  

mercurial