271 Since low-level array lists are just plain arrays, there is no need for such many low-level functions as for linked |
271 Since low-level array lists are just plain arrays, there is no need for such many low-level functions as for linked |
272 lists. |
272 lists. |
273 However, there is one extremely powerful function that can be used for several complex tasks: `cx_array_copy`. |
273 However, there is one extremely powerful function that can be used for several complex tasks: `cx_array_copy`. |
274 The full signature is shown below: |
274 The full signature is shown below: |
275 ```c |
275 ```c |
276 enum cx_array_result cx_array_copy( |
276 int cx_array_copy( |
277 void **target, |
277 void **target, |
278 size_t *size, |
278 void *size, |
279 size_t *capacity, // optional |
279 void *capacity, |
|
280 unsigned width, |
280 size_t index, |
281 size_t index, |
281 const void *src, |
282 const void *src, |
282 size_t elem_size, |
283 size_t elem_size, |
283 size_t elem_count, |
284 size_t elem_count, |
284 struct cx_array_reallocator_s *reallocator // optional |
285 struct cx_array_reallocator_s *reallocator |
285 ); |
286 ); |
286 ``` |
287 ``` |
287 The `target` argument is a pointer to the target array pointer. |
288 The `target` argument is a pointer to the target array pointer. |
288 The reason for this additional indirection is that - given that you provide a `reallocator` - this function writes |
289 The reason for this additional indirection is that this function writes |
289 back the pointer to the possibly reallocated array. |
290 back the pointer to the possibly reallocated array. |
290 The next two arguments are pointers to the `size` and `capacity` of the target array. |
291 The next two arguments are pointers to the `size` and `capacity` of the target array for which the width |
291 Tracking the capacity is optional. |
292 (in bits) is specified in the `width` argument. |
292 If you do not specify a pointer for the capacity, automatic reallocation of the array is entirely disabled (i.e. it |
|
293 does not make sense to specify a `reallocator` then). |
|
294 In this case, the function cannot copy more than `size-index` elements and if you try, it will return |
|
295 `CX_ARRAY_REALLOC_NOT_SUPPORTED` and do nothing. |
|
296 |
293 |
297 On a successful invocation, the function copies `elem_count` number of elements, each of size `elem_size` from |
294 On a successful invocation, the function copies `elem_count` number of elements, each of size `elem_size` from |
298 `src` to `*target` and uses the `reallocator` to extend the array when necessary. |
295 `src` to `*target` and uses the `reallocator` to extend the array when necessary. |
299 Finally, the size, capacity, and the pointer to the array are all updated and the function returns |
296 Finally, the size, capacity, and the pointer to the array are all updated and the function returns zero. |
300 `CX_ARRAY_SUCCESS`. |
|
301 |
|
302 The third, but extremely rare, return code is `CX_ARRAY_REALLOC_FAILED` and speaks for itself. |
|
303 |
297 |
304 A few things to note: |
298 A few things to note: |
305 * `*target` and `src` can point to the same memory region, effectively copying elements within the array with `memmove` |
299 * `*target` and `src` can point to the same memory region, effectively copying elements within the array with `memmove` |
306 * `*target` does not need to point to the start of the array, but `size` and `capacity` always start counting from the |
300 * `*target` does not need to point to the start of the array, but `size` and `capacity` always start counting from the |
307 position, `*target` points to - in this scenario, specifying a `reallocator` is forbidden for obvious reasons |
301 position, `*target` points to - in this scenario, the need for reallocation must be avoided for obvious reasons |
308 * `index` does not need to be within size of the current array, if `capacity` is specified |
302 * `index` does not need to be within size of the current array |
309 * `index` does not even need to be within the capacity of the array, if `reallocator` is specified |
303 * `index` does not even need to be within the capacity of the array |
|
304 * `width` must be one of 8, 16, 32, 64 (only on 64-bit systems), or zero (in which case the native word width is used) |
310 |
305 |
311 If you just want to add one single element to an existing array, you can use the macro `cx_array_add()`. |
306 If you just want to add one single element to an existing array, you can use the macro `cx_array_add()`. |
312 In that case, since the element is added to the end of the array, the `capacity` argument is mandatory. |
|
313 You can use `CX_ARRAY_DECLARE()` to declare the necessary fields within a structure and then use the |
307 You can use `CX_ARRAY_DECLARE()` to declare the necessary fields within a structure and then use the |
314 `cx_array_simple_*()` convenience macros to reduce code overhead. |
308 `cx_array_simple_*()` convenience macros to reduce code overhead. |
|
309 The convenience macros automatically determine the width of the size/capacity variables. |
315 |
310 |
316 ## Map |
311 ## Map |
317 |
312 |
318 *Header file:* [map.h](api/map_8h.html) |
313 *Header file:* [map.h](api/map_8h.html) |
319 |
314 |