add cxLinkedListFromArray() and cxListCompare()

Tue, 28 Dec 2021 17:24:18 +0100

author
Mike Becker <universe@uap-core.de>
date
Tue, 28 Dec 2021 17:24:18 +0100
changeset 488
9138acaa494b
parent 487
4bd19279778c
child 489
af6be1e123aa

add cxLinkedListFromArray() and cxListCompare()

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.c file | annotate | diff | comparison | revisions
     1.1 --- a/src/cx/linked_list.h	Tue Dec 28 14:25:05 2021 +0100
     1.2 +++ b/src/cx/linked_list.h	Tue Dec 28 17:24:18 2021 +0100
     1.3 @@ -59,7 +59,7 @@
     1.4          CxAllocator allocator,
     1.5          CxListComparator comparator,
     1.6          size_t item_size
     1.7 -);
     1.8 +) __attribute__((__nonnull__));
     1.9  
    1.10  /**
    1.11   * Allocates a linked list for storing pointers.
    1.12 @@ -73,7 +73,25 @@
    1.13  CxList cxPointerLinkedListCreate(
    1.14          CxAllocator allocator,
    1.15          CxListComparator comparator
    1.16 -);
    1.17 +) __attribute__((__nonnull__));
    1.18 +
    1.19 +/**
    1.20 + * Creates a linked list using the data from an array.
    1.21 + *
    1.22 + * @param allocator the allocator for allocating the list nodes
    1.23 + * @param comparator the comparator for the elements
    1.24 + * @param item_size the size of one item in the array
    1.25 + * @param num_items the number of items
    1.26 + * @param array the array data
    1.27 + * @return the created list
    1.28 + */
    1.29 +CxList cxLinkedListFromArray(
    1.30 +        CxAllocator allocator,
    1.31 +        CxListComparator comparator,
    1.32 +        size_t item_size,
    1.33 +        size_t num_items,
    1.34 +        const void *array
    1.35 +) __attribute__((__nonnull__));
    1.36  
    1.37  /**
    1.38   * Deallocates the memory of the entire list.
    1.39 @@ -82,7 +100,7 @@
    1.40   *
    1.41   * @param list the list
    1.42   */
    1.43 -void cxLinkedListDestroy(CxList list);
    1.44 +void cxLinkedListDestroy(CxList list) __attribute__((__nonnull__));
    1.45  
    1.46  /**
    1.47   * Finds the node at a certain index.
    1.48 @@ -386,6 +404,8 @@
    1.49  /**
    1.50   * Compares two lists element wise.
    1.51   *
    1.52 + * \note Both list must have the same structure.
    1.53 + *
    1.54   * @param begin_left the begin of the left list (\c NULL denotes an empty list)
    1.55   * @param begin_right the begin of the right list  (\c NULL denotes an empty list)
    1.56   * @param loc_advance the location of the pointer to advance
     2.1 --- a/src/cx/list.h	Tue Dec 28 14:25:05 2021 +0100
     2.2 +++ b/src/cx/list.h	Tue Dec 28 17:24:18 2021 +0100
     2.3 @@ -81,12 +81,23 @@
     2.4      /**
     2.5       * Member function for finding an element.
     2.6       */
     2.7 -    size_t (*find)(cx_list_s *list, void *elem);
     2.8 +    size_t (*find)(
     2.9 +            cx_list_s *list,
    2.10 +            void *elem
    2.11 +    );
    2.12  
    2.13      /**
    2.14       * Member function for sorting the list in place.
    2.15       */
    2.16      void (*sort)(cx_list_s *list);
    2.17 +
    2.18 +    /**
    2.19 +     * Member function for comparing this list to another list of the same type.
    2.20 +     */
    2.21 +    int (*compare)(
    2.22 +            cx_list_s *list,
    2.23 +            cx_list_s *other
    2.24 +    );
    2.25  } cx_list_class;
    2.26  
    2.27  /**
    2.28 @@ -205,6 +216,22 @@
    2.29      list->cl->sort(list);
    2.30  }
    2.31  
    2.32 +/**
    2.33 + * Compares a list to another list of the same type.
    2.34 + *
    2.35 + * First, the list sizes are compared. If they match, the lists are compared element-wise.
    2.36 + *
    2.37 + * @param list the list
    2.38 + * @param other the list to compare to
    2.39 + * @return zero, if both lists are equal element wise, negative if the first list is smaller, zero if the first list is larger
    2.40 + */
    2.41 +static inline int cxListCompare(
    2.42 +        CxList list,
    2.43 +        CxList other
    2.44 +) {
    2.45 +    return list->cl->compare(list, other);
    2.46 +}
    2.47 +
    2.48  #ifdef __cplusplus
    2.49  } /* extern "C" */
    2.50  #endif
     3.1 --- a/src/linked_list.c	Tue Dec 28 14:25:05 2021 +0100
     3.2 +++ b/src/linked_list.c	Tue Dec 28 17:24:18 2021 +0100
     3.3 @@ -613,13 +613,36 @@
     3.4                          true, list->cmpfunc);
     3.5  }
     3.6  
     3.7 +static int cx_ll_compare(
     3.8 +        cx_list_s *list,
     3.9 +        cx_list_s *other
    3.10 +) {
    3.11 +    cx_linked_list *left = (cx_linked_list *) list;
    3.12 +    cx_linked_list *right = (cx_linked_list *) other;
    3.13 +    return cx_linked_list_compare(left->begin, right->begin,
    3.14 +                                  CX_LL_LOC_NEXT, CX_LL_LOC_DATA,
    3.15 +                                  false, list->cmpfunc);
    3.16 +}
    3.17 +
    3.18 +static int cx_pll_compare(
    3.19 +        cx_list_s *list,
    3.20 +        cx_list_s *other
    3.21 +) {
    3.22 +    cx_linked_list *left = (cx_linked_list *) list;
    3.23 +    cx_linked_list *right = (cx_linked_list *) other;
    3.24 +    return cx_linked_list_compare(left->begin, right->begin,
    3.25 +                                  CX_LL_LOC_NEXT, CX_LL_LOC_DATA,
    3.26 +                                  true, list->cmpfunc);
    3.27 +}
    3.28 +
    3.29  static cx_list_class cx_linked_list_class = {
    3.30          cx_ll_add,
    3.31          cx_ll_insert,
    3.32          cx_ll_remove,
    3.33          cx_ll_at,
    3.34          cx_ll_find,
    3.35 -        cx_ll_sort
    3.36 +        cx_ll_sort,
    3.37 +        cx_ll_compare
    3.38  };
    3.39  
    3.40  static cx_list_class cx_pointer_linked_list_class = {
    3.41 @@ -628,7 +651,8 @@
    3.42          cx_ll_remove,
    3.43          cx_pll_at,
    3.44          cx_pll_find,
    3.45 -        cx_pll_sort
    3.46 +        cx_pll_sort,
    3.47 +        cx_pll_compare
    3.48  };
    3.49  
    3.50  CxList cxLinkedListCreate(
    3.51 @@ -674,6 +698,24 @@
    3.52      return (CxList) list;
    3.53  }
    3.54  
    3.55 +CxList cxLinkedListFromArray(
    3.56 +        CxAllocator allocator,
    3.57 +        CxListComparator comparator,
    3.58 +        size_t item_size,
    3.59 +        size_t num_items,
    3.60 +        const void *array
    3.61 +) {
    3.62 +    CxList list = cxLinkedListCreate(allocator, comparator, item_size);
    3.63 +    if (list == NULL) return NULL;
    3.64 +    for (size_t i = 0; i < num_items; i++) {
    3.65 +        if (0 != cxListAdd(list, ((const unsigned char *) array) + i * item_size)) {
    3.66 +            cxLinkedListDestroy(list);
    3.67 +            return NULL;
    3.68 +        }
    3.69 +    }
    3.70 +    return list;
    3.71 +}
    3.72 +
    3.73  void cxLinkedListDestroy(CxList list) {
    3.74      cx_linked_list *ll = (cx_linked_list *) list;
    3.75  
     4.1 --- a/test/test_list.c	Tue Dec 28 14:25:05 2021 +0100
     4.2 +++ b/test/test_list.c	Tue Dec 28 17:24:18 2021 +0100
     4.3 @@ -570,6 +570,19 @@
     4.4      CU_ASSERT_TRUE(cxTestingAllocatorVerify())
     4.5  }
     4.6  
     4.7 +void test_hl_linked_list_from_array(void) {
     4.8 +    cxTestingAllocatorReset();
     4.9 +
    4.10 +    int data[] = {2, 4, 5, 7, 10, 15};
    4.11 +
    4.12 +    CxList expected = cxLinkedListCreate(cxTestingAllocator, (CxListComparator) cmp_int, sizeof(int));
    4.13 +    for (int i = 0; i < 5; i++) cxListAdd(expected, &data[i]);
    4.14 +
    4.15 +    CxList list = cxLinkedListFromArray(cxTestingAllocator, (CxListComparator) cmp_int, sizeof(int), 5, data);
    4.16 +
    4.17 +    CU_ASSERT_TRUE(0 == cxListCompare(list, expected))
    4.18 +}
    4.19 +
    4.20  void test_hl_linked_list_add(void) {
    4.21      cxTestingAllocatorReset();
    4.22  
    4.23 @@ -994,6 +1007,7 @@
    4.24      suite = CU_add_suite("high level linked list", NULL, NULL);
    4.25  
    4.26      cu_add_test(suite, test_hl_linked_list_create);
    4.27 +    cu_add_test(suite, test_hl_linked_list_from_array);
    4.28      cu_add_test(suite, test_hl_linked_list_add);
    4.29      cu_add_test(suite, test_hl_linked_list_insert);
    4.30      cu_add_test(suite, test_hl_linked_list_remove);

mercurial