Sun, 09 Apr 2023 19:03:58 +0200
refactoring of collections to make use of destructors in map implementations
src/CMakeLists.txt | file | annotate | diff | comparison | revisions | |
src/array_list.c | file | annotate | diff | comparison | revisions | |
src/cx/allocator.h | file | annotate | diff | comparison | revisions | |
src/cx/array_list.h | file | annotate | diff | comparison | revisions | |
src/cx/collection.h | file | annotate | diff | comparison | revisions | |
src/cx/hash_map.h | file | annotate | diff | comparison | revisions | |
src/cx/linked_list.h | file | annotate | diff | comparison | revisions | |
src/cx/list.h | file | annotate | diff | comparison | revisions | |
src/cx/map.h | file | annotate | diff | comparison | revisions | |
src/cx/string.h | file | annotate | diff | comparison | revisions | |
src/hash_map.c | file | annotate | diff | comparison | revisions | |
src/linked_list.c | file | annotate | diff | comparison | revisions | |
src/list.c | file | annotate | diff | comparison | revisions | |
tests/test_list.cpp | file | annotate | diff | comparison | revisions | |
tests/test_map.cpp | file | annotate | diff | comparison | revisions |
1.1 --- a/src/CMakeLists.txt Fri Apr 07 11:30:28 2023 +0200 1.2 +++ b/src/CMakeLists.txt Sun Apr 09 19:03:58 2023 +0200 1.3 @@ -19,6 +19,7 @@ 1.4 cx/string.h 1.5 cx/allocator.h 1.6 cx/iterator.h 1.7 + cx/collection.h 1.8 cx/list.h 1.9 cx/array_list.h 1.10 cx/linked_list.h
2.1 --- a/src/array_list.c Fri Apr 07 11:30:28 2023 +0200 2.2 +++ b/src/array_list.c Sun Apr 09 19:03:58 2023 +0200 2.3 @@ -150,6 +150,7 @@ 2.4 typedef struct { 2.5 struct cx_list_s base; 2.6 void *data; 2.7 + size_t capacity; 2.8 struct cx_array_reallocator_s reallocator; 2.9 } cx_array_list; 2.10 2.11 @@ -186,17 +187,17 @@ 2.12 // do we need to move some elements? 2.13 if (index < list->size) { 2.14 char const *first_to_move = (char const *) arl->data; 2.15 - first_to_move += index * list->itemsize; 2.16 + first_to_move += index * list->item_size; 2.17 size_t elems_to_move = list->size - index; 2.18 size_t start_of_moved = index + n; 2.19 2.20 if (CX_ARRAY_COPY_SUCCESS != cx_array_copy( 2.21 &arl->data, 2.22 &list->size, 2.23 - &list->capacity, 2.24 + &arl->capacity, 2.25 start_of_moved, 2.26 first_to_move, 2.27 - list->itemsize, 2.28 + list->item_size, 2.29 elems_to_move, 2.30 &arl->reallocator 2.31 )) { 2.32 @@ -213,10 +214,10 @@ 2.33 if (CX_ARRAY_COPY_SUCCESS == cx_array_copy( 2.34 &arl->data, 2.35 &list->size, 2.36 - &list->capacity, 2.37 + &arl->capacity, 2.38 index, 2.39 array, 2.40 - list->itemsize, 2.41 + list->item_size, 2.42 n, 2.43 &arl->reallocator 2.44 )) { 2.45 @@ -249,7 +250,7 @@ 2.46 ); 2.47 if (result == 0 && prepend != 0) { 2.48 iter->index++; 2.49 - iter->elem_handle = ((char *) iter->elem_handle) + list->itemsize; 2.50 + iter->elem_handle = ((char *) iter->elem_handle) + list->item_size; 2.51 } 2.52 return result; 2.53 } else { 2.54 @@ -271,11 +272,7 @@ 2.55 } 2.56 2.57 // content destruction 2.58 - if (list->content_destructor_type != CX_DESTRUCTOR_NONE) { 2.59 - char *ptr = arl->data; 2.60 - ptr += index * list->itemsize; 2.61 - cx_list_invoke_destructor(list, ptr); 2.62 - } 2.63 + cx_invoke_destructor(list, ((char*)arl->data) + index * list->item_size); 2.64 2.65 // short-circuit removal of last element 2.66 if (index == list->size - 1) { 2.67 @@ -287,10 +284,10 @@ 2.68 int result = cx_array_copy( 2.69 &arl->data, 2.70 &list->size, 2.71 - &list->capacity, 2.72 + &arl->capacity, 2.73 index, 2.74 - ((char *) arl->data) + (index + 1) * list->itemsize, 2.75 - list->itemsize, 2.76 + ((char *) arl->data) + (index + 1) * list->item_size, 2.77 + list->item_size, 2.78 list->size - index - 1, 2.79 &arl->reallocator 2.80 ); 2.81 @@ -307,26 +304,20 @@ 2.82 cx_array_list *arl = (cx_array_list *) list; 2.83 char *ptr = arl->data; 2.84 2.85 - switch (list->content_destructor_type) { 2.86 - case CX_DESTRUCTOR_SIMPLE: { 2.87 - for (size_t i = 0; i < list->size; i++) { 2.88 - cx_list_invoke_simple_destructor(list, ptr); 2.89 - ptr += list->itemsize; 2.90 - } 2.91 - break; 2.92 + if (list->simple_destructor) { 2.93 + for (size_t i = 0; i < list->size; i++) { 2.94 + cx_invoke_simple_destructor(list, ptr); 2.95 + ptr += list->item_size; 2.96 } 2.97 - case CX_DESTRUCTOR_ADVANCED: { 2.98 - for (size_t i = 0; i < list->size; i++) { 2.99 - cx_list_invoke_advanced_destructor(list, ptr); 2.100 - ptr += list->itemsize; 2.101 - } 2.102 - break; 2.103 + } 2.104 + if (list->advanced_destructor) { 2.105 + for (size_t i = 0; i < list->size; i++) { 2.106 + cx_invoke_advanced_destructor(list, ptr); 2.107 + ptr += list->item_size; 2.108 } 2.109 - case CX_DESTRUCTOR_NONE: 2.110 - break; // nothing 2.111 } 2.112 2.113 - memset(arl->data, 0, list->size * list->itemsize); 2.114 + memset(arl->data, 0, list->size * list->item_size); 2.115 list->size = 0; 2.116 } 2.117 2.118 @@ -337,7 +328,7 @@ 2.119 ) { 2.120 if (i >= list->size || j >= list->size) return 1; 2.121 cx_array_list *arl = (cx_array_list *) list; 2.122 - cx_array_swap(arl->data, list->itemsize, i, j); 2.123 + cx_array_swap(arl->data, list->item_size, i, j); 2.124 return 0; 2.125 } 2.126 2.127 @@ -348,7 +339,7 @@ 2.128 if (index < list->size) { 2.129 cx_array_list const *arl = (cx_array_list const *) list; 2.130 char *space = arl->data; 2.131 - return space + index * list->itemsize; 2.132 + return space + index * list->item_size; 2.133 } else { 2.134 return NULL; 2.135 } 2.136 @@ -365,7 +356,7 @@ 2.137 if (0 == list->cmpfunc(elem, cur)) { 2.138 return i; 2.139 } 2.140 - cur += list->itemsize; 2.141 + cur += list->item_size; 2.142 } 2.143 2.144 return list->size; 2.145 @@ -375,7 +366,7 @@ 2.146 assert(list->cmpfunc != NULL); 2.147 qsort(((cx_array_list *) list)->data, 2.148 list->size, 2.149 - list->itemsize, 2.150 + list->item_size, 2.151 list->cmpfunc 2.152 ); 2.153 } 2.154 @@ -393,8 +384,8 @@ 2.155 if (d != 0) { 2.156 return d; 2.157 } 2.158 - left += list->itemsize; 2.159 - right += other->itemsize; 2.160 + left += list->item_size; 2.161 + right += other->item_size; 2.162 } 2.163 return 0; 2.164 } else { 2.165 @@ -407,7 +398,7 @@ 2.166 void *data = ((cx_array_list const *) list)->data; 2.167 size_t half = list->size / 2; 2.168 for (size_t i = 0; i < half; i++) { 2.169 - cx_array_swap(data, list->itemsize, i, list->size - 1 - i); 2.170 + cx_array_swap(data, list->item_size, i, list->size - 1 - i); 2.171 } 2.172 } 2.173 2.174 @@ -433,7 +424,7 @@ 2.175 iter->index++; 2.176 iter->elem_handle = 2.177 ((char *) iter->elem_handle) 2.178 - + ((struct cx_list_s const *) iter->src_handle)->itemsize; 2.179 + + ((struct cx_list_s const *) iter->src_handle)->item_size; 2.180 } 2.181 } 2.182 2.183 @@ -448,7 +439,7 @@ 2.184 iter->index--; 2.185 if (iter->index < list->base.size) { 2.186 iter->elem_handle = ((char *) list->data) 2.187 - + iter->index * list->base.itemsize; 2.188 + + iter->index * list->base.item_size; 2.189 } 2.190 } 2.191 2.192 @@ -500,7 +491,7 @@ 2.193 2.194 CxList *cxArrayListCreate( 2.195 CxAllocator const *allocator, 2.196 - CxListComparator comparator, 2.197 + cx_compare_func comparator, 2.198 size_t item_size, 2.199 size_t initial_capacity 2.200 ) { 2.201 @@ -514,10 +505,10 @@ 2.202 list->base.cl = &cx_array_list_class; 2.203 list->base.allocator = allocator; 2.204 list->base.cmpfunc = comparator; 2.205 - list->base.capacity = initial_capacity; 2.206 + list->capacity = initial_capacity; 2.207 2.208 if (item_size > 0) { 2.209 - list->base.itemsize = item_size; 2.210 + list->base.item_size = item_size; 2.211 } else { 2.212 item_size = sizeof(void*); 2.213 cxListStorePointers((CxList *) list);
3.1 --- a/src/cx/allocator.h Fri Apr 07 11:30:28 2023 +0200 3.2 +++ b/src/cx/allocator.h Sun Apr 09 19:03:58 2023 +0200 3.3 @@ -133,41 +133,6 @@ 3.4 ) __attribute__((__nonnull__(2))); 3.5 3.6 /** 3.7 - * Structure holding an advanced destructor function and the desired payload. 3.8 - * Invocations of func should use data as first argument. 3.9 - */ 3.10 -typedef struct { 3.11 - /** 3.12 - * A pointer to the data that SHALL be used to invoke func. 3.13 - */ 3.14 - void *data; 3.15 - /** 3.16 - * A pointer to the function to invoke. 3.17 - */ 3.18 - cx_destructor_func2 func; 3.19 -} cx_advanced_destructor; 3.20 - 3.21 -/** 3.22 - * Specifies the type of destructor to use. 3.23 - */ 3.24 -enum cx_destructor_type { 3.25 - /** 3.26 - * Do not use a destructor function. 3.27 - */ 3.28 - CX_DESTRUCTOR_NONE, 3.29 - /** 3.30 - * Use a simple destructor. 3.31 - * @see cx_destructor_func 3.32 - */ 3.33 - CX_DESTRUCTOR_SIMPLE, 3.34 - /** 3.35 - * Use an advanced destructor. 3.36 - * @see cx_advanced_destructor 3.37 - */ 3.38 - CX_DESTRUCTOR_ADVANCED 3.39 -}; 3.40 - 3.41 -/** 3.42 * Allocate \p n bytes of memory. 3.43 * 3.44 * @param allocator the allocator
4.1 --- a/src/cx/array_list.h Fri Apr 07 11:30:28 2023 +0200 4.2 +++ b/src/cx/array_list.h Sun Apr 09 19:03:58 2023 +0200 4.3 @@ -165,7 +165,7 @@ 4.4 */ 4.5 CxList *cxArrayListCreate( 4.6 CxAllocator const *allocator, 4.7 - CxListComparator comparator, 4.8 + cx_compare_func comparator, 4.9 size_t item_size, 4.10 size_t initial_capacity 4.11 );
5.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 5.2 +++ b/src/cx/collection.h Sun Apr 09 19:03:58 2023 +0200 5.3 @@ -0,0 +1,139 @@ 5.4 +/* 5.5 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. 5.6 + * 5.7 + * Copyright 2023 Mike Becker, Olaf Wintermann All rights reserved. 5.8 + * 5.9 + * Redistribution and use in source and binary forms, with or without 5.10 + * modification, are permitted provided that the following conditions are met: 5.11 + * 5.12 + * 1. Redistributions of source code must retain the above copyright 5.13 + * notice, this list of conditions and the following disclaimer. 5.14 + * 5.15 + * 2. Redistributions in binary form must reproduce the above copyright 5.16 + * notice, this list of conditions and the following disclaimer in the 5.17 + * documentation and/or other materials provided with the distribution. 5.18 + * 5.19 + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 5.20 + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 5.21 + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 5.22 + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE 5.23 + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 5.24 + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 5.25 + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 5.26 + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 5.27 + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 5.28 + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 5.29 + * POSSIBILITY OF SUCH DAMAGE. 5.30 + */ 5.31 +/** 5.32 + * \file collection.h 5.33 + * \brief Common definitions for various collection implementations. 5.34 + * \author Mike Becker 5.35 + * \author Olaf Wintermann 5.36 + * \version 3.0 5.37 + * \copyright 2-Clause BSD License 5.38 + */ 5.39 + 5.40 +#ifndef UCX_COLLECTION_H 5.41 +#define UCX_COLLECTION_H 5.42 + 5.43 +#include "common.h" 5.44 +#include "allocator.h" 5.45 +#include "iterator.h" 5.46 + 5.47 +#ifdef __cplusplus 5.48 +extern "C" { 5.49 +#endif 5.50 + 5.51 +/** 5.52 + * Special constant used for creating collections that are storing pointers. 5.53 + */ 5.54 +#define CX_STORE_POINTERS 0 5.55 + 5.56 +/** 5.57 + * A comparator function comparing two collection elements. 5.58 + */ 5.59 +typedef int(*cx_compare_func)( 5.60 + void const *left, 5.61 + void const *right 5.62 +); 5.63 + 5.64 +/** 5.65 + * Use this macro to declare common members for a collection structure. 5.66 + */ 5.67 +#define CX_COLLECTION_MEMBERS \ 5.68 + /** \ 5.69 + * The allocator to use. \ 5.70 + */ \ 5.71 + CxAllocator const *allocator; \ 5.72 + /** \ 5.73 + * The comparator function for the elements. \ 5.74 + */ \ 5.75 + cx_compare_func cmpfunc; \ 5.76 + /** \ 5.77 + * The size of each element. \ 5.78 + */ \ 5.79 + size_t item_size; \ 5.80 + /** \ 5.81 + * The number of currently stored elements. \ 5.82 + */ \ 5.83 + size_t size; \ 5.84 + /** \ 5.85 + * An optional simple destructor for the collection's elements. \ 5.86 + * \ 5.87 + * @attention Read the documentation of the particular collection implementation \ 5.88 + * whether this destructor shall only destroy the contents or also free the memory. \ 5.89 + */ \ 5.90 + cx_destructor_func simple_destructor; \ 5.91 + /** \ 5.92 + * An optional advanced destructor for the collection's elements. \ 5.93 + * \ 5.94 + * @attention Read the documentation of the particular collection implementation \ 5.95 + * whether this destructor shall only destroy the contents or also free the memory. \ 5.96 + */ \ 5.97 + cx_destructor_func2 advanced_destructor; \ 5.98 + /** \ 5.99 + * The pointer to additional data that is passed to the advanced destructor. \ 5.100 + */ \ 5.101 + void *destructor_data; \ 5.102 + /** \ 5.103 + * Indicates if this instance of a collection is supposed to store pointers \ 5.104 + * instead of copies of the actual objects. \ 5.105 + */ \ 5.106 + bool store_pointer; 5.107 + 5.108 +/** 5.109 + * Invokes the simple destructor function for a specific element. 5.110 + * 5.111 + * Usually only used by collection implementations. There should be no need 5.112 + * to invoke this macro manually. 5.113 + * 5.114 + * @param c the collection 5.115 + * @param e the element 5.116 + */ 5.117 +#define cx_invoke_simple_destructor(c, e) \ 5.118 + (c)->simple_destructor((c)->store_pointer ? (*((void **) e)) : e) 5.119 + 5.120 +/** 5.121 + * Invokes the advanced destructor function for a specific element. 5.122 + * 5.123 + * Usually only used by collection implementations. There should be no need 5.124 + * to invoke this macro manually. 5.125 + * 5.126 + * @param c the collection 5.127 + * @param e the element 5.128 + */ 5.129 +#define cx_invoke_advanced_destructor(c, e) \ 5.130 + (c)->advanced_destructor((c)->destructor_data, \ 5.131 + (c)->store_pointer ? (*((void **) e)) : e) 5.132 + 5.133 + 5.134 +#define cx_invoke_destructor(c, e) \ 5.135 + if ((c)->simple_destructor) cx_invoke_simple_destructor(c,e); \ 5.136 + if ((c)->advanced_destructor) cx_invoke_advanced_destructor(c,e) 5.137 + 5.138 +#ifdef __cplusplus 5.139 +} // extern "C" 5.140 +#endif 5.141 + 5.142 +#endif // UCX_COLLECTION_H
6.1 --- a/src/cx/hash_map.h Fri Apr 07 11:30:28 2023 +0200 6.2 +++ b/src/cx/hash_map.h Sun Apr 09 19:03:58 2023 +0200 6.3 @@ -70,7 +70,7 @@ 6.4 * 6.5 * If \p buckets is zero, an implementation defined default will be used. 6.6 * 6.7 - * If \p itemsize is CX_STORE_POINTERS, the created map will be created as if 6.8 + * If \p item_size is CX_STORE_POINTERS, the created map will be created as if 6.9 * cxMapStorePointers() was called immediately after creation. 6.10 * 6.11 * @note Iterators provided by this hash map implementation provide the remove operation.
7.1 --- a/src/cx/linked_list.h Fri Apr 07 11:30:28 2023 +0200 7.2 +++ b/src/cx/linked_list.h Sun Apr 09 19:03:58 2023 +0200 7.3 @@ -66,7 +66,7 @@ 7.4 */ 7.5 CxList *cxLinkedListCreate( 7.6 CxAllocator const *allocator, 7.7 - CxListComparator comparator, 7.8 + cx_compare_func comparator, 7.9 size_t item_size 7.10 ); 7.11 7.12 @@ -124,7 +124,7 @@ 7.13 void const *start, 7.14 ptrdiff_t loc_advance, 7.15 ptrdiff_t loc_data, 7.16 - CxListComparator cmp_func, 7.17 + cx_compare_func cmp_func, 7.18 void const *elem 7.19 ) __attribute__((__nonnull__)); 7.20 7.21 @@ -368,7 +368,7 @@ 7.22 ptrdiff_t loc_prev, 7.23 ptrdiff_t loc_next, 7.24 ptrdiff_t loc_data, 7.25 - CxListComparator cmp_func 7.26 + cx_compare_func cmp_func 7.27 ) __attribute__((__nonnull__(1, 6))); 7.28 7.29 7.30 @@ -390,7 +390,7 @@ 7.31 void const *begin_right, 7.32 ptrdiff_t loc_advance, 7.33 ptrdiff_t loc_data, 7.34 - CxListComparator cmp_func 7.35 + cx_compare_func cmp_func 7.36 ) __attribute__((__nonnull__(5))); 7.37 7.38 /**
8.1 --- a/src/cx/list.h Fri Apr 07 11:30:28 2023 +0200 8.2 +++ b/src/cx/list.h Sun Apr 09 19:03:58 2023 +0200 8.3 @@ -37,29 +37,12 @@ 8.4 #ifndef UCX_LIST_H 8.5 #define UCX_LIST_H 8.6 8.7 -#include "common.h" 8.8 -#include "allocator.h" 8.9 -#include "iterator.h" 8.10 +#include "collection.h" 8.11 8.12 #ifdef __cplusplus 8.13 extern "C" { 8.14 #endif 8.15 8.16 -#ifndef CX_STORE_POINTERS 8.17 -/** 8.18 - * Special constant used for creating collections that are storing pointers. 8.19 - */ 8.20 -#define CX_STORE_POINTERS 0 8.21 -#endif 8.22 - 8.23 -/** 8.24 - * A comparator function comparing two list elements. 8.25 - */ 8.26 -typedef int(*CxListComparator)( 8.27 - void const *left, 8.28 - void const *right 8.29 -); 8.30 - 8.31 /** 8.32 * List class type. 8.33 */ 8.34 @@ -69,6 +52,7 @@ 8.35 * Structure for holding the base data of a list. 8.36 */ 8.37 struct cx_list_s { 8.38 + CX_COLLECTION_MEMBERS 8.39 /** 8.40 * The list class definition. 8.41 */ 8.42 @@ -77,50 +61,6 @@ 8.43 * The actual implementation in case the list class is delegating. 8.44 */ 8.45 cx_list_class const *climpl; 8.46 - /** 8.47 - * The allocator to use. 8.48 - */ 8.49 - CxAllocator const *allocator; 8.50 - /** 8.51 - * The comparator function for the elements. 8.52 - */ 8.53 - CxListComparator cmpfunc; 8.54 - /** 8.55 - * The size of each element (payload only). 8.56 - */ 8.57 - size_t itemsize; 8.58 - /** 8.59 - * The size of the list (number of currently stored elements). 8.60 - */ 8.61 - size_t size; 8.62 - /** 8.63 - * The capacity of the list (maximum number of elements). 8.64 - */ 8.65 - size_t capacity; 8.66 - union { 8.67 - /** 8.68 - * An optional simple destructor for the list contents that admits the free() interface. 8.69 - * 8.70 - * @remark Set content_destructor_type to #CX_DESTRUCTOR_SIMPLE. 8.71 - * 8.72 - * @attention Read the documentation of the particular list implementation 8.73 - * whether this destructor shall only destroy the contents or also free the memory. 8.74 - */ 8.75 - cx_destructor_func simple_destructor; 8.76 - /** 8.77 - * An optional advanced destructor for the list contents providing additional data. 8.78 - * 8.79 - * @remark Set content_destructor_type to #CX_DESTRUCTOR_ADVANCED. 8.80 - * 8.81 - * @attention Read the documentation of the particular list implementation 8.82 - * whether this destructor shall only destroy the contents or also free the memory. 8.83 - */ 8.84 - cx_advanced_destructor advanced_destructor; 8.85 - }; 8.86 - /** 8.87 - * The type of destructor to use. 8.88 - */ 8.89 - enum cx_destructor_type content_destructor_type; 8.90 }; 8.91 8.92 /** 8.93 @@ -234,51 +174,6 @@ 8.94 typedef struct cx_list_s CxList; 8.95 8.96 /** 8.97 - * Invokes the configured destructor function for a specific element. 8.98 - * 8.99 - * Usually only used by list implementations. There should be no need 8.100 - * to invoke this function manually. 8.101 - * 8.102 - * @param list the list 8.103 - * @param elem the element 8.104 - */ 8.105 -__attribute__((__nonnull__)) 8.106 -void cx_list_invoke_destructor( 8.107 - struct cx_list_s const *list, 8.108 - void *elem 8.109 -); 8.110 - 8.111 -/** 8.112 - * Invokes the simple destructor function for a specific element. 8.113 - * 8.114 - * Usually only used by list implementations. There should be no need 8.115 - * to invoke this function manually. 8.116 - * 8.117 - * @param list the list 8.118 - * @param elem the element 8.119 - */ 8.120 -__attribute__((__nonnull__)) 8.121 -void cx_list_invoke_simple_destructor( 8.122 - struct cx_list_s const *list, 8.123 - void *elem 8.124 -); 8.125 - 8.126 -/** 8.127 - * Invokes the advanced destructor function for a specific element. 8.128 - * 8.129 - * Usually only used by list implementations. There should be no need 8.130 - * to invoke this function manually. 8.131 - * 8.132 - * @param list the list 8.133 - * @param elem the element 8.134 - */ 8.135 -__attribute__((__nonnull__)) 8.136 -void cx_list_invoke_advanced_destructor( 8.137 - struct cx_list_s const *list, 8.138 - void *elem 8.139 -); 8.140 - 8.141 -/** 8.142 * Advises the list to store copies of the objects (default mode of operation). 8.143 * 8.144 * Retrieving objects from this list will yield pointers to the copies stored 8.145 @@ -309,11 +204,24 @@ 8.146 * Returns true, if this list is storing pointers instead of the actual data. 8.147 * 8.148 * @param list 8.149 - * @return 8.150 + * @return true, if this list is storing pointers 8.151 * @see cxListStorePointers() 8.152 */ 8.153 __attribute__((__nonnull__)) 8.154 -bool cxListIsStoringPointers(CxList const *list); 8.155 +static inline bool cxListIsStoringPointers(CxList const *list) { 8.156 + return list->store_pointer; 8.157 +} 8.158 + 8.159 +/** 8.160 + * Returns the number of elements currently stored in the list. 8.161 + * 8.162 + * @param list the list 8.163 + * @return the number of currently stored elements 8.164 + */ 8.165 +__attribute__((__nonnull__)) 8.166 +static inline size_t cxListSize(CxList const *list) { 8.167 + return list->size; 8.168 +} 8.169 8.170 /** 8.171 * Adds an item to the end of the list.
9.1 --- a/src/cx/map.h Fri Apr 07 11:30:28 2023 +0200 9.2 +++ b/src/cx/map.h Sun Apr 09 19:03:58 2023 +0200 9.3 @@ -37,22 +37,13 @@ 9.4 #ifndef UCX_MAP_H 9.5 #define UCX_MAP_H 9.6 9.7 -#include "common.h" 9.8 -#include "allocator.h" 9.9 -#include "iterator.h" 9.10 +#include "collection.h" 9.11 #include "hash_key.h" 9.12 9.13 #ifdef __cplusplus 9.14 extern "C" { 9.15 #endif 9.16 9.17 -#ifndef CX_STORE_POINTERS 9.18 -/** 9.19 - * Special constant used for creating collections that are storing pointers. 9.20 - */ 9.21 -#define CX_STORE_POINTERS 0 9.22 -#endif 9.23 - 9.24 /** Type for the UCX map. */ 9.25 typedef struct cx_map_s CxMap; 9.26 9.27 @@ -73,7 +64,7 @@ 9.28 /** 9.29 * The size of an element. 9.30 */ 9.31 - size_t itemsize; 9.32 + size_t item_size; 9.33 /** 9.34 * True, if this map shall store pointers instead 9.35 * of copies of objects. 9.36 @@ -205,7 +196,7 @@ 9.37 __attribute__((__nonnull__)) 9.38 static inline void cxMapStorePointers(CxMap *map) { 9.39 map->store_pointers = true; 9.40 - map->itemsize = sizeof(void *); 9.41 + map->item_size = sizeof(void *); 9.42 } 9.43 9.44
10.1 --- a/src/cx/string.h Fri Apr 07 11:30:28 2023 +0200 10.2 +++ b/src/cx/string.h Sun Apr 09 19:03:58 2023 +0200 10.3 @@ -660,7 +660,7 @@ 10.4 /** 10.5 * Compares two strings. 10.6 * 10.7 - * This function has a compatible signature for the use as a CxListComparator. 10.8 + * This function has a compatible signature for the use as a cx_compare_func. 10.9 * 10.10 * @param s1 the first string 10.11 * @param s2 the second string 10.12 @@ -676,7 +676,7 @@ 10.13 /** 10.14 * Compares two strings ignoring case. 10.15 * 10.16 - * This function has a compatible signature for the use as a CxListComparator. 10.17 + * This function has a compatible signature for the use as a cx_compare_func. 10.18 * 10.19 * @param s1 the first string 10.20 * @param s2 the second string
11.1 --- a/src/hash_map.c Fri Apr 07 11:30:28 2023 +0200 11.2 +++ b/src/hash_map.c Sun Apr 09 19:03:58 2023 +0200 11.3 @@ -103,13 +103,13 @@ 11.4 if (map->store_pointers) { 11.5 memcpy(elm->data, &value, sizeof(void *)); 11.6 } else { 11.7 - memcpy(elm->data, value, map->itemsize); 11.8 + memcpy(elm->data, value, map->item_size); 11.9 } 11.10 } else { 11.11 // allocate new element 11.12 struct cx_hash_map_element_s *e = cxMalloc( 11.13 allocator, 11.14 - sizeof(struct cx_hash_map_element_s) + map->itemsize 11.15 + sizeof(struct cx_hash_map_element_s) + map->item_size 11.16 ); 11.17 if (e == NULL) { 11.18 return -1; 11.19 @@ -119,7 +119,7 @@ 11.20 if (map->store_pointers) { 11.21 memcpy(e->data, &value, sizeof(void *)); 11.22 } else { 11.23 - memcpy(e->data, value, map->itemsize); 11.24 + memcpy(e->data, value, map->item_size); 11.25 } 11.26 11.27 // copy the key 11.28 @@ -434,10 +434,10 @@ 11.29 11.30 if (itemsize > 0) { 11.31 map->base.store_pointers = false; 11.32 - map->base.itemsize = itemsize; 11.33 + map->base.item_size = itemsize; 11.34 } else { 11.35 map->base.store_pointers = true; 11.36 - map->base.itemsize = sizeof(void *); 11.37 + map->base.item_size = sizeof(void *); 11.38 } 11.39 11.40 return (CxMap *) map;
12.1 --- a/src/linked_list.c Fri Apr 07 11:30:28 2023 +0200 12.2 +++ b/src/linked_list.c Sun Apr 09 19:03:58 2023 +0200 12.3 @@ -60,7 +60,7 @@ 12.4 void const *start, 12.5 ptrdiff_t loc_advance, 12.6 ptrdiff_t loc_data, 12.7 - CxListComparator cmp_func, 12.8 + cx_compare_func cmp_func, 12.9 void const *elem 12.10 ) { 12.11 assert(start != NULL); 12.12 @@ -291,7 +291,7 @@ 12.13 void *ls, 12.14 void *le, 12.15 void *re, 12.16 - CxListComparator cmp_func 12.17 + cx_compare_func cmp_func 12.18 ) { 12.19 void *sbo[CX_LINKED_LIST_SORT_SBO_SIZE]; 12.20 void **sorted = length >= CX_LINKED_LIST_SORT_SBO_SIZE ? 12.21 @@ -343,7 +343,7 @@ 12.22 ptrdiff_t loc_prev, 12.23 ptrdiff_t loc_next, 12.24 ptrdiff_t loc_data, 12.25 - CxListComparator cmp_func 12.26 + cx_compare_func cmp_func 12.27 ) { 12.28 assert(begin != NULL); 12.29 assert(loc_next >= 0); 12.30 @@ -403,7 +403,7 @@ 12.31 void const *begin_right, 12.32 ptrdiff_t loc_advance, 12.33 ptrdiff_t loc_data, 12.34 - CxListComparator cmp_func 12.35 + cx_compare_func cmp_func 12.36 ) { 12.37 void const *left = begin_left, *right = begin_right; 12.38 12.39 @@ -494,14 +494,14 @@ 12.40 12.41 // create the new new_node 12.42 cx_linked_list_node *new_node = cxMalloc(list->allocator, 12.43 - sizeof(cx_linked_list_node) + list->itemsize); 12.44 + sizeof(cx_linked_list_node) + list->item_size); 12.45 12.46 // sortir if failed 12.47 if (new_node == NULL) return 1; 12.48 12.49 // initialize new new_node 12.50 new_node->prev = new_node->next = NULL; 12.51 - memcpy(new_node->payload, elem, list->itemsize); 12.52 + memcpy(new_node->payload, elem, list->item_size); 12.53 12.54 // insert 12.55 cx_linked_list *ll = (cx_linked_list *) list; 12.56 @@ -542,7 +542,7 @@ 12.57 // we can add the remaining nodes and immedately advance to the inserted node 12.58 char const *source = array; 12.59 for (size_t i = 1; i < n; i++) { 12.60 - source += list->itemsize; 12.61 + source += list->item_size; 12.62 if (0 != cx_ll_insert_at(list, node, source)) { 12.63 return i; 12.64 } 12.65 @@ -570,9 +570,7 @@ 12.66 if (node == NULL) return 1; 12.67 12.68 // element destruction 12.69 - if (list->content_destructor_type != CX_DESTRUCTOR_NONE) { 12.70 - cx_list_invoke_destructor(list, node->payload); 12.71 - } 12.72 + cx_invoke_destructor(list, node->payload); 12.73 12.74 // remove 12.75 cx_linked_list_remove((void **) &ll->begin, (void **) &ll->end, 12.76 @@ -592,38 +590,12 @@ 12.77 12.78 cx_linked_list *ll = (cx_linked_list *) list; 12.79 cx_linked_list_node *node = ll->begin; 12.80 - 12.81 - // looks super redundant, but avoids repeatedly checking 12.82 - // the destructor type for each element 12.83 - switch (list->content_destructor_type) { 12.84 - case CX_DESTRUCTOR_SIMPLE: { 12.85 - while (node != NULL) { 12.86 - cx_list_invoke_simple_destructor(list, node->payload); 12.87 - cx_linked_list_node *next = node->next; 12.88 - cxFree(list->allocator, node); 12.89 - node = next; 12.90 - } 12.91 - break; 12.92 - } 12.93 - case CX_DESTRUCTOR_ADVANCED: { 12.94 - while (node != NULL) { 12.95 - cx_list_invoke_advanced_destructor(list, node->payload); 12.96 - cx_linked_list_node *next = node->next; 12.97 - cxFree(list->allocator, node); 12.98 - node = next; 12.99 - } 12.100 - break; 12.101 - } 12.102 - case CX_DESTRUCTOR_NONE: { 12.103 - while (node != NULL) { 12.104 - cx_linked_list_node *next = node->next; 12.105 - cxFree(list->allocator, node); 12.106 - node = next; 12.107 - } 12.108 - break; 12.109 - } 12.110 + while (node != NULL) { 12.111 + cx_invoke_destructor(list, node->payload); 12.112 + cx_linked_list_node *next = node->next; 12.113 + cxFree(list->allocator, node); 12.114 + node = next; 12.115 } 12.116 - 12.117 ll->begin = ll->end = NULL; 12.118 list->size = 0; 12.119 } 12.120 @@ -708,7 +680,7 @@ 12.121 } 12.122 } 12.123 12.124 - if (list->itemsize > CX_LINKED_LIST_SWAP_SBO_SIZE || CX_DISABLE_LINKED_LIST_SWAP_SBO) { 12.125 + if (list->item_size > CX_LINKED_LIST_SWAP_SBO_SIZE || CX_DISABLE_LINKED_LIST_SWAP_SBO) { 12.126 cx_linked_list_node *prev = nleft->prev; 12.127 cx_linked_list_node *next = nright->next; 12.128 cx_linked_list_node *midstart = nleft->next; 12.129 @@ -740,9 +712,9 @@ 12.130 } else { 12.131 // swap payloads to avoid relinking 12.132 char buf[CX_LINKED_LIST_SWAP_SBO_SIZE]; 12.133 - memcpy(buf, nleft->payload, list->itemsize); 12.134 - memcpy(nleft->payload, nright->payload, list->itemsize); 12.135 - memcpy(nright->payload, buf, list->itemsize); 12.136 + memcpy(buf, nleft->payload, list->item_size); 12.137 + memcpy(nleft->payload, nright->payload, list->item_size); 12.138 + memcpy(nright->payload, buf, list->item_size); 12.139 } 12.140 12.141 return 0; 12.142 @@ -803,9 +775,7 @@ 12.143 cx_linked_list *ll = iter->src_handle; 12.144 cx_linked_list_node *node = iter->elem_handle; 12.145 iter->elem_handle = node->next; 12.146 - if (list->content_destructor_type != CX_DESTRUCTOR_NONE) { 12.147 - cx_list_invoke_destructor(list, node->payload); 12.148 - } 12.149 + cx_invoke_destructor(list, node->payload); 12.150 cx_linked_list_remove((void **) &ll->begin, (void **) &ll->end, 12.151 CX_LL_LOC_PREV, CX_LL_LOC_NEXT, node); 12.152 list->size--; 12.153 @@ -828,9 +798,7 @@ 12.154 cx_linked_list_node *node = iter->elem_handle; 12.155 iter->elem_handle = node->prev; 12.156 iter->index--; 12.157 - if (list->content_destructor_type != CX_DESTRUCTOR_NONE) { 12.158 - cx_list_invoke_destructor(list, node->payload); 12.159 - } 12.160 + cx_invoke_destructor(list, node->payload); 12.161 cx_linked_list_remove((void **) &ll->begin, (void **) &ll->end, 12.162 CX_LL_LOC_PREV, CX_LL_LOC_NEXT, node); 12.163 list->size--; 12.164 @@ -927,7 +895,7 @@ 12.165 12.166 CxList *cxLinkedListCreate( 12.167 CxAllocator const *allocator, 12.168 - CxListComparator comparator, 12.169 + cx_compare_func comparator, 12.170 size_t item_size 12.171 ) { 12.172 if (allocator == NULL) { 12.173 @@ -940,10 +908,9 @@ 12.174 list->base.cl = &cx_linked_list_class; 12.175 list->base.allocator = allocator; 12.176 list->base.cmpfunc = comparator; 12.177 - list->base.capacity = SIZE_MAX; 12.178 12.179 if (item_size > 0) { 12.180 - list->base.itemsize = item_size; 12.181 + list->base.item_size = item_size; 12.182 } else { 12.183 cxListStorePointers((CxList *) list); 12.184 }
13.1 --- a/src/list.c Fri Apr 07 11:30:28 2023 +0200 13.2 +++ b/src/list.c Sun Apr 09 19:03:58 2023 +0200 13.3 @@ -32,7 +32,7 @@ 13.4 13.5 // <editor-fold desc="Store Pointers Functionality"> 13.6 13.7 -static _Thread_local CxListComparator cx_pl_cmpfunc_impl; 13.8 +static _Thread_local cx_compare_func cx_pl_cmpfunc_impl; 13.9 13.10 static int cx_pl_cmpfunc( 13.11 void const *l, 13.12 @@ -179,6 +179,7 @@ 13.13 }; 13.14 13.15 void cxListStoreObjects(CxList *list) { 13.16 + list->store_pointer = false; 13.17 if (list->climpl != NULL) { 13.18 list->cl = list->climpl; 13.19 list->climpl = NULL; 13.20 @@ -186,75 +187,28 @@ 13.21 } 13.22 13.23 void cxListStorePointers(CxList *list) { 13.24 - list->itemsize = sizeof(void *); 13.25 + list->item_size = sizeof(void *); 13.26 + list->store_pointer = true; 13.27 list->climpl = list->cl; 13.28 list->cl = &cx_pointer_list_class; 13.29 } 13.30 13.31 -bool cxListIsStoringPointers(CxList const *list) { 13.32 - return list->climpl != NULL; 13.33 -} 13.34 - 13.35 // </editor-fold> 13.36 13.37 -void cx_list_invoke_destructor( 13.38 - CxList const *list, 13.39 - void *elem 13.40 -) { 13.41 - switch (list->content_destructor_type) { 13.42 - case CX_DESTRUCTOR_SIMPLE: { 13.43 - cx_list_invoke_simple_destructor(list, elem); 13.44 - break; 13.45 +void cxListDestroy(CxList *list) { 13.46 + if (list->simple_destructor) { 13.47 + CxIterator iter = cxListIterator(list); 13.48 + cx_foreach(void*, elem, iter) { 13.49 + // already correctly resolved pointer - immediately invoke dtor 13.50 + list->simple_destructor(elem); 13.51 } 13.52 - case CX_DESTRUCTOR_ADVANCED: { 13.53 - cx_list_invoke_advanced_destructor(list, elem); 13.54 - break; 13.55 + } 13.56 + if (list->advanced_destructor) { 13.57 + CxIterator iter = cxListIterator(list); 13.58 + cx_foreach(void*, elem, iter) { 13.59 + // already correctly resolved pointer - immediately invoke dtor 13.60 + list->advanced_destructor(list->destructor_data, elem); 13.61 } 13.62 - case CX_DESTRUCTOR_NONE: 13.63 - break; // nothing 13.64 - } 13.65 -} 13.66 - 13.67 -void cx_list_invoke_simple_destructor( 13.68 - CxList const *list, 13.69 - void *elem 13.70 -) { 13.71 - if (cxListIsStoringPointers(list)) { 13.72 - elem = *((void **) elem); 13.73 - } 13.74 - list->simple_destructor(elem); 13.75 -} 13.76 - 13.77 -void cx_list_invoke_advanced_destructor( 13.78 - CxList const *list, 13.79 - void *elem 13.80 -) { 13.81 - if (cxListIsStoringPointers(list)) { 13.82 - elem = *((void **) elem); 13.83 - } 13.84 - list->advanced_destructor.func(list->advanced_destructor.data, elem); 13.85 -} 13.86 - 13.87 -void cxListDestroy(CxList *list) { 13.88 - switch (list->content_destructor_type) { 13.89 - case CX_DESTRUCTOR_SIMPLE: { 13.90 - CxIterator iter = cxListIterator(list); 13.91 - cx_foreach(void*, elem, iter) { 13.92 - // already correctly resolved pointer - immediately invoke dtor 13.93 - list->simple_destructor(elem); 13.94 - } 13.95 - break; 13.96 - } 13.97 - case CX_DESTRUCTOR_ADVANCED: { 13.98 - CxIterator iter = cxListIterator(list); 13.99 - cx_foreach(void*, elem, iter) { 13.100 - // already correctly resolved pointer - immediately invoke dtor 13.101 - list->advanced_destructor.func(list->advanced_destructor.data, elem); 13.102 - } 13.103 - break; 13.104 - } 13.105 - case CX_DESTRUCTOR_NONE: 13.106 - break; // nothing 13.107 } 13.108 13.109 list->cl->destructor(list);
14.1 --- a/tests/test_list.cpp Fri Apr 07 11:30:28 2023 +0200 14.2 +++ b/tests/test_list.cpp Sun Apr 09 19:03:58 2023 +0200 14.3 @@ -592,8 +592,7 @@ 14.4 ) { 14.5 auto len = testdata_len; 14.6 cx_for_n (i, len) EXPECT_EQ(cxListAdd(list, &testdata.data[i]), 0); 14.7 - EXPECT_EQ(list->size, len); 14.8 - EXPECT_GE(list->capacity, list->size); 14.9 + EXPECT_EQ(cxListSize(list), len); 14.10 cx_for_n (i, len) EXPECT_EQ(*(int *) cxListAt(list, i), testdata.data[i]); 14.11 cx_for_n (i, len) ++testdata.data[i]; 14.12 if (as_pointer) { 14.13 @@ -607,17 +606,16 @@ 14.14 int a = 5, b = 47, c = 13, d = 42; 14.15 14.16 EXPECT_NE(cxListInsert(list, 1, &a), 0); 14.17 - EXPECT_EQ(list->size, 0); 14.18 + EXPECT_EQ(cxListSize(list), 0); 14.19 EXPECT_EQ(cxListInsert(list, 0, &a), 0); 14.20 - EXPECT_EQ(list->size, 1); 14.21 + EXPECT_EQ(cxListSize(list), 1); 14.22 EXPECT_EQ(cxListInsert(list, 0, &b), 0); 14.23 - EXPECT_EQ(list->size, 2); 14.24 + EXPECT_EQ(cxListSize(list), 2); 14.25 EXPECT_EQ(cxListInsert(list, 1, &c), 0); 14.26 - EXPECT_EQ(list->size, 3); 14.27 + EXPECT_EQ(cxListSize(list), 3); 14.28 EXPECT_EQ(cxListInsert(list, 3, &d), 0); 14.29 14.30 - ASSERT_EQ(list->size, 4); 14.31 - EXPECT_GE(list->capacity, list->size); 14.32 + ASSERT_EQ(cxListSize(list), 4); 14.33 14.34 EXPECT_EQ(*(int *) cxListAt(list, 0), 47); 14.35 EXPECT_EQ(*(int *) cxListAt(list, 1), 13); 14.36 @@ -672,8 +670,7 @@ 14.37 void verifyRemove(CxList *list) const { 14.38 EXPECT_EQ(cxListRemove(list, 2), 0); 14.39 EXPECT_EQ(cxListRemove(list, 4), 0); 14.40 - EXPECT_EQ(list->size, testdata_len - 2); 14.41 - EXPECT_GE(list->capacity, list->size); 14.42 + EXPECT_EQ(cxListSize(list), testdata_len - 2); 14.43 EXPECT_EQ(*(int *) cxListAt(list, 0), testdata.data[0]); 14.44 EXPECT_EQ(*(int *) cxListAt(list, 1), testdata.data[1]); 14.45 EXPECT_EQ(*(int *) cxListAt(list, 2), testdata.data[3]); 14.46 @@ -681,8 +678,7 @@ 14.47 EXPECT_EQ(*(int *) cxListAt(list, 4), testdata.data[6]); 14.48 14.49 EXPECT_EQ(cxListRemove(list, 0), 0); 14.50 - EXPECT_EQ(list->size, testdata_len - 3); 14.51 - EXPECT_GE(list->capacity, list->size); 14.52 + EXPECT_EQ(cxListSize(list), testdata_len - 3); 14.53 EXPECT_EQ(*(int *) cxListAt(list, 0), testdata.data[1]); 14.54 EXPECT_EQ(*(int *) cxListAt(list, 1), testdata.data[3]); 14.55 14.56 @@ -691,7 +687,7 @@ 14.57 14.58 static void verifyClear(CxList *list) { 14.59 cxListClear(list); 14.60 - EXPECT_EQ(0, list->size); 14.61 + EXPECT_EQ(0, cxListSize(list)); 14.62 } 14.63 14.64 static unsigned destr_test_ctr; 14.65 @@ -717,33 +713,33 @@ 14.66 cxListRemove(list, 15); 14.67 EXPECT_EQ(1, destr_test_ctr); 14.68 EXPECT_EQ(testdata.data[15], destr_last_value + off); 14.69 - EXPECT_EQ(testdata_len - destr_test_ctr, list->size); 14.70 + EXPECT_EQ(testdata_len - destr_test_ctr, cxListSize(list)); 14.71 cxListRemove(list, 47); 14.72 EXPECT_EQ(2, destr_test_ctr); 14.73 EXPECT_EQ(testdata.data[48], destr_last_value + off); 14.74 - EXPECT_EQ(testdata_len - destr_test_ctr, list->size); 14.75 + EXPECT_EQ(testdata_len - destr_test_ctr, cxListSize(list)); 14.76 14.77 auto iter = cxListMutIteratorAt(list, 7); 14.78 cxIteratorNext(iter); 14.79 EXPECT_EQ(2, destr_test_ctr); 14.80 EXPECT_EQ(testdata.data[48], destr_last_value + off); 14.81 - EXPECT_EQ(testdata_len - destr_test_ctr, list->size); 14.82 + EXPECT_EQ(testdata_len - destr_test_ctr, cxListSize(list)); 14.83 cxIteratorFlagRemoval(iter); 14.84 cxIteratorNext(iter); 14.85 EXPECT_EQ(3, destr_test_ctr); 14.86 EXPECT_EQ(testdata.data[8], destr_last_value + off); 14.87 - EXPECT_EQ(testdata_len - destr_test_ctr, list->size); 14.88 + EXPECT_EQ(testdata_len - destr_test_ctr, cxListSize(list)); 14.89 14.90 iter = cxListMutBackwardsIteratorAt(list, 5); 14.91 cxIteratorNext(iter); 14.92 EXPECT_EQ(3, destr_test_ctr); 14.93 EXPECT_EQ(testdata.data[8], destr_last_value + off); 14.94 - EXPECT_EQ(testdata_len - destr_test_ctr, list->size); 14.95 + EXPECT_EQ(testdata_len - destr_test_ctr, cxListSize(list)); 14.96 cxIteratorFlagRemoval(iter); 14.97 cxIteratorNext(iter); 14.98 EXPECT_EQ(4, destr_test_ctr); 14.99 EXPECT_EQ(testdata.data[4], destr_last_value + off); 14.100 - EXPECT_EQ(testdata_len - destr_test_ctr, list->size); 14.101 + EXPECT_EQ(testdata_len - destr_test_ctr, cxListSize(list)); 14.102 14.103 cxListClear(list); 14.104 EXPECT_EQ(testdata_len, destr_test_ctr); 14.105 @@ -754,20 +750,18 @@ 14.106 14.107 void verifySimpleDestructor(CxList *list) { 14.108 destr_test_ctr = 0; 14.109 - list->content_destructor_type = CX_DESTRUCTOR_SIMPLE; 14.110 list->simple_destructor = simple_destr_test_fun; 14.111 verifyAnyDestructor(list); 14.112 } 14.113 14.114 void verifyAdvancedDestructor(CxList *list) { 14.115 destr_test_ctr = 0; 14.116 - list->content_destructor_type = CX_DESTRUCTOR_ADVANCED; 14.117 - list->advanced_destructor.func = advanced_destr_test_fun; 14.118 + list->advanced_destructor = advanced_destr_test_fun; 14.119 verifyAnyDestructor(list); 14.120 } 14.121 14.122 static void verifySwap(CxList *list) { 14.123 - ASSERT_EQ(list->size, 0); 14.124 + ASSERT_EQ(cxListSize(list), 0); 14.125 14.126 int original[16] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15}; 14.127 int swapped[16] = {8, 4, 14, 3, 1, 5, 9, 12, 0, 6, 11, 10, 7, 15, 2, 13}; 14.128 @@ -816,11 +810,11 @@ 14.129 14.130 void verifyAt(CxList *list) const { 14.131 auto len = testdata_len; 14.132 - EXPECT_EQ(list->size, len); 14.133 + EXPECT_EQ(cxListSize(list), len); 14.134 cx_for_n (i, len) { 14.135 EXPECT_EQ(*(int *) cxListAt(list, i), testdata.data[i]); 14.136 } 14.137 - EXPECT_EQ(cxListAt(list, list->size), nullptr); 14.138 + EXPECT_EQ(cxListAt(list, cxListSize(list)), nullptr); 14.139 } 14.140 14.141 void verifyFind(CxList *list) const { 14.142 @@ -838,7 +832,7 @@ 14.143 } 14.144 14.145 int notinlist = -1; 14.146 - EXPECT_EQ(list->size, cxListFind(list, ¬inlist)); 14.147 + EXPECT_EQ(cxListSize(list), cxListFind(list, ¬inlist)); 14.148 } 14.149 14.150 void verifySort(CxList *list) const { 14.151 @@ -856,7 +850,7 @@ 14.152 EXPECT_EQ(*x, testdata.data[iter.index]); 14.153 i++; 14.154 } 14.155 - ASSERT_EQ(i, list->size); 14.156 + ASSERT_EQ(i, cxListSize(list)); 14.157 iter = cxListBackwardsIterator(list); 14.158 cx_foreach(int*, x, iter) { 14.159 ASSERT_EQ(i - 1, iter.index); 14.160 @@ -887,7 +881,7 @@ 14.161 j++; 14.162 } 14.163 ASSERT_EQ(i, 0); 14.164 - ASSERT_EQ(list->size, len / 2); 14.165 + ASSERT_EQ(cxListSize(list), len / 2); 14.166 cx_for_n(j, len / 2) ASSERT_EQ(*(int *) cxListAt(list, j), testdata.data[j * 2]); 14.167 } 14.168 14.169 @@ -912,11 +906,11 @@ 14.170 EXPECT_TRUE(cxIteratorValid(iter)); 14.171 EXPECT_EQ(iter.index, 1); 14.172 EXPECT_EQ(*(int *) cxIteratorCurrent(iter), 0); 14.173 - iter = cxListMutIteratorAt(list, list->size); 14.174 + iter = cxListMutIteratorAt(list, cxListSize(list)); 14.175 cxListInsertBefore(&iter, &newdata[3]); 14.176 EXPECT_FALSE(cxIteratorValid(iter)); 14.177 EXPECT_EQ(iter.index, 9); 14.178 - iter = cxListMutIteratorAt(list, list->size); 14.179 + iter = cxListMutIteratorAt(list, cxListSize(list)); 14.180 cxListInsertAfter(&iter, &newdata[4]); 14.181 EXPECT_FALSE(cxIteratorValid(iter)); 14.182 EXPECT_EQ(iter.index, 10); 14.183 @@ -939,16 +933,16 @@ 14.184 EXPECT_EQ(cxListCompare(left, right), 0); 14.185 int x = 42; 14.186 cxListAdd(left, &x); 14.187 - ASSERT_GT(left->size, right->size); 14.188 + ASSERT_GT(cxListSize(left), cxListSize(right)); 14.189 EXPECT_GT(cxListCompare(left, right), 0); 14.190 EXPECT_LT(cxListCompare(right, left), 0); 14.191 cxListAdd(right, &x); 14.192 - ASSERT_EQ(left->size, right->size); 14.193 + ASSERT_EQ(cxListSize(left), cxListSize(right)); 14.194 EXPECT_EQ(cxListCompare(left, right), 0); 14.195 int a = 5, b = 10; 14.196 cxListInsert(left, 15, &a); 14.197 cxListInsert(right, 15, &b); 14.198 - ASSERT_EQ(left->size, right->size); 14.199 + ASSERT_EQ(cxListSize(left), cxListSize(right)); 14.200 EXPECT_LT(cxListCompare(left, right), 0); 14.201 EXPECT_GT(cxListCompare(right, left), 0); 14.202 *(int *) cxListAt(left, 15) = 10; 14.203 @@ -972,7 +966,7 @@ 14.204 auto list = autofree(cxLinkedListCreate(&testingAllocator, cx_cmp_int, 47)); 14.205 EXPECT_FALSE(cxListIsStoringPointers(list)); 14.206 cxListStorePointers(list); 14.207 - EXPECT_EQ(list->itemsize, sizeof(void *)); 14.208 + EXPECT_EQ(list->item_size, sizeof(void *)); 14.209 EXPECT_NE(list->cl, nullptr); 14.210 EXPECT_NE(list->climpl, nullptr); 14.211 EXPECT_TRUE(cxListIsStoringPointers(list)); 14.212 @@ -985,10 +979,11 @@ 14.213 TEST_F(LinkedList, cxLinkedListCreate) { 14.214 CxList *list = autofree(cxLinkedListCreate(&testingAllocator, cx_cmp_int, sizeof(int))); 14.215 ASSERT_NE(list, nullptr); 14.216 - EXPECT_EQ(list->itemsize, sizeof(int)); 14.217 - EXPECT_EQ(list->capacity, (size_t) -1); 14.218 - EXPECT_EQ(list->content_destructor_type, CX_DESTRUCTOR_NONE); 14.219 - EXPECT_EQ(list->size, 0); 14.220 + EXPECT_EQ(list->item_size, sizeof(int)); 14.221 + EXPECT_EQ(list->simple_destructor, nullptr); 14.222 + EXPECT_EQ(list->advanced_destructor, nullptr); 14.223 + EXPECT_EQ(list->destructor_data, nullptr); 14.224 + EXPECT_EQ(cxListSize(list), 0); 14.225 EXPECT_EQ(list->allocator, &testingAllocator); 14.226 EXPECT_EQ(list->cmpfunc, cx_cmp_int); 14.227 EXPECT_FALSE(cxListIsStoringPointers(list)); 14.228 @@ -997,30 +992,37 @@ 14.229 TEST_F(LinkedList, cxLinkedListCreateSimple) { 14.230 CxList *list = autofree(cxLinkedListCreateSimple(sizeof(int))); 14.231 ASSERT_NE(list, nullptr); 14.232 - EXPECT_EQ(list->itemsize, sizeof(int)); 14.233 - EXPECT_EQ(list->capacity, (size_t) -1); 14.234 + EXPECT_EQ(list->item_size, sizeof(int)); 14.235 EXPECT_EQ(list->cmpfunc, nullptr); 14.236 EXPECT_EQ(list->allocator, cxDefaultAllocator); 14.237 + EXPECT_EQ(list->simple_destructor, nullptr); 14.238 + EXPECT_EQ(list->advanced_destructor, nullptr); 14.239 + EXPECT_EQ(list->destructor_data, nullptr); 14.240 + EXPECT_EQ(cxListSize(list), 0); 14.241 EXPECT_FALSE(cxListIsStoringPointers(list)); 14.242 } 14.243 14.244 TEST_F(LinkedList, cxLinkedListCreateSimpleForPointers) { 14.245 CxList *list = autofree(cxLinkedListCreateSimple(CX_STORE_POINTERS)); 14.246 ASSERT_NE(list, nullptr); 14.247 - EXPECT_EQ(list->itemsize, sizeof(void *)); 14.248 - EXPECT_EQ(list->capacity, (size_t) -1); 14.249 + EXPECT_EQ(list->item_size, sizeof(void *)); 14.250 EXPECT_EQ(list->cmpfunc, nullptr); 14.251 EXPECT_EQ(list->allocator, cxDefaultAllocator); 14.252 + EXPECT_EQ(list->simple_destructor, nullptr); 14.253 + EXPECT_EQ(list->advanced_destructor, nullptr); 14.254 + EXPECT_EQ(list->destructor_data, nullptr); 14.255 + EXPECT_EQ(cxListSize(list), 0); 14.256 EXPECT_TRUE(cxListIsStoringPointers(list)); 14.257 } 14.258 14.259 TEST_F(ArrayList, cxArrayListCreate) { 14.260 CxList *list = autofree(cxArrayListCreate(&testingAllocator, cx_cmp_int, sizeof(int), 8)); 14.261 ASSERT_NE(list, nullptr); 14.262 - EXPECT_EQ(list->itemsize, sizeof(int)); 14.263 - EXPECT_EQ(list->capacity, 8); 14.264 - EXPECT_EQ(list->content_destructor_type, CX_DESTRUCTOR_NONE); 14.265 - EXPECT_EQ(list->size, 0); 14.266 + EXPECT_EQ(list->item_size, sizeof(int)); 14.267 + EXPECT_EQ(list->simple_destructor, nullptr); 14.268 + EXPECT_EQ(list->advanced_destructor, nullptr); 14.269 + EXPECT_EQ(list->destructor_data, nullptr); 14.270 + EXPECT_EQ(cxListSize(list), 0); 14.271 EXPECT_EQ(list->allocator, &testingAllocator); 14.272 EXPECT_EQ(list->cmpfunc, cx_cmp_int); 14.273 EXPECT_FALSE(cxListIsStoringPointers(list)); 14.274 @@ -1031,8 +1033,11 @@ 14.275 ASSERT_NE(list, nullptr); 14.276 EXPECT_EQ(list->cmpfunc, nullptr); 14.277 EXPECT_EQ(list->allocator, cxDefaultAllocator); 14.278 - EXPECT_EQ(list->itemsize, sizeof(int)); 14.279 - EXPECT_EQ(list->capacity, 8); 14.280 + EXPECT_EQ(list->item_size, sizeof(int)); 14.281 + EXPECT_EQ(list->simple_destructor, nullptr); 14.282 + EXPECT_EQ(list->advanced_destructor, nullptr); 14.283 + EXPECT_EQ(list->destructor_data, nullptr); 14.284 + EXPECT_EQ(cxListSize(list), 0); 14.285 EXPECT_FALSE(cxListIsStoringPointers(list)); 14.286 } 14.287 14.288 @@ -1041,8 +1046,7 @@ 14.289 ASSERT_NE(list, nullptr); 14.290 EXPECT_EQ(list->cmpfunc, nullptr); 14.291 EXPECT_EQ(list->allocator, cxDefaultAllocator); 14.292 - EXPECT_EQ(list->itemsize, sizeof(void *)); 14.293 - EXPECT_EQ(list->capacity, 8); 14.294 + EXPECT_EQ(list->item_size, sizeof(void *)); 14.295 EXPECT_TRUE(cxListIsStoringPointers(list)); 14.296 } 14.297 14.298 @@ -1313,7 +1317,6 @@ 14.299 TEST_F(PointerLinkedList, DestroySimpleDestructor) { 14.300 int item = 0; 14.301 auto list = cxLinkedListCreate(cxDefaultAllocator, cx_cmp_int, CX_STORE_POINTERS); 14.302 - list->content_destructor_type = CX_DESTRUCTOR_SIMPLE; 14.303 list->simple_destructor = [](void *elem) { *(int *) elem = 42; }; 14.304 cxListAdd(list, &item); 14.305 cxListDestroy(list); 14.306 @@ -1323,9 +1326,8 @@ 14.307 TEST_F(PointerLinkedList, DestroyAdvancedDestructor) { 14.308 void *item = cxMalloc(&testingAllocator, sizeof(int)); 14.309 auto list = cxLinkedListCreate(cxDefaultAllocator, cx_cmp_int, CX_STORE_POINTERS); 14.310 - list->content_destructor_type = CX_DESTRUCTOR_ADVANCED; 14.311 - list->advanced_destructor.data = &testingAllocator; 14.312 - list->advanced_destructor.func = (cx_destructor_func2) cxFree; 14.313 + list->destructor_data = &testingAllocator; 14.314 + list->advanced_destructor = (cx_destructor_func2) cxFree; 14.315 cxListAdd(list, item); 14.316 ASSERT_FALSE(testingAllocator.verify()); 14.317 cxListDestroy(list);
15.1 --- a/tests/test_map.cpp Fri Apr 07 11:30:28 2023 +0200 15.2 +++ b/tests/test_map.cpp Sun Apr 09 19:03:58 2023 +0200 15.3 @@ -121,13 +121,13 @@ 15.4 cx_for_n(i, hmap->bucket_count) { 15.5 EXPECT_EQ(hmap->buckets[i], nullptr); 15.6 } 15.7 - EXPECT_EQ(map->itemsize, 1); 15.8 + EXPECT_EQ(map->item_size, 1); 15.9 EXPECT_EQ(map->size, 0); 15.10 EXPECT_EQ(map->allocator, &allocator); 15.11 EXPECT_FALSE(map->store_pointers); 15.12 cxMapStorePointers(map); 15.13 EXPECT_TRUE(map->store_pointers); 15.14 - EXPECT_EQ(map->itemsize, sizeof(void *)); 15.15 + EXPECT_EQ(map->item_size, sizeof(void *)); 15.16 cxMapStoreObjects(map); 15.17 EXPECT_FALSE(map->store_pointers); 15.18 15.19 @@ -146,7 +146,7 @@ 15.20 EXPECT_EQ(map->size, 0); 15.21 EXPECT_EQ(map->allocator, &allocator); 15.22 EXPECT_TRUE(map->store_pointers); 15.23 - EXPECT_EQ(map->itemsize, sizeof(void *)); 15.24 + EXPECT_EQ(map->item_size, sizeof(void *)); 15.25 15.26 cxMapDestroy(map); 15.27 EXPECT_TRUE(allocator.verify());