93 */ |
93 */ |
94 #define cx_array_initialize(array, capacity) \ |
94 #define cx_array_initialize(array, capacity) \ |
95 array##_capacity = capacity; \ |
95 array##_capacity = capacity; \ |
96 array##_size = 0; \ |
96 array##_size = 0; \ |
97 array = malloc(sizeof(array[0]) * capacity) |
97 array = malloc(sizeof(array[0]) * capacity) |
|
98 |
|
99 /** |
|
100 * Initializes an array declared with CX_ARRAY_DECLARE(). |
|
101 * |
|
102 * The memory for the array is allocated with the specified allocator. |
|
103 * @param allocator the allocator |
|
104 * @param array the array |
|
105 * @param capacity the initial capacity |
|
106 */ |
|
107 #define cx_array_initialize_a(allocator, array, capacity) \ |
|
108 array##_capacity = capacity; \ |
|
109 array##_size = 0; \ |
|
110 array = cxMalloc(allocator, sizeof(array[0]) * capacity) |
98 |
111 |
99 /** |
112 /** |
100 * Defines a reallocation mechanism for arrays. |
113 * Defines a reallocation mechanism for arrays. |
101 */ |
114 */ |
102 struct cx_array_reallocator_s { |
115 struct cx_array_reallocator_s { |
172 const struct cx_allocator_s *allocator, |
185 const struct cx_allocator_s *allocator, |
173 const void *stackmem |
186 const void *stackmem |
174 ); |
187 ); |
175 |
188 |
176 /** |
189 /** |
|
190 * Reserves memory for additional elements. |
|
191 * |
|
192 * This function checks if the \p capacity of the array is sufficient to hold |
|
193 * at least \p size plus \p elem_count elements. If not, a reallocation is |
|
194 * performed with the specified \p reallocator. |
|
195 * |
|
196 * This function can be useful to replace subsequent calls to cx_array_copy() |
|
197 * with one single cx_array_reserve() and then - after guaranteeing a |
|
198 * sufficient capacity - use simple memmove() or memcpy(). |
|
199 * |
|
200 * The \p width refers to the size and capacity. Both must have the same width. |
|
201 * Supported are 0, 8, 16, and 32, as well as 64 if running on a 64 bit |
|
202 * architecture. If set to zero, the native word width is used. |
|
203 * |
|
204 * @param array a pointer to the target array |
|
205 * @param size a pointer to the size of the array |
|
206 * @param capacity a pointer to the capacity of the array |
|
207 * @param width the width in bytes for the \p size and \p capacity or zero for default |
|
208 * @param elem_size the size of one element |
|
209 * @param elem_count the number of expected additional elements |
|
210 * @param reallocator the array reallocator to use |
|
211 * @return zero on success, non-zero on failure |
|
212 */ |
|
213 cx_attr_nonnull |
|
214 int cx_array_reserve( |
|
215 void **array, |
|
216 void *size, |
|
217 void *capacity, |
|
218 unsigned width, |
|
219 size_t elem_size, |
|
220 size_t elem_count, |
|
221 struct cx_array_reallocator_s *reallocator |
|
222 ); |
|
223 |
|
224 /** |
177 * Copies elements from one array to another. |
225 * Copies elements from one array to another. |
178 * |
226 * |
179 * The elements are copied to the \p target array at the specified \p index, |
227 * The elements are copied to the \p target array at the specified \p index, |
180 * overwriting possible elements. The \p index does not need to be in range of |
228 * overwriting possible elements. The \p index does not need to be in range of |
181 * the current array \p size. If the new index plus the number of elements added |
229 * the current array \p size. If the new index plus the number of elements added |
212 struct cx_array_reallocator_s *reallocator |
260 struct cx_array_reallocator_s *reallocator |
213 ); |
261 ); |
214 |
262 |
215 /** |
263 /** |
216 * Convenience macro that uses cx_array_copy() with a default layout and |
264 * Convenience macro that uses cx_array_copy() with a default layout and |
217 * the default reallocator. |
265 * the specified reallocator. |
218 * |
266 * |
|
267 * @param reallocator the array reallocator to use |
219 * @param array the name of the array (NOT a pointer to the array) |
268 * @param array the name of the array (NOT a pointer to the array) |
220 * @param index the index where the copied elements shall be placed |
269 * @param index the index where the copied elements shall be placed |
221 * @param src the source array |
270 * @param src the source array |
222 * @param count the number of elements to copy |
271 * @param count the number of elements to copy |
223 * @return zero on success, non-zero on failure |
272 * @return zero on success, non-zero on failure |
224 * @see CX_ARRAY_DECLARE() |
273 * @see CX_ARRAY_DECLARE() |
|
274 * @see cx_array_simple_copy() |
|
275 */ |
|
276 #define cx_array_simple_copy_a(reallocator, array, index, src, count) \ |
|
277 cx_array_copy((void**)&(array), &(array##_size), &(array##_capacity), \ |
|
278 8*sizeof(array##_size), index, src, sizeof((array)[0]), count, \ |
|
279 reallocator) |
|
280 |
|
281 /** |
|
282 * Convenience macro that uses cx_array_copy() with a default layout and |
|
283 * the default reallocator. |
|
284 * |
|
285 * @param array the name of the array (NOT a pointer to the array) |
|
286 * @param index the index where the copied elements shall be placed |
|
287 * @param src the source array |
|
288 * @param count the number of elements to copy |
|
289 * @return zero on success, non-zero on failure |
|
290 * @see CX_ARRAY_DECLARE() |
|
291 * @see cx_array_simple_copy_a() |
225 */ |
292 */ |
226 #define cx_array_simple_copy(array, index, src, count) \ |
293 #define cx_array_simple_copy(array, index, src, count) \ |
227 cx_array_copy((void**)&(array), &(array##_size), &(array##_capacity), \ |
294 cx_array_simple_copy_a(cx_array_default_reallocator, \ |
228 8*sizeof(array##_size), index, src, sizeof((array)[0]), count, \ |
295 array, index, src, count) |
229 cx_array_default_reallocator) |
296 |
|
297 /** |
|
298 * Convenience macro that uses cx_array_reserve() with a default layout and |
|
299 * the specified reallocator. |
|
300 * |
|
301 * @param reallocator the array reallocator to use |
|
302 * @param array the name of the array (NOT a pointer to the array) |
|
303 * @param count the number of expected additional elements |
|
304 * @return zero on success, non-zero on failure |
|
305 * @see CX_ARRAY_DECLARE() |
|
306 * @see cx_array_simple_reserve() |
|
307 */ |
|
308 #define cx_array_simple_reserve_a(reallocator, array, count) \ |
|
309 cx_array_reserve((void**)&(array), &(array##_size), &(array##_capacity), \ |
|
310 8*sizeof(array##_size), sizeof((array)[0]), count, \ |
|
311 reallocator) |
|
312 |
|
313 /** |
|
314 * Convenience macro that uses cx_array_reserve() with a default layout and |
|
315 * the default reallocator. |
|
316 * |
|
317 * @param array the name of the array (NOT a pointer to the array) |
|
318 * @param count the number of expected additional elements |
|
319 * @return zero on success, non-zero on failure |
|
320 * @see CX_ARRAY_DECLARE() |
|
321 * @see cx_array_simple_reserve_a() |
|
322 */ |
|
323 #define cx_array_simple_reserve(array, count) \ |
|
324 cx_array_simple_reserve_a(cx_array_default_reallocator, \ |
|
325 array, count) |
230 |
326 |
231 /** |
327 /** |
232 * Adds an element to an array with the possibility of allocating more space. |
328 * Adds an element to an array with the possibility of allocating more space. |
233 * |
329 * |
234 * The element \p elem is added to the end of the \p target array which contains |
330 * The element \p elem is added to the end of the \p target array which contains |
250 cx_array_copy((void**)(target), size, capacity, 8*sizeof(*(size)), \ |
346 cx_array_copy((void**)(target), size, capacity, 8*sizeof(*(size)), \ |
251 *(size), elem, elem_size, 1, reallocator) |
347 *(size), elem, elem_size, 1, reallocator) |
252 |
348 |
253 /** |
349 /** |
254 * Convenience macro that uses cx_array_add() with a default layout and |
350 * Convenience macro that uses cx_array_add() with a default layout and |
|
351 * the specified reallocator. |
|
352 * |
|
353 * @param reallocator the array reallocator to use |
|
354 * @param array the name of the array (NOT a pointer to the array) |
|
355 * @param elem the element to add (NOT a pointer, address is automatically taken) |
|
356 * @return zero on success, non-zero on failure |
|
357 * @see CX_ARRAY_DECLARE() |
|
358 * @see cx_array_simple_add() |
|
359 */ |
|
360 #define cx_array_simple_add_a(reallocator, array, elem) \ |
|
361 cx_array_simple_copy_a(reallocator, array, array##_size, &(elem), 1) |
|
362 |
|
363 /** |
|
364 * Convenience macro that uses cx_array_add() with a default layout and |
255 * the default reallocator. |
365 * the default reallocator. |
256 * |
366 * |
257 * @param array the name of the array (NOT a pointer to the array) |
367 * @param array the name of the array (NOT a pointer to the array) |
258 * @param elem the element to add (NOT a pointer, address is automatically taken) |
368 * @param elem the element to add (NOT a pointer, address is automatically taken) |
259 * @return zero on success, non-zero on failure |
369 * @return zero on success, non-zero on failure |
260 * @see CX_ARRAY_DECLARE() |
370 * @see CX_ARRAY_DECLARE() |
|
371 * @see cx_array_simple_add_a() |
261 */ |
372 */ |
262 #define cx_array_simple_add(array, elem) \ |
373 #define cx_array_simple_add(array, elem) \ |
263 cx_array_simple_copy(array, array##_size, &(elem), 1) |
374 cx_array_simple_add_a(cx_array_default_reallocator, array, elem) |
264 |
|
265 |
375 |
266 /** |
376 /** |
267 * Inserts a sorted array into another sorted array. |
377 * Inserts a sorted array into another sorted array. |
268 * |
378 * |
269 * If either the target or the source array is not already sorted with respect |
379 * If either the target or the source array is not already sorted with respect |