add cx_array_add() + fix type of cx_array_default_reallocator

Thu, 25 Jan 2024 22:01:12 +0100

author
Mike Becker <universe@uap-core.de>
date
Thu, 25 Jan 2024 22:01:12 +0100
changeset 818
2be8fe3d5a2d
parent 817
949908c97474
child 819
5da2ead43077

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);

mercurial