changes UcxArray from value to pointer semantics feature/array

Thu, 03 Oct 2019 10:55:39 +0200

author
Mike Becker <universe@uap-core.de>
date
Thu, 03 Oct 2019 10:55:39 +0200
branch
feature/array
changeset 356
77efe51c6c9a
parent 355
d315a068235a
child 357
0f5732f0dc00

changes UcxArray from value to pointer semantics

src/array.c file | annotate | diff | comparison | revisions
src/ucx/array.h file | annotate | diff | comparison | revisions
test/array_tests.c file | annotate | diff | comparison | revisions
test/array_tests.h file | annotate | diff | comparison | revisions
test/main.c file | annotate | diff | comparison | revisions
--- a/src/array.c	Tue Sep 24 20:16:00 2019 +0200
+++ b/src/array.c	Thu Oct 03 10:55:39 2019 +0200
@@ -113,61 +113,70 @@
     return 0;
 }
 
-UcxArray ucx_array_new(size_t capacity, size_t elemsize) {
+UcxArray* ucx_array_new(size_t capacity, size_t elemsize) {
     return ucx_array_new_a(capacity, elemsize, ucx_default_allocator());
 }
 
-UcxArray ucx_array_new_a(size_t capacity, size_t elemsize,
+UcxArray* ucx_array_new_a(size_t capacity, size_t elemsize,
         UcxAllocator* allocator) {
-    UcxArray array;
-    
-    array.allocator = allocator;
-    array.elemsize = elemsize;
-    array.size = 0;
-    array.data = alcalloc(allocator, capacity, elemsize);
-    
-    if (array.data) {
-        array.capacity = capacity;
-    } else {
-        array.capacity = 0;
+    UcxArray* array = almalloc(allocator, sizeof(UcxArray));
+    if(array) {
+        ucx_array_init_a(array, capacity, elemsize, allocator);
     }
-    
     return array;
 }
 
-UcxArray ucx_array_clone(UcxArray array) {
-    UcxArray clone;
+void ucx_array_init(UcxArray* array, size_t capacity, size_t elemsize) {
+    ucx_array_init_a(array, capacity, elemsize, ucx_default_allocator());
+}
+
+void ucx_array_init_a(UcxArray* array, size_t capacity, size_t elemsize,
+        UcxAllocator* allocator) {
     
-    clone.allocator = array.allocator;
-    clone.elemsize = array.elemsize;
-    clone.size = array.size;
-    clone.data = alcalloc(array.allocator, array.capacity, array.elemsize);
+    array->allocator = allocator;
+    array->elemsize = elemsize;
+    array->size = 0;
+    array->data = alcalloc(allocator, capacity, elemsize);
     
-    if (clone.data) {
-        clone.capacity = array.capacity;
-        memcpy(clone.data, array.data, array.size*array.elemsize);
+    if (array->data) {
+        array->capacity = capacity;
     } else {
-        clone.capacity = clone.size = 0;
+        array->capacity = 0;
+    }
+}
+
+int ucx_array_clone(UcxArray* dest, UcxArray const* src) {
+    if (ucx_array_ensurecap(dest, src->capacity)) {
+        return 1;
     }
     
-    return clone;
+    dest->elemsize = src->elemsize;
+    dest->size = src->size;
+    
+    if (dest->data) {
+        memcpy(dest->data, src->data, src->size*src->elemsize);
+    }
+    
+    return 0;
 }
 
-int ucx_array_equals(UcxArray array1, UcxArray array2,
+int ucx_array_equals(UcxArray const *array1, UcxArray const *array2,
         cmp_func cmpfnc, void* data) {
     
-    if (array1.size != array2.size || array1.elemsize != array2.elemsize) {
+    if (array1->size != array2->size || array1->elemsize != array2->elemsize) {
         return 0;
     } else {
-        if (array1.size == 0)
+        if (array1->size == 0)
             return 1;
         
+        size_t elemsize;
         if (cmpfnc == NULL) {
             cmpfnc = ucx_cmp_mem;
-            data = &array1.elemsize;
+            elemsize = array1->elemsize;
+            data = &elemsize;
         }
         
-        for (size_t i = 0 ; i < array1.size ; i++) {
+        for (size_t i = 0 ; i < array1->size ; i++) {
             int r = cmpfnc(
                     ucx_array_at(array1, i),
                     ucx_array_at(array2, i),
@@ -180,16 +189,22 @@
 }
 
 void ucx_array_destroy(UcxArray *array) {
-    alfree(array->allocator, array->data);
+    if(array->data)
+        alfree(array->allocator, array->data);
     array->data = NULL;
     array->capacity = array->size = 0;
 }
 
+void ucx_array_free(UcxArray *array) {
+    ucx_array_destroy(array);
+    alfree(array->allocator, array);
+}
+
 int ucx_array_append_from(UcxArray *array, void *data, size_t count) {
     if (ucx_array_ensurecap(array, array->size + count))
         return 1;
     
-    void* dest = ucx_array_at(*array, array->size);
+    void* dest = ucx_array_at(array, array->size);
     if (data) {
         memcpy(dest, data, array->elemsize*count);
     } else {
@@ -205,7 +220,7 @@
         return 1;
     
     if (array->size > 0) {
-        void *dest = ucx_array_at(*array, count);
+        void *dest = ucx_array_at(array, count);
         memmove(dest, array->data, array->elemsize*array->size);
     }
     
@@ -228,7 +243,7 @@
         array->size = index+count;
     }
     
-    void *dest = ucx_array_at(*array, index);
+    void *dest = ucx_array_at(array, index);
     if (data) {
         memcpy(dest, data, array->elemsize*count);
     } else {
@@ -278,7 +293,7 @@
         }
     }
     
-    void* dest = ucx_array_at(*array1, array1->size);
+    void* dest = ucx_array_at(array1, array1->size);
     memcpy(dest, array2->data, array2->size*array2->elemsize);
     
     array1->size += array2->size;
@@ -286,34 +301,38 @@
     return 0;
 }
 
-void *ucx_array_at(UcxArray array, size_t index) {
-    char* memory = array.data;
-    char* loc = memory + index*array.elemsize;
+void *ucx_array_at(UcxArray const *array, size_t index) {
+    char* memory = array->data;
+    char* loc = memory + index*array->elemsize;
     return loc;
 }
 
-size_t ucx_array_find(UcxArray array, void *elem, cmp_func cmpfnc, void *data) {
+size_t ucx_array_find(UcxArray const *array, void *elem,
+        cmp_func cmpfnc, void *data) {
     
+    size_t elemsize;
     if (cmpfnc == NULL) {
         cmpfnc = ucx_cmp_mem;
-        data = &array.elemsize;
+        elemsize = array->elemsize;
+        data = &elemsize;
     }
 
-    if (array.size > 0) {
-        for (size_t i = 0 ; i < array.size ; i++) {
+    if (array->size > 0) {
+        for (size_t i = 0 ; i < array->size ; i++) {
             void* ptr = ucx_array_at(array, i);
             if (cmpfnc(ptr, elem, data) == 0) {
                 return i;
             }
         }
-        return array.size;
+        return array->size;
     } else {
         return 0;
     }
 }
 
-int ucx_array_contains(UcxArray array, void *elem, cmp_func cmpfnc, void *data) {
-    return ucx_array_find(array, elem, cmpfnc, data) != array.size;
+int ucx_array_contains(UcxArray const *array, void *elem,
+        cmp_func cmpfnc, void *data) {
+    return ucx_array_find(array, elem, cmpfnc, data) != array->size;
 }
 
 static void ucx_mergesort_merge(void *arrdata,size_t elemsize,
@@ -397,15 +416,16 @@
 }
 #endif /* USE_UCX_QSORT_R */
 
-void ucx_array_sort(UcxArray array, cmp_func cmpfnc, void *data) {
-    ucx_array_sort_impl(array.data, array.size, array.elemsize, cmpfnc, data);
+void ucx_array_sort(UcxArray* array, cmp_func cmpfnc, void *data) {
+    ucx_array_sort_impl(array->data, array->size, array->elemsize,
+            cmpfnc, data);
 }
 
 void ucx_array_remove(UcxArray *array, size_t index) {
     array->size--;
     if (index < array->size) {
-        void* dest = ucx_array_at(*array, index);
-        void* src = ucx_array_at(*array, index+1);
+        void* dest = ucx_array_at(array, index);
+        void* src = ucx_array_at(array, index+1);
         memmove(dest, src, (array->size - index)*array->elemsize);
     }
 }
@@ -413,8 +433,8 @@
 void ucx_array_remove_fast(UcxArray *array, size_t index) {
     array->size--;
     if (index < array->size) {       
-        void* dest = ucx_array_at(*array, index);
-        void* src = ucx_array_at(*array, array->size);
+        void* dest = ucx_array_at(array, index);
+        void* src = ucx_array_at(array, array->size);
         memcpy(dest, src, array->elemsize);
     }
 }
--- a/src/ucx/array.h	Tue Sep 24 20:16:00 2019 +0200
+++ b/src/ucx/array.h	Thu Oct 03 10:55:39 2019 +0200
@@ -145,9 +145,9 @@
  * Creates a new UCX array with the given capacity and element size.
  * @param capacity the initial capacity
  * @param elemsize the element size
- * @return a new UCX array structure
+ * @return a pointer to a new UCX array structure
  */
-UcxArray ucx_array_new(size_t capacity, size_t elemsize);
+UcxArray* ucx_array_new(size_t capacity, size_t elemsize);
 
 /**
  * Creates a new UCX array using the specified allocator.
@@ -155,20 +155,44 @@
  * @param capacity the initial capacity
  * @param elemsize the element size
  * @param allocator the allocator to use
- * @return a new UCX array structure
+ * @return a pointer to new UCX array structure
  */
-UcxArray ucx_array_new_a(size_t capacity, size_t elemsize,
+UcxArray* ucx_array_new_a(size_t capacity, size_t elemsize,
+        UcxAllocator* allocator);
+
+/**
+ * Initializes a UCX array structure with the given capacity and element size.
+ * The structure must be uninitialized as the data pointer will be overwritten.
+ * 
+ * @param array the structure to initialize
+ * @param capacity the initial capacity
+ * @param elemsize the element size
+ */
+void ucx_array_init(UcxArray* array, size_t capacity, size_t elemsize);
+
+/**
+ * Initializes a UCX array structure using the specified allocator.
+ * The structure must be uninitialized as the data pointer will be overwritten.
+ * 
+ * @param capacity the initial capacity
+ * @param elemsize the element size
+ * @param allocator the allocator to use
+ */
+void ucx_array_init_a(UcxArray* array, size_t capacity, size_t elemsize,
         UcxAllocator* allocator);
 
 /**
  * Creates an shallow copy of an array.
  * 
  * This function clones the specified array by using memcpy().
+ * If the destination capacity is insufficient, an automatic reallocation is
+ * attempted.
  * 
- * @param array the array to copy
- * @return the copy (may be an empty array on allocation errors)
+ * @param dest the array to copy to
+ * @param src the array to copy from
+ * @return zero on success, non-zero on reallocation failure.
  */
-UcxArray ucx_array_clone(UcxArray array);
+int ucx_array_clone(UcxArray* dest, UcxArray const* src);
 
 
 /**
@@ -187,7 +211,7 @@
  * @param data additional data for the compare function
  * @return 1, if and only if the two arrays equal element-wise, 0 otherwise
  */
-int ucx_array_equals(UcxArray array1, UcxArray array2,
+int ucx_array_equals(UcxArray const *array1, UcxArray const *array2,
         cmp_func cmpfnc, void* data);
 
 /**
@@ -202,6 +226,13 @@
 void ucx_array_destroy(UcxArray *array);
 
 /**
+ * Destroys and frees the array.
+ * 
+ * @param array the array to free
+ */
+void ucx_array_free(UcxArray *array);
+
+/**
  * Inserts elements at the end of the array.
  * 
  * This is an O(1) operation.
@@ -362,7 +393,7 @@
  * @return a pointer to the element at the specified index or <code>NULL</code>,
  * if the index is greater than the array size
  */
-void *ucx_array_at(UcxArray array, size_t index);
+void *ucx_array_at(UcxArray const* array, size_t index);
 
 /**
  * Returns the index of an element containing the specified data.
@@ -381,7 +412,8 @@
  * @return the index of the element containing the specified data or the size of
  * the array, if the data is not found in this array
  */
-size_t ucx_array_find(UcxArray array, void *elem, cmp_func cmpfnc, void *data);
+size_t ucx_array_find(UcxArray const *array, void *elem,
+    cmp_func cmpfnc, void *data);
 
 /**
  * Checks, if an array contains a specific element.
@@ -395,7 +427,8 @@
  * @return 1, if and only if the array contains the specified element data
  * @see ucx_array_find()
  */
-int ucx_array_contains(UcxArray array, void *elem, cmp_func cmpfnc, void *data);
+int ucx_array_contains(UcxArray const *array, void *elem,
+    cmp_func cmpfnc, void *data);
 
 /**
  * Sorts a UcxArray with the best available sort algorithm.
@@ -411,7 +444,7 @@
  * @param cmpfnc the function that shall be used to compare the element data
  * @param data additional data for the cmp_func() or <code>NULL</code>
  */
-void ucx_array_sort(UcxArray array, cmp_func cmpfnc, void *data);
+void ucx_array_sort(UcxArray* array, cmp_func cmpfnc, void *data);
 
 /**
  * Removes an element from the array.
--- a/test/array_tests.c	Tue Sep 24 20:16:00 2019 +0200
+++ b/test/array_tests.c	Thu Oct 03 10:55:39 2019 +0200
@@ -29,58 +29,59 @@
 #include "array_tests.h"
 #include <ucx/utils.h>
 
-UCX_TEST(test_ucx_array_free) {
-    UcxArray array = ucx_array_new(16, sizeof(int));
+UCX_TEST(test_ucx_array_destroy) {
+    UcxArray array;
+    ucx_array_init(&array, 16, sizeof(int));
     
     UCX_TEST_BEGIN
     ucx_array_destroy(&array);
-    UCX_TEST_ASSERT(array.data == NULL, "data pointer not NULL after free");
-    UCX_TEST_ASSERT(array.size == 0, "size not zero after free");
-    UCX_TEST_ASSERT(array.capacity == 0, "capacity not zero after free");
+    UCX_TEST_ASSERT(array.data == NULL, "data pointer not NULL after destroy");
+    UCX_TEST_ASSERT(array.size == 0, "size not zero after destroy");
+    UCX_TEST_ASSERT(array.capacity == 0, "capacity not zero after destroy");
     UCX_TEST_ASSERT(array.allocator == ucx_default_allocator(),
-            "allocator corrupted during free");
+            "allocator corrupted during destroy");
     UCX_TEST_END
 }
 
 UCX_TEST(test_ucx_array_new) {
-    UcxArray array = ucx_array_new(16, 47);
+    UcxArray* array = ucx_array_new(16, 47);
     
     UCX_TEST_BEGIN
-    UCX_TEST_ASSERT(array.data, "no memory allocated");
-    UCX_TEST_ASSERT(array.size == 0, "size not initially zero");
-    UCX_TEST_ASSERT(array.capacity == 16, "capacity not as requested");
-    UCX_TEST_ASSERT(array.elemsize == 47, "element size not as requested");
-    UCX_TEST_ASSERT(array.allocator == ucx_default_allocator(),
+    UCX_TEST_ASSERT(array->data, "no memory allocated");
+    UCX_TEST_ASSERT(array->size == 0, "size not initially zero");
+    UCX_TEST_ASSERT(array->capacity == 16, "capacity not as requested");
+    UCX_TEST_ASSERT(array->elemsize == 47, "element size not as requested");
+    UCX_TEST_ASSERT(array->allocator == ucx_default_allocator(),
             "array not using the default allocator");
     UCX_TEST_END
-    ucx_array_destroy(&array);
+    ucx_array_free(array);
 }
 
 UCX_TEST(test_ucx_array_append_from) {
-    UcxArray array = ucx_array_new(16, sizeof(int));
+    UcxArray *array = ucx_array_new(16, sizeof(int));
     int *elements;
     
     int x = 42;
-    ucx_array_append_from(&array, &x, 1);
+    ucx_array_append_from(array, &x, 1);
     UCX_TEST_BEGIN
     
-    elements = array.data;
+    elements = array->data;
     UCX_TEST_ASSERT(elements[0] == 42, "failed");
     
     int y[2] = {13, 37};
-    ucx_array_append_from(&array, y, 2);
+    ucx_array_append_from(array, y, 2);
     
-    elements = array.data;
-    UCX_TEST_ASSERT(array.size == 3, "incorrect size after append");
+    elements = array->data;
+    UCX_TEST_ASSERT(array->size == 3, "incorrect size after append");
     UCX_TEST_ASSERT(elements[1] == 13, "failed");
     UCX_TEST_ASSERT(elements[2] == 37, "failed");
     UCX_TEST_ASSERT(elements[0] == 42,
             "append corrupted previously inserted data");
     
-    ucx_array_append_from(&array, NULL, 2);
+    ucx_array_append_from(array, NULL, 2);
     
-    elements = array.data;
-    UCX_TEST_ASSERT(array.size == 5, "incorrect size after NULL append");
+    elements = array->data;
+    UCX_TEST_ASSERT(array->size == 5, "incorrect size after NULL append");
     UCX_TEST_ASSERT(elements[3] == 0, "element is not zeroed");
     UCX_TEST_ASSERT(elements[4] == 0, "element is not zeroed");
     UCX_TEST_ASSERT(elements[0] == 42,
@@ -92,34 +93,34 @@
     
     UCX_TEST_END
     
-    ucx_array_destroy(&array);
+    ucx_array_free(array);
 }
 
 UCX_TEST(test_ucx_array_prepend_from) {
     int *elems;
-    UcxArray array = ucx_array_new(16, sizeof(int));
+    UcxArray *array = ucx_array_new(16, sizeof(int));
     
     int x = 42;
-    ucx_array_prepend_from(&array, &x, 1);
+    ucx_array_prepend_from(array, &x, 1);
     UCX_TEST_BEGIN
     
-    elems = array.data;
+    elems = array->data;
     UCX_TEST_ASSERT(elems[0] == 42, "failed");
     
     int y[2] = {13, 37};
-    ucx_array_prepend_from(&array, y, 2);
+    ucx_array_prepend_from(array, y, 2);
     
-    elems = array.data;
-    UCX_TEST_ASSERT(array.size == 3, "incorrect size after prepend");
+    elems = array->data;
+    UCX_TEST_ASSERT(array->size == 3, "incorrect size after prepend");
     UCX_TEST_ASSERT(elems[0] == 13, "failed");
     UCX_TEST_ASSERT(elems[1] == 37, "failed");
     UCX_TEST_ASSERT(elems[2] == 42,
             "prepend corrupted previously inserted data");
     
-    ucx_array_prepend_from(&array, NULL, 2);
+    ucx_array_prepend_from(array, NULL, 2);
     
-    elems = array.data;
-    UCX_TEST_ASSERT(array.size == 5, "incorrect size after NULL prepend");
+    elems = array->data;
+    UCX_TEST_ASSERT(array->size == 5, "incorrect size after NULL prepend");
     UCX_TEST_ASSERT(elems[0] == 0, "element is not zeroed");
     UCX_TEST_ASSERT(elems[1] == 0, "element is not zeroed");
     UCX_TEST_ASSERT(elems[2] == 13,
@@ -131,59 +132,59 @@
     
     UCX_TEST_END
     
-    ucx_array_destroy(&array);
+    ucx_array_free(array);
 }
 
 UCX_TEST(test_ucx_array_set_from) {
     int *elems;
-    UcxArray array = ucx_array_new(16, sizeof(int));
+    UcxArray *array = ucx_array_new(16, sizeof(int));
     
     int x = 42;
 
     UCX_TEST_BEGIN
 
-    ucx_array_set_from(&array, 7, &x, 1);
+    ucx_array_set_from(array, 7, &x, 1);
     
-    elems = array.data;
+    elems = array->data;
     UCX_TEST_ASSERT(elems[7] == 42, "failed");
-    UCX_TEST_ASSERT(array.size >= 8, "array not resized on set");
-    UCX_TEST_ASSERT(array.capacity == 16, "capacity changed unnecessarily");
+    UCX_TEST_ASSERT(array->size >= 8, "array not resized on set");
+    UCX_TEST_ASSERT(array->capacity == 16, "capacity changed unnecessarily");
     
     int y[2] = {13, 37};
-    ucx_array_set_from(&array, 27, y, 2);
+    ucx_array_set_from(array, 27, y, 2);
     
-    elems = array.data;
+    elems = array->data;
     UCX_TEST_ASSERT(elems[27] == 13, "failed");
     UCX_TEST_ASSERT(elems[28] == 37, "failed");
-    UCX_TEST_ASSERT(array.size == 29, "array not resized on set");
-    UCX_TEST_ASSERT(array.capacity == 32, "capacity not grown");
+    UCX_TEST_ASSERT(array->size == 29, "array not resized on set");
+    UCX_TEST_ASSERT(array->capacity == 32, "capacity not grown");
     
-    ucx_array_set_from(&array, 7, NULL, 2);
+    ucx_array_set_from(array, 7, NULL, 2);
     
-    elems = array.data;
+    elems = array->data;
     UCX_TEST_ASSERT(elems[7] == 0, "not zeroed on NULL set");
     UCX_TEST_ASSERT(elems[8] == 0, "not zeroed on NULL set");
     
     UCX_TEST_END
     
-    ucx_array_destroy(&array);
+    ucx_array_free(array);
 }
 
 UCX_TEST(test_ucx_array_append) {
-    UcxArray array = ucx_array_new(16, sizeof(int));
+    UcxArray *array = ucx_array_new(16, sizeof(int));
     int *elements;
     
-    ucx_array_append(&array, 42);
+    ucx_array_append(array, 42);
     UCX_TEST_BEGIN
     
-    elements = array.data;
+    elements = array->data;
     UCX_TEST_ASSERT(elements[0] == 42, "failed");
     
-    ucx_array_append(&array, 13);
-    ucx_array_append(&array, 37);
+    ucx_array_append(array, 13);
+    ucx_array_append(array, 37);
     
-    elements = array.data;
-    UCX_TEST_ASSERT(array.size == 3, "incorrect size after append");
+    elements = array->data;
+    UCX_TEST_ASSERT(array->size == 3, "incorrect size after append");
     UCX_TEST_ASSERT(elements[1] == 13, "failed");
     UCX_TEST_ASSERT(elements[2] == 37, "failed");
     UCX_TEST_ASSERT(elements[0] == 42,
@@ -191,24 +192,24 @@
     
     UCX_TEST_END
     
-    ucx_array_destroy(&array);
+    ucx_array_destroy(array);
 }
 
 UCX_TEST(test_ucx_array_prepend) {
     int *elems;
-    UcxArray array = ucx_array_new(16, sizeof(int));
+    UcxArray *array = ucx_array_new(16, sizeof(int));
     
-    ucx_array_prepend(&array, 42);
+    ucx_array_prepend(array, 42);
     UCX_TEST_BEGIN
     
-    elems = array.data;
+    elems = array->data;
     UCX_TEST_ASSERT(elems[0] == 42, "failed");
     
-    ucx_array_prepend(&array, 37);
-    ucx_array_prepend(&array, 13);
+    ucx_array_prepend(array, 37);
+    ucx_array_prepend(array, 13);
     
-    elems = array.data;
-    UCX_TEST_ASSERT(array.size == 3, "incorrect size after prepend");
+    elems = array->data;
+    UCX_TEST_ASSERT(array->size == 3, "incorrect size after prepend");
     UCX_TEST_ASSERT(elems[0] == 13, "failed");
     UCX_TEST_ASSERT(elems[1] == 37, "failed");
     UCX_TEST_ASSERT(elems[2] == 42,
@@ -216,68 +217,68 @@
     
     UCX_TEST_END
     
-    ucx_array_destroy(&array);
+    ucx_array_free(array);
 }
 
 UCX_TEST(test_ucx_array_set) {
     int *elems;
-    UcxArray array = ucx_array_new(16, sizeof(int));
+    UcxArray *array = ucx_array_new(16, sizeof(int));
 
     UCX_TEST_BEGIN
 
-    ucx_array_set(&array, 7, 42);
+    ucx_array_set(array, 7, 42);
     
-    elems = array.data;
+    elems = array->data;
     UCX_TEST_ASSERT(elems[7] == 42, "failed");
-    UCX_TEST_ASSERT(array.size == 8, "array not resized on set");
-    UCX_TEST_ASSERT(array.capacity == 16, "capacity changed unnecessarily");
+    UCX_TEST_ASSERT(array->size == 8, "array not resized on set");
+    UCX_TEST_ASSERT(array->capacity == 16, "capacity changed unnecessarily");
     
-    ucx_array_set(&array, 27, 13);
-    ucx_array_set(&array, 28, 37);
+    ucx_array_set(array, 27, 13);
+    ucx_array_set(array, 28, 37);
     
-    elems = array.data;
+    elems = array->data;
     UCX_TEST_ASSERT(elems[27] == 13, "failed");
     UCX_TEST_ASSERT(elems[28] == 37, "failed");
-    UCX_TEST_ASSERT(array.size == 29, "array not resized on set");
-    UCX_TEST_ASSERT(array.capacity == 32, "capacity not grown");
+    UCX_TEST_ASSERT(array->size == 29, "array not resized on set");
+    UCX_TEST_ASSERT(array->capacity == 32, "capacity not grown");
         
     UCX_TEST_END
     
-    ucx_array_destroy(&array);
+    ucx_array_free(array);
 }
 
 UCX_TEST(test_ucx_array_equals) {
-    UcxArray a1 = ucx_array_new(16, sizeof(int32_t));
-    UcxArray a2 = ucx_array_new(16, sizeof(int32_t));
-    UcxArray a3 = ucx_array_new(16, sizeof(int64_t));
-    UcxArray a4 = ucx_array_new(16, sizeof(int32_t));
+    UcxArray *a1 = ucx_array_new(16, sizeof(int32_t));
+    UcxArray *a2 = ucx_array_new(16, sizeof(int32_t));
+    UcxArray *a3 = ucx_array_new(16, sizeof(int64_t));
+    UcxArray *a4 = ucx_array_new(16, sizeof(int32_t));
     
     int32_t *intelems;
     int64_t *longintelems;
     
-    a1.size = 5;
-    intelems = a1.data;
+    a1->size = 5;
+    intelems = a1->data;
     intelems[0] = 47;
     intelems[1] = 11;
     intelems[2] = 0;
     intelems[3] = 8;
     intelems[4] = 15;
-    a2.size = 5;
-    intelems = a2.data;
+    a2->size = 5;
+    intelems = a2->data;
     intelems[0] = 47;
     intelems[1] = 11;
     intelems[2] = 0;
     intelems[3] = 8;
     intelems[4] = 15;
-    a3.size = 5;
-    longintelems = a3.data;
+    a3->size = 5;
+    longintelems = a3->data;
     longintelems[0] = 47;
     longintelems[1] = 11;
     longintelems[2] = 0;
     longintelems[3] = 8;
     longintelems[4] = 15;
-    a4.size = 5;
-    intelems = a4.data;
+    a4->size = 5;
+    intelems = a4->data;
     intelems[0] = 47;
     intelems[1] = 11;
     intelems[2] = -6;
@@ -300,54 +301,54 @@
             "compare using memcmp() failed");
     
     UCX_TEST_END
-    ucx_array_destroy(&a1);
-    ucx_array_destroy(&a2);
-    ucx_array_destroy(&a3);
-    ucx_array_destroy(&a4);
+    ucx_array_free(a1);
+    ucx_array_free(a2);
+    ucx_array_free(a3);
+    ucx_array_free(a4);
 }
 
 UCX_TEST(test_ucx_array_concat) {
-    UcxArray a1 = ucx_array_new(16, sizeof(int));
-    UcxArray a2 = ucx_array_new(16, sizeof(int));
+    UcxArray *a1 = ucx_array_new(16, sizeof(int));
+    UcxArray *a2 = ucx_array_new(16, sizeof(int));
     int *elems;
     
-    a1.size = 2;
-    elems = a1.data;
+    a1->size = 2;
+    elems = a1->data;
     elems[0] = 47;
     elems[1] = 11;
-    a2.size = 3;
-    elems = a2.data;
+    a2->size = 3;
+    elems = a2->data;
     elems[0] = 0;
     elems[1] = 8;
     elems[2] = 15;
     
     UCX_TEST_BEGIN
     
-    UCX_TEST_ASSERT(!ucx_array_concat(&a1, &a2), "failed");
-    UCX_TEST_ASSERT(a1.size == 5, "failed");
-    elems = a1.data;
+    UCX_TEST_ASSERT(!ucx_array_concat(a1, a2), "failed");
+    UCX_TEST_ASSERT(a1->size == 5, "failed");
+    elems = a1->data;
     UCX_TEST_ASSERT(elems[0] == 47, "failed");
     UCX_TEST_ASSERT(elems[1] == 11, "failed");
     UCX_TEST_ASSERT(elems[2] == 0, "failed");
     UCX_TEST_ASSERT(elems[3] == 8, "failed");
     UCX_TEST_ASSERT(elems[4] == 15, "failed");
     
-    a1.elemsize *= 2;
-    UCX_TEST_ASSERT(ucx_array_concat(&a1, &a2),
+    a1->elemsize *= 2;
+    UCX_TEST_ASSERT(ucx_array_concat(a1, a2),
             "arrays of different element size must not be concatenated");
-    UCX_TEST_ASSERT(a1.size == 5,
+    UCX_TEST_ASSERT(a1->size == 5,
             "arrays of different element size must not be concatenated");
     
     UCX_TEST_END
-    ucx_array_destroy(&a1);
-    ucx_array_destroy(&a2);    
+    ucx_array_free(a1);
+    ucx_array_free(a2);    
 }
 
 UCX_TEST(test_ucx_array_at) {
-    UcxArray array = ucx_array_new(16, sizeof(int));
+    UcxArray *array = ucx_array_new(16, sizeof(int));
     
     int x[3] = {42, 13, 5};
-    ucx_array_append_from(&array, x, 3);
+    ucx_array_append_from(array, x, 3);
     
     UCX_TEST_BEGIN
     
@@ -360,15 +361,15 @@
     
     UCX_TEST_END
     
-    ucx_array_destroy(&array);
+    ucx_array_free(array);
 }
 
 UCX_TEST(test_ucx_array_find) {
-    UcxArray array = ucx_array_new(16, sizeof(int));
+    UcxArray *array = ucx_array_new(16, sizeof(int));
     int *elems;
     
-    array.size = 5;
-    elems = array.data;
+    array->size = 5;
+    elems = array->data;
     elems[0] = 47;
     elems[1] = 11;
     elems[2] = 0;
@@ -391,15 +392,15 @@
         "failed using memcmp()");
     
     UCX_TEST_END
-    ucx_array_destroy(&array);
+    ucx_array_free(array);
 }
 
 UCX_TEST(test_ucx_array_contains) {
-    UcxArray array = ucx_array_new(16, sizeof(int));
+    UcxArray *array = ucx_array_new(16, sizeof(int));
     int *elems;
     
-    array.size = 5;
-    elems = array.data;
+    array->size = 5;
+    elems = array->data;
     elems[0] = 47;
     elems[1] = 11;
     elems[2] = 0;
@@ -422,15 +423,15 @@
         "false positive using memcmp()");
     
     UCX_TEST_END
-    ucx_array_destroy(&array);
+    ucx_array_free(array);
 }
 
 UCX_TEST(test_ucx_array_remove) {
-    UcxArray array = ucx_array_new(16, sizeof(int));
+    UcxArray *array = ucx_array_new(16, sizeof(int));
     int *elems;
     
-    array.size = 5;
-    elems = array.data;
+    array->size = 5;
+    elems = array->data;
     elems[0] = 47;
     elems[1] = 11;
     elems[2] = 0;
@@ -439,31 +440,33 @@
         
     UCX_TEST_BEGIN
     
-    ucx_array_remove(&array, 2);
-    elems = array.data;
+    ucx_array_remove(array, 2);
+    elems = array->data;
     UCX_TEST_ASSERT(
             elems[0] == 47 &&
             elems[1] == 11 &&
             elems[2] == 8 &&
             elems[3] == 15,
             "wrong contents after remove");
-    UCX_TEST_ASSERT(array.size == 4, "wrong size after remove");
+    UCX_TEST_ASSERT(array->size == 4, "wrong size after remove");
     
-    ucx_array_remove_fast(&array, 1);
-    elems = array.data;
+    ucx_array_remove_fast(array, 1);
+    elems = array->data;
     UCX_TEST_ASSERT(
             elems[0] == 47 &&
             elems[1] == 15 &&
             elems[2] == 8,
             "wrong contents after fast remove");
-    UCX_TEST_ASSERT(array.size == 3, "wrong size after fast remove");
+    UCX_TEST_ASSERT(array->size == 3, "wrong size after fast remove");
     
     UCX_TEST_END
-    ucx_array_destroy(&array);
+    ucx_array_free(array);
 }
 
 UCX_TEST(test_ucx_array_clone) {
-    UcxArray array = ucx_array_new(16, sizeof(int));
+    UcxArray array;
+    UcxArray copy;
+    ucx_array_init(&array, 16, sizeof(int));
     int *elems;
     
     array.size = 5;
@@ -474,7 +477,7 @@
     elems[3] = 8;
     elems[4] = 15;
     
-    UcxArray copy = ucx_array_clone(array);
+    ucx_array_clone(&copy, &array);
     UCX_TEST_BEGIN
 
     UCX_TEST_ASSERT(array.data != copy.data, "no true copy");
@@ -482,7 +485,8 @@
     UCX_TEST_ASSERT(array.capacity == copy.capacity, "capacity mismatch");
     UCX_TEST_ASSERT(array.elemsize == copy.elemsize, "element size mismatch");
     UCX_TEST_ASSERT(array.allocator == copy.allocator, "allocator mismatch");
-    UCX_TEST_ASSERT(ucx_array_equals(array, copy, ucx_cmp_int, NULL), "failed");
+    UCX_TEST_ASSERT(ucx_array_equals(&array, &copy, ucx_cmp_int, NULL),
+            "contents do not match after clone");
     
     UCX_TEST_END
 
@@ -497,27 +501,27 @@
 UCX_TEST(test_ucx_array_sort) {
     int *elems;
 
-    UcxArray array = ucx_array_new(16, sizeof(int));    
-    array.size = 5;
-    elems = array.data;
+    UcxArray *array = ucx_array_new(16, sizeof(int));    
+    array->size = 5;
+    elems = array->data;
     elems[0] = 47;
     elems[1] = 11;
     elems[2] = 0;
     elems[3] = 8;
     elems[4] = 15;
     
-    UcxArray expected = ucx_array_new(16, sizeof(int));
-    expected.size = 5;
-    elems = expected.data;
+    UcxArray *expected = ucx_array_new(16, sizeof(int));
+    expected->size = 5;
+    elems = expected->data;
     elems[0] = 0;
     elems[1] = 8;
     elems[2] = 11;
     elems[3] = 15;
     elems[4] = 47;
     
-    UcxArray expectedrev = ucx_array_new(16, sizeof(int));
-    expectedrev.size = 5;
-    elems = expectedrev.data;
+    UcxArray *expectedrev = ucx_array_new(16, sizeof(int));
+    expectedrev->size = 5;
+    elems = expectedrev->data;
     elems[0] = 47;
     elems[1] = 15;
     elems[2] = 11;
@@ -526,101 +530,102 @@
     
 
     UCX_TEST_BEGIN
-    void* original_ptr = array.data;
+    void* original_ptr = array->data;
     ucx_array_sort(array, ucx_cmp_int, NULL);
     UCX_TEST_ASSERT(ucx_array_equals(array, expected, NULL, NULL), "failed");
-    UCX_TEST_ASSERT(array.size == 5, "size corrupted");
-    UCX_TEST_ASSERT(array.data == original_ptr, "shall not reallocate");
+    UCX_TEST_ASSERT(array->size == 5, "size corrupted");
+    UCX_TEST_ASSERT(array->data == original_ptr, "shall not reallocate");
     
     ucx_array_sort(array, ucx_cmp_int_reverse, NULL);
     UCX_TEST_ASSERT(ucx_array_equals(array, expectedrev, NULL, NULL), "failed");
 
-    ucx_array_reserve(&array, 32);
-    ucx_array_reserve(&expected, 32);
-    array.size = expected.size = 32;
+    ucx_array_reserve(array, 32);
+    ucx_array_reserve(expected, 32);
+    array->size = expected->size = 32;
     for (size_t i = 0 ; i < 32 ; i++) {
-        ((int*)array.data)[i]= ((i%2==0)?-1:1) * ((int) i);
-        ((int*)expected.data)[i] = (-30+2*i) - (i > 15 ? 1 : 0);
+        ((int*)array->data)[i]= ((i%2==0)?-1:1) * ((int) i);
+        ((int*)expected->data)[i] = (-30+2*i) - (i > 15 ? 1 : 0);
     }
     
     /* dummy third argument to trigger a possible fallback for qsort_s */
-    ucx_array_sort(array, ucx_cmp_int, array.data);
+    ucx_array_sort(array, ucx_cmp_int, array->data);
     UCX_TEST_ASSERT(ucx_array_equals(array, expected, NULL, NULL),
             "failed for bigger arrays");
     UCX_TEST_END
 
-    ucx_array_destroy(&expected);
-    ucx_array_destroy(&array);
+    ucx_array_free(expectedrev);
+    ucx_array_free(expected);
+    ucx_array_free(array);
 }
 
 UCX_TEST(test_ucx_array_autogrow) {
     int *elems;
-    UcxArray array = ucx_array_new(4, sizeof(int));
-    array.size = 3;
-    elems = array.data;
+    UcxArray *array = ucx_array_new(4, sizeof(int));
+    array->size = 3;
+    elems = array->data;
     elems[0] = 47;
     elems[1] = 11;
     int x = 5;
     
     UCX_TEST_BEGIN
 
-    void* oldptr = array.data;
+    void* oldptr = array->data;
     
-    ucx_array_append(&array, 5);
-    UCX_TEST_ASSERT(array.capacity == 4 && array.data == oldptr,
+    ucx_array_append(array, 5);
+    UCX_TEST_ASSERT(array->capacity == 4 && array->data == oldptr,
             "array should not grow too early");
-    ucx_array_append(&array, 5);
-    elems = array.data;
-    UCX_TEST_ASSERT(array.capacity == 8, "array did not grow");
-    UCX_TEST_ASSERT(array.size == 5, "incorrect size after grow");
+    ucx_array_append(array, 5);
+    elems = array->data;
+    UCX_TEST_ASSERT(array->capacity == 8, "array did not grow");
+    UCX_TEST_ASSERT(array->size == 5, "incorrect size after grow");
     UCX_TEST_ASSERT(elems[3] == 5 && elems[4] == 5, "corrupt data");
     
     UCX_TEST_END
-    ucx_array_destroy(&array);
+    ucx_array_free(array);
 }
 
 UCX_TEST(test_ucx_array_shrink) {
-    UcxArray array = ucx_array_new(16, sizeof(int));
-    array.size = 4;
+    UcxArray *array = ucx_array_new(16, sizeof(int));
+    array->size = 4;
     
     UCX_TEST_BEGIN
-    UCX_TEST_ASSERT(!ucx_array_shrink(&array), "failed");
-    UCX_TEST_ASSERT(array.capacity == 4, "incorrect capacity after shrink");
+    UCX_TEST_ASSERT(!ucx_array_shrink(array), "failed");
+    UCX_TEST_ASSERT(array->capacity == 4, "incorrect capacity after shrink");
     UCX_TEST_END
-    ucx_array_destroy(&array);
+    ucx_array_free(array);
 }
 
 UCX_TEST(test_ucx_array_resize) {
-    UcxArray array = ucx_array_new(16, sizeof(int));
-    array.size = 8;
+    UcxArray *array = ucx_array_new(16, sizeof(int));
+    array->size = 8;
     
     UCX_TEST_BEGIN
 
-    UCX_TEST_ASSERT(!ucx_array_resize(&array, 32), "failed");
-    UCX_TEST_ASSERT(array.capacity == 32, "incorrect capacity after resize");
-    UCX_TEST_ASSERT(array.size == 8, "incorrect size after resize");
+    UCX_TEST_ASSERT(!ucx_array_resize(array, 32), "failed");
+    UCX_TEST_ASSERT(array->capacity == 32, "incorrect capacity after resize");
+    UCX_TEST_ASSERT(array->size == 8, "incorrect size after resize");
     
-    UCX_TEST_ASSERT(!ucx_array_resize(&array, 4), "failed");
-    UCX_TEST_ASSERT(array.capacity == 4, "incorrect capacity after resize");
-    UCX_TEST_ASSERT(array.size == 4, "incorrect size after resize");
+    UCX_TEST_ASSERT(!ucx_array_resize(array, 4), "failed");
+    UCX_TEST_ASSERT(array->capacity == 4, "incorrect capacity after resize");
+    UCX_TEST_ASSERT(array->size == 4, "incorrect size after resize");
     
     UCX_TEST_END
-    ucx_array_destroy(&array);
+    ucx_array_free(array);
 }
 
 UCX_TEST(test_ucx_array_reserve) {
-    UcxArray array = ucx_array_new(16, sizeof(int));
+    UcxArray *array = ucx_array_new(16, sizeof(int));
     
     UCX_TEST_BEGIN
 
-    UCX_TEST_ASSERT(!ucx_array_reserve(&array, 4), "failed");
-    UCX_TEST_ASSERT(array.capacity == 16, "reserve shall not shrink");
+    UCX_TEST_ASSERT(!ucx_array_reserve(array, 4), "failed");
+    UCX_TEST_ASSERT(array->capacity == 16, "reserve shall not shrink");
             
-    UCX_TEST_ASSERT(!ucx_array_resize(&array, 32), "failed");
-    UCX_TEST_ASSERT(array.capacity == 32, "incorrect capacity after reserve");    
+    UCX_TEST_ASSERT(!ucx_array_resize(array, 32), "failed");
+    UCX_TEST_ASSERT(array->capacity == 32, "incorrect capacity after reserve");    
     
     UCX_TEST_END
-    ucx_array_destroy(&array);
+    ucx_array_free(array);
 }
 
 UCX_TEST(test_ucx_array_util_set) {
--- a/test/array_tests.h	Tue Sep 24 20:16:00 2019 +0200
+++ b/test/array_tests.h	Thu Oct 03 10:55:39 2019 +0200
@@ -36,7 +36,7 @@
 extern "C" {
 #endif
 
-UCX_TEST(test_ucx_array_free);
+UCX_TEST(test_ucx_array_destroy);
 UCX_TEST(test_ucx_array_new);
 UCX_TEST(test_ucx_array_at);
 UCX_TEST(test_ucx_array_append_from);
--- a/test/main.c	Tue Sep 24 20:16:00 2019 +0200
+++ b/test/main.c	Thu Oct 03 10:55:39 2019 +0200
@@ -143,7 +143,7 @@
         ucx_test_register(suite, test_ucx_logger_log);
         
         /* UcxArray Tests */
-        ucx_test_register(suite, test_ucx_array_free);
+        ucx_test_register(suite, test_ucx_array_destroy);
         ucx_test_register(suite, test_ucx_array_new);
         ucx_test_register(suite, test_ucx_array_at);
         ucx_test_register(suite, test_ucx_array_append_from);

mercurial