ucx/cx/array_list.h

changeset 818
bc782cca0759
parent 816
839fefbdedc7
equal deleted inserted replaced
817:22257f6d06a3 818:bc782cca0759
29 * \file array_list.h 29 * \file array_list.h
30 * \brief Array list implementation. 30 * \brief Array list implementation.
31 * \details Also provides several low-level functions for custom array list implementations. 31 * \details Also provides several low-level functions for custom array list implementations.
32 * \author Mike Becker 32 * \author Mike Becker
33 * \author Olaf Wintermann 33 * \author Olaf Wintermann
34 * \version 3.0
35 * \copyright 2-Clause BSD License 34 * \copyright 2-Clause BSD License
36 */ 35 */
37 36
38 37
39 #ifndef UCX_ARRAY_LIST_H 38 #ifndef UCX_ARRAY_LIST_H
44 #ifdef __cplusplus 43 #ifdef __cplusplus
45 extern "C" { 44 extern "C" {
46 #endif 45 #endif
47 46
48 /** 47 /**
48 * The maximum item size in an array list that fits into stack buffer when swapped.
49 */
50 extern unsigned cx_array_swap_sbo_size;
51
52 /**
53 * Declares variables for an array that can be used with the convenience macros.
54 *
55 * @see cx_array_simple_add()
56 * @see cx_array_simple_copy()
57 * @see cx_array_initialize()
58 */
59 #define CX_ARRAY_DECLARE(type, name) \
60 type * name; \
61 size_t name##_size; \
62 size_t name##_capacity
63
64 /**
65 * Initializes an array declared with CX_ARRAY_DECLARE().
66 *
67 * The memory for the array is allocated with stdlib malloc().
68 * @param array the array
69 * @param capacity the initial capacity
70 */
71 #define cx_array_initialize(array, capacity) \
72 array##_capacity = capacity; \
73 array##_size = 0; \
74 array = malloc(sizeof(array[0]) * capacity)
75
76 /**
49 * Defines a reallocation mechanism for arrays. 77 * Defines a reallocation mechanism for arrays.
50 */ 78 */
51 struct cx_array_reallocator_s { 79 struct cx_array_reallocator_s {
52 /** 80 /**
53 * Re-allocates space for the given array. 81 * Reallocates space for the given array.
54 * 82 *
55 * Implementations are not required to free the original array. 83 * Implementations are not required to free the original array.
56 * This allows re-allocation of static memory by allocating heap memory 84 * This allows reallocation of static memory by allocating heap memory
57 * and copying the array contents. The information in \p data can keep 85 * and copying the array contents. The information in the custom fields of
58 * track of the state of the memory or other additional allocator info. 86 * the referenced allocator can be used to track the state of the memory
87 * or to transport other additional data.
59 * 88 *
60 * @param array the array to reallocate 89 * @param array the array to reallocate
61 * @param capacity the new capacity (number of elements) 90 * @param capacity the new capacity (number of elements)
62 * @param elem_size the size of each element 91 * @param elem_size the size of each element
63 * @param alloc a reference to this allocator 92 * @param alloc a reference to this allocator
87 */ 116 */
88 size_t int2; 117 size_t int2;
89 }; 118 };
90 119
91 /** 120 /**
92 * Return codes for cx_array_copy(). 121 * A default stdlib-based array reallocator.
93 */ 122 */
94 enum cx_array_copy_result { 123 extern struct cx_array_reallocator_s *cx_array_default_reallocator;
95 CX_ARRAY_COPY_SUCCESS, 124
96 CX_ARRAY_COPY_REALLOC_NOT_SUPPORTED, 125 /**
97 CX_ARRAY_COPY_REALLOC_FAILED, 126 * Return codes for array functions.
127 */
128 enum cx_array_result {
129 CX_ARRAY_SUCCESS,
130 CX_ARRAY_REALLOC_NOT_SUPPORTED,
131 CX_ARRAY_REALLOC_FAILED,
98 }; 132 };
99 133
100 /** 134 /**
101 * Copies elements from one array to another. 135 * Copies elements from one array to another.
102 * 136 *
105 * the current array \p size. If the new index plus the number of elements added 139 * the current array \p size. If the new index plus the number of elements added
106 * would extend the array's size, and \p capacity is not \c NULL, the remaining 140 * would extend the array's size, and \p capacity is not \c NULL, the remaining
107 * capacity is used. 141 * capacity is used.
108 * 142 *
109 * If the capacity is insufficient to hold the new data, a reallocation 143 * If the capacity is insufficient to hold the new data, a reallocation
110 * attempt is made, unless the allocator is set to \c NULL, in which case 144 * attempt is made, unless the \p reallocator is set to \c NULL, in which case
111 * this function ultimately returns a failure. 145 * this function ultimately returns a failure.
112 * 146 *
113 * @param target the target array 147 * @param target a pointer to the target array
114 * @param size a pointer to the size of the target array 148 * @param size a pointer to the size of the target array
115 * @param capacity a pointer to the target array's capacity - 149 * @param capacity a pointer to the target array's capacity -
116 * \c NULL if only the size shall be used to bound the array 150 * \c NULL if only the size shall be used to bound the array
117 * @param index the index where the copied elements shall be placed 151 * @param index the index where the copied elements shall be placed
118 * @param src the source array 152 * @param src the source array
119 * @param elem_size the size of one element 153 * @param elem_size the size of one element
120 * @param elem_count the number of elements to copy 154 * @param elem_count the number of elements to copy
121 * @param reallocator the array re-allocator to use, or \c NULL 155 * @param reallocator the array reallocator to use, or \c NULL
122 * if re-allocation shall not happen 156 * if reallocation shall not happen
123 * @return zero on success, non-zero error code on failure 157 * @return zero on success, non-zero error code on failure
124 */ 158 */
125 enum cx_array_copy_result cx_array_copy( 159 enum cx_array_result cx_array_copy(
126 void **target, 160 void **target,
127 size_t *size, 161 size_t *size,
128 size_t *capacity, 162 size_t *capacity,
129 size_t index, 163 size_t index,
130 void const *src, 164 void const *src,
131 size_t elem_size, 165 size_t elem_size,
132 size_t elem_count, 166 size_t elem_count,
133 struct cx_array_reallocator_s *reallocator 167 struct cx_array_reallocator_s *reallocator
134 ) __attribute__((__nonnull__(1, 2, 5))); 168 ) __attribute__((__nonnull__(1, 2, 5)));
135 169
170 /**
171 * Convenience macro that uses cx_array_copy() with a default layout and the default reallocator.
172 *
173 * @param array the name of the array (NOT a pointer to the array)
174 * @param index the index where the copied elements shall be placed
175 * @param src the source array
176 * @param count the number of elements to copy
177 */
178 #define cx_array_simple_copy(array, index, src, count) \
179 cx_array_copy((void**)&(array), &(array##_size), &(array##_capacity), \
180 index, src, sizeof((array)[0]), count, cx_array_default_reallocator)
181
182 /**
183 * Adds an element to an array with the possibility of allocating more space.
184 *
185 * The element \p elem is added to the end of the \p target array which containing
186 * \p size elements, already. The \p capacity must not be \c NULL and point a
187 * variable holding the current maximum number of elements the array can hold.
188 *
189 * If the capacity is insufficient to hold the new element, and the optional
190 * \p reallocator is not \c NULL, an attempt increase the \p capacity is made
191 * and the new capacity is written back.
192 *
193 * @param target a pointer to the target array
194 * @param size a pointer to the size of the target array
195 * @param capacity a pointer to the target array's capacity - must not be \c NULL
196 * @param elem_size the size of one element
197 * @param elem a pointer to the element to add
198 * @param reallocator the array reallocator to use, or \c NULL if reallocation shall not happen
199 * @return zero on success, non-zero error code on failure
200 */
201 #define cx_array_add(target, size, capacity, elem_size, elem, reallocator) \
202 cx_array_copy((void**)(target), size, capacity, *(size), elem, elem_size, 1, reallocator)
203
204 /**
205 * Convenience macro that uses cx_array_add() with a default layout and the default reallocator.
206 *
207 * @param array the name of the array (NOT a pointer to the array)
208 * @param elem the element to add (NOT a pointer, address is automatically taken)
209 */
210 #define cx_array_simple_add(array, elem) \
211 cx_array_simple_copy(array, array##_size, &(elem), 1)
136 212
137 /** 213 /**
138 * Swaps two array elements. 214 * Swaps two array elements.
139 * 215 *
140 * @param arr the array 216 * @param arr the array
148 size_t idx1, 224 size_t idx1,
149 size_t idx2 225 size_t idx2
150 ) __attribute__((__nonnull__)); 226 ) __attribute__((__nonnull__));
151 227
152 /** 228 /**
153 * Allocates an array list for storing elements with \p item_size bytes each. 229 * Allocates an array list for storing elements with \p elem_size bytes each.
154 * 230 *
155 * If \p item_size is CX_STORE_POINTERS, the created list will be created as if 231 * If \p elem_size is CX_STORE_POINTERS, the created list will be created as if
156 * cxListStorePointers() was called immediately after creation. 232 * cxListStorePointers() was called immediately after creation and the compare
233 * function will be automatically set to cx_cmp_ptr(), if none is given.
157 * 234 *
158 * @param allocator the allocator for allocating the list memory 235 * @param allocator the allocator for allocating the list memory
159 * (if \c NULL the cxDefaultAllocator will be used) 236 * (if \c NULL the cxDefaultAllocator will be used)
160 * @param comparator the comparator for the elements 237 * @param comparator the comparator for the elements
161 * (if \c NULL sort and find functions will not work) 238 * (if \c NULL, and the list is not storing pointers, sort and find
162 * @param item_size the size of each element in bytes 239 * functions will not work)
240 * @param elem_size the size of each element in bytes
163 * @param initial_capacity the initial number of elements the array can store 241 * @param initial_capacity the initial number of elements the array can store
164 * @return the created list 242 * @return the created list
165 */ 243 */
166 CxList *cxArrayListCreate( 244 CxList *cxArrayListCreate(
167 CxAllocator const *allocator, 245 CxAllocator const *allocator,
168 cx_compare_func comparator, 246 cx_compare_func comparator,
169 size_t item_size, 247 size_t elem_size,
170 size_t initial_capacity 248 size_t initial_capacity
171 ); 249 );
172 250
173 /** 251 /**
174 * Allocates an array list for storing elements with \p item_size bytes each. 252 * Allocates an array list for storing elements with \p elem_size bytes each.
175 * 253 *
176 * The list will use the cxDefaultAllocator and \em NO compare function. 254 * The list will use the cxDefaultAllocator and \em NO compare function.
177 * If you want to call functions that need a compare function, you have to 255 * If you want to call functions that need a compare function, you have to
178 * set it immediately after creation or use cxArrayListCreate(). 256 * set it immediately after creation or use cxArrayListCreate().
179 * 257 *
180 * If \p item_size is CX_STORE_POINTERS, the created list will be created as if 258 * If \p elem_size is CX_STORE_POINTERS, the created list will be created as if
181 * cxListStorePointers() was called immediately after creation. 259 * cxListStorePointers() was called immediately after creation and the compare
182 * 260 * function will be automatically set to cx_cmp_ptr().
183 * @param item_size the size of each element in bytes 261 *
262 * @param elem_size the size of each element in bytes
184 * @param initial_capacity the initial number of elements the array can store 263 * @param initial_capacity the initial number of elements the array can store
185 * @return the created list 264 * @return the created list
186 */ 265 */
187 #define cxArrayListCreateSimple(item_size, initial_capacity) \ 266 #define cxArrayListCreateSimple(elem_size, initial_capacity) \
188 cxArrayListCreate(NULL, NULL, item_size, initial_capacity) 267 cxArrayListCreate(NULL, NULL, elem_size, initial_capacity)
189 268
190 #ifdef __cplusplus 269 #ifdef __cplusplus
191 } // extern "C" 270 } // extern "C"
192 #endif 271 #endif
193 272

mercurial