#219 array list: implement reverse

Sun, 20 Nov 2022 16:58:51 +0100

author
Mike Becker <universe@uap-core.de>
date
Sun, 20 Nov 2022 16:58:51 +0100
changeset 623
21082350a590
parent 622
3d93cd78aa20
child 624
b0bdff7d8203

#219 array list: implement reverse

src/array_list.c file | annotate | diff | comparison | revisions
src/cx/array_list.h file | annotate | diff | comparison | revisions
test/test_list.cpp file | annotate | diff | comparison | revisions
     1.1 --- a/src/array_list.c	Sun Nov 20 16:28:03 2022 +0100
     1.2 +++ b/src/array_list.c	Sun Nov 20 16:58:51 2022 +0100
     1.3 @@ -101,6 +101,45 @@
     1.4      return CX_ARRAY_COPY_SUCCESS;
     1.5  }
     1.6  
     1.7 +#define CX_ARRAY_SWAP_SBO_SIZE 512
     1.8 +
     1.9 +void cx_array_swap(
    1.10 +        void *arr,
    1.11 +        size_t elem_size,
    1.12 +        size_t idx1,
    1.13 +        size_t idx2
    1.14 +) {
    1.15 +    /* short circuit */
    1.16 +    if (idx1 == idx2) return;
    1.17 +
    1.18 +    char sbo_mem[CX_ARRAY_SWAP_SBO_SIZE];
    1.19 +    void *tmp;
    1.20 +
    1.21 +    /* decide if we can use the local buffer */
    1.22 +    if (elem_size > CX_ARRAY_SWAP_SBO_SIZE) {
    1.23 +        tmp = malloc(elem_size);
    1.24 +        /* we don't want to enforce error handling */
    1.25 +        if (tmp == NULL) abort();
    1.26 +    } else {
    1.27 +        tmp = sbo_mem;
    1.28 +    }
    1.29 +
    1.30 +    /* calculate memory locations */
    1.31 +    char *left = arr, *right = arr;
    1.32 +    left += idx1 * elem_size;
    1.33 +    right += idx2 * elem_size;
    1.34 +
    1.35 +    /* three-way swap */
    1.36 +    memcpy(tmp, left, elem_size);
    1.37 +    memcpy(left, right, elem_size);
    1.38 +    memcpy(right, tmp, elem_size);
    1.39 +
    1.40 +    /* free dynamic memory, if it was needed */
    1.41 +    if (tmp != sbo_mem) {
    1.42 +        free(tmp);
    1.43 +    }
    1.44 +}
    1.45 +
    1.46  /* HIGH LEVEL ARRAY LIST FUNCTIONS */
    1.47  
    1.48  typedef struct {
    1.49 @@ -290,7 +329,12 @@
    1.50  }
    1.51  
    1.52  static void cx_arl_reverse(struct cx_list_s *list) {
    1.53 -
    1.54 +    if (list->size < 2) return;
    1.55 +    void *data = ((cx_array_list const *) list)->data;
    1.56 +    size_t half = list->size / 2;
    1.57 +    for (size_t i = 0; i < half; i++) {
    1.58 +        cx_array_swap(data, list->itemsize, i, list->size - 1 - i);
    1.59 +    }
    1.60  }
    1.61  
    1.62  static bool cx_arl_iter_valid(struct cx_iterator_s const *iter) {
     2.1 --- a/src/cx/array_list.h	Sun Nov 20 16:28:03 2022 +0100
     2.2 +++ b/src/cx/array_list.h	Sun Nov 20 16:58:51 2022 +0100
     2.3 @@ -132,6 +132,22 @@
     2.4          struct cx_array_reallocator_s *reallocator
     2.5  ) __attribute__((__nonnull__(1, 2, 5)));
     2.6  
     2.7 +
     2.8 +/**
     2.9 + * Swaps two array elements.
    2.10 + *
    2.11 + * @param arr the array
    2.12 + * @param elem_size the element size
    2.13 + * @param idx1 index of first element
    2.14 + * @param idx2 index of second element
    2.15 + */
    2.16 +void cx_array_swap(
    2.17 +        void *arr,
    2.18 +        size_t elem_size,
    2.19 +        size_t idx1,
    2.20 +        size_t idx2
    2.21 +) __attribute__((__nonnull__));
    2.22 +
    2.23  /**
    2.24   * Allocates an array list for storing elements with \p item_size bytes each.
    2.25   *
     3.1 --- a/test/test_list.cpp	Sun Nov 20 16:28:03 2022 +0100
     3.2 +++ b/test/test_list.cpp	Sun Nov 20 16:58:51 2022 +0100
     3.3 @@ -933,7 +933,6 @@
     3.4  }
     3.5  
     3.6  TEST_F(ArrayList, cxListReverse) {
     3.7 -    ASSERT_EQ(1,0); // TODO: remove when implemented
     3.8      verifyReverse(arrayListFromTestData());
     3.9  }
    3.10  

mercurial