Thu, 25 Jan 2024 22:01:12 +0100
add cx_array_add() + fix type of cx_array_default_reallocator
CHANGELOG | file | annotate | diff | comparison | revisions | |
src/array_list.c | file | annotate | diff | comparison | revisions | |
src/cx/array_list.h | file | annotate | diff | comparison | revisions | |
tests/test_list.c | file | annotate | diff | comparison | revisions |
1.1 --- a/CHANGELOG Wed Jan 24 22:19:05 2024 +0100 1.2 +++ b/CHANGELOG Thu Jan 25 22:01:12 2024 +0100 1.3 @@ -2,6 +2,7 @@ 1.4 ------------------------ 1.5 * adds tree.h 1.6 * adds cx_array_default_reallocator 1.7 + * adds cx_array_add() 1.8 * adds cx_linked_list_find_node() 1.9 * adds cxListFindRemove() 1.10 * adds cxBufferReset()
2.1 --- a/src/array_list.c Wed Jan 24 22:19:05 2024 +0100 2.2 +++ b/src/array_list.c Thu Jan 25 22:01:12 2024 +0100 2.3 @@ -42,10 +42,12 @@ 2.4 return realloc(array, capacity * elem_size); 2.5 } 2.6 2.7 -struct cx_array_reallocator_s cx_array_default_reallocator = { 2.8 +struct cx_array_reallocator_s cx_array_default_reallocator_impl = { 2.9 cx_array_default_realloc, NULL, NULL, 0, 0 2.10 }; 2.11 2.12 +struct cx_array_reallocator_s *cx_array_default_reallocator = &cx_array_default_reallocator_impl; 2.13 + 2.14 // LOW LEVEL ARRAY LIST FUNCTIONS 2.15 2.16 enum cx_array_copy_result cx_array_copy(
3.1 --- a/src/cx/array_list.h Wed Jan 24 22:19:05 2024 +0100 3.2 +++ b/src/cx/array_list.h Thu Jan 25 22:01:12 2024 +0100 3.3 @@ -96,7 +96,7 @@ 3.4 /** 3.5 * A default stdlib-based array reallocator. 3.6 */ 3.7 -extern struct cx_array_reallocator_s cx_array_default_reallocator; 3.8 +extern struct cx_array_reallocator_s *cx_array_default_reallocator; 3.9 3.10 /** 3.11 * Return codes for cx_array_copy(). 3.12 @@ -117,7 +117,7 @@ 3.13 * capacity is used. 3.14 * 3.15 * If the capacity is insufficient to hold the new data, a reallocation 3.16 - * attempt is made, unless the allocator is set to \c NULL, in which case 3.17 + * attempt is made, unless the \p reallocator is set to \c NULL, in which case 3.18 * this function ultimately returns a failure. 3.19 * 3.20 * @param target the target array 3.21 @@ -143,6 +143,28 @@ 3.22 struct cx_array_reallocator_s *reallocator 3.23 ) __attribute__((__nonnull__(1, 2, 5))); 3.24 3.25 +/** 3.26 + * Adds an element to an array with the possibility of allocating more space. 3.27 + * 3.28 + * The element \p elem is added to the end of the \p target array which containing 3.29 + * \p size elements, already. The \p capacity must not be \c NULL and point a 3.30 + * variable holding the current maximum number of elements the array can hold. 3.31 + * 3.32 + * If the capacity is insufficient to hold the new element, and the optional 3.33 + * \p reallocator is not \c NULL, an attempt increase the \p capacity is made 3.34 + * and the new capacity is written back. 3.35 + * 3.36 + * @param target the target array 3.37 + * @param size a pointer to the size of the target array 3.38 + * @param capacity a pointer to the target array's capacity - must not be \c NULL 3.39 + * @param elem_size the size of one element 3.40 + * @param elem the element to add 3.41 + * @param reallocator the array re-allocator to use, or \c NULL 3.42 + * if re-allocation shall not happen 3.43 + * @return zero on success, non-zero error code on failure 3.44 + */ 3.45 +#define cx_array_add(target, size, capacity, elem_size, elem, reallocator) \ 3.46 + cx_array_copy((void**)(target), size, capacity, *(size), elem, elem_size, 1, reallocator) 3.47 3.48 /** 3.49 * Swaps two array elements.
4.1 --- a/tests/test_list.c Wed Jan 24 22:19:05 2024 +0100 4.2 +++ b/tests/test_list.c Thu Jan 25 22:01:12 2024 +0100 4.3 @@ -36,6 +36,68 @@ 4.4 4.5 #include <stdarg.h> 4.6 4.7 +CX_TEST(test_array_add) { 4.8 + int stackspace[5] = {1,1,2,3,5}; 4.9 + int *stackarray = stackspace; 4.10 + size_t stackarray_size = 3; 4.11 + size_t stackarray_capacity = 5; 4.12 + int *heaparray = calloc(5, sizeof(int)); 4.13 + heaparray[0] = 2; 4.14 + heaparray[1] = 3; 4.15 + heaparray[2] = 5; 4.16 + heaparray[3] = 7; 4.17 + heaparray[4] = 11; 4.18 + size_t heaparray_size = 3; 4.19 + size_t heaparray_capacity = 5; 4.20 + int elem = 8, elem2 = 47; 4.21 + enum cx_array_copy_result result; 4.22 + CX_TEST_DO { 4.23 + result = cx_array_add(&stackarray, &stackarray_size, &stackarray_capacity, sizeof(int), &elem, NULL); 4.24 + CX_TEST_ASSERT(result == CX_ARRAY_COPY_SUCCESS); 4.25 + CX_TEST_ASSERT(stackarray[0] == 1); 4.26 + CX_TEST_ASSERT(stackarray[1] == 1); 4.27 + CX_TEST_ASSERT(stackarray[2] == 2); 4.28 + CX_TEST_ASSERT(stackarray[3] == 8); 4.29 + CX_TEST_ASSERT(stackarray[4] == 5); 4.30 + CX_TEST_ASSERT(stackarray_size == 4); 4.31 + CX_TEST_ASSERT(stackarray_capacity == 5); 4.32 + 4.33 + stackarray_size = 5; 4.34 + result = cx_array_add(&stackarray, &stackarray_size, &stackarray_capacity, sizeof(int), &elem2, NULL); 4.35 + CX_TEST_ASSERT(result == CX_ARRAY_COPY_REALLOC_NOT_SUPPORTED); 4.36 + CX_TEST_ASSERT(stackarray[0] == 1); 4.37 + CX_TEST_ASSERT(stackarray[1] == 1); 4.38 + CX_TEST_ASSERT(stackarray[2] == 2); 4.39 + CX_TEST_ASSERT(stackarray[3] == 8); 4.40 + CX_TEST_ASSERT(stackarray[4] == 5); 4.41 + CX_TEST_ASSERT(stackarray_size == 5); 4.42 + CX_TEST_ASSERT(stackarray_capacity == 5); 4.43 + 4.44 + result = cx_array_add(&heaparray, &heaparray_size, &heaparray_capacity, sizeof(int), &elem, cx_array_default_reallocator); 4.45 + CX_TEST_ASSERT(result == CX_ARRAY_COPY_SUCCESS); 4.46 + CX_TEST_ASSERT(heaparray[0] == 2); 4.47 + CX_TEST_ASSERT(heaparray[1] == 3); 4.48 + CX_TEST_ASSERT(heaparray[2] == 5); 4.49 + CX_TEST_ASSERT(heaparray[3] == 8); 4.50 + CX_TEST_ASSERT(heaparray[4] == 11); 4.51 + CX_TEST_ASSERT(heaparray_size == 4); 4.52 + CX_TEST_ASSERT(heaparray_capacity == 5); 4.53 + 4.54 + heaparray_size = 5; 4.55 + result = cx_array_add(&heaparray, &heaparray_size, &heaparray_capacity, sizeof(int), &elem2, cx_array_default_reallocator); 4.56 + CX_TEST_ASSERT(result == CX_ARRAY_COPY_SUCCESS); 4.57 + CX_TEST_ASSERT(heaparray[0] == 2); 4.58 + CX_TEST_ASSERT(heaparray[1] == 3); 4.59 + CX_TEST_ASSERT(heaparray[2] == 5); 4.60 + CX_TEST_ASSERT(heaparray[3] == 8); 4.61 + CX_TEST_ASSERT(heaparray[4] == 11); 4.62 + CX_TEST_ASSERT(heaparray[5] == 47); 4.63 + CX_TEST_ASSERT(heaparray_size == 6); 4.64 + CX_TEST_ASSERT(heaparray_capacity >= 6); 4.65 + } 4.66 + free(heaparray); 4.67 +} 4.68 + 4.69 typedef struct node { 4.70 struct node *next; 4.71 struct node *prev; 4.72 @@ -1344,6 +1406,8 @@ 4.73 CxTestSuite *cx_test_suite_array_list(void) { 4.74 CxTestSuite *suite = cx_test_suite_new("array_list"); 4.75 4.76 + cx_test_register(suite, test_array_add); 4.77 + 4.78 cx_test_register(suite, test_list_arl_create); 4.79 cx_test_register(suite, test_list_arl_create_simple); 4.80 cx_test_register(suite, test_list_arl_create_simple_for_pointers);