Tue, 28 Dec 2021 17:24:18 +0100
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);