--- a/docs/Writerside/topics/array_list.h.md Wed Mar 12 18:32:57 2025 +0100 +++ b/docs/Writerside/topics/array_list.h.md Thu Mar 13 11:07:00 2025 +0100 @@ -33,9 +33,59 @@ #define cx_array_initialize_a(allocator, ARRAY, capacity) ``` -<warning> -TODO: document -</warning> +The purpose of the UCX array functions is to keep track of the size and capacity of a plain C array. + +The raw functions do not need this information packed into a structure, but working with independent variables is quite cumbersome. +Therefore, UCX defines several macros that call the raw functions assuming certain variable names. + +This is what the `CX_ARRAY_DECLARE_SIZED()` and `CX_ARRAY_DECLARE()` macros are for. +They take a `type` for the array members, a `name` for the array variable, and a `size_type` for the type of the size and capacity variables (`size_t` by default when you use `CX_ARRAY_DECLARE()`), +and generate three variables named `name`, `name_size`, and `name_capacity`. + +For example, you can abbreviate the following code +```C +struct my_data { + int other_int; + float other_float; + int *my_array; + size_t my_array_size; + size_t my_array_capacity; +} +``` +by substituting the three members for the array with `CX_ARRAY_DECLARE()`. +```C +struct my_data { + int other_int; + float other_float; + CX_ARRAY_DECLARE(int, my_array); +} +``` + +> Using `CX_ARRAY_DECLARE_SIZED()` can save some space when you are using a size type that is _half_ as wide as `sizeof(void*)`. +> On 64-bit architectures, having the possibility to store more than four billion items is rarely necessary, hence using 32-bit integers for size and capacity +> saves eight bytes (assuming proper alignment in your struct). + +Once the array is declared, you can use one of the macros `cx_array_initialize()` or `cx_array_initialize_a()` to allocate memory. +The former uses a stdlib default allocator and the latter allows you to use a specific allocator. +Important to note is, that the `ARRAY` argument expects the variable's _name_. +The macros set `ARRAY_size` to zero, `ARRAY_capacity` to the specified initial capacity, and invoke the allocator's `malloc()` function to allocate the memory. + +Using the example from above, and the UCX [memory pool](mempool.h.md), this could look like this: + +```C +CxMempool *mpool = cxMempoolCreateSimple(128); + +struct my_data data; +cx_array_initialize_a(mpool->allocator, data.my_array, 16); +``` + +> The aforementioned macros make your life simpler, but keep in mind that using them is not mandatory. +> All other macros continue to work perfectly, if you declare and initialize your array manually, as long as you use +> the naming convention to suffix the size variable with `_size` and the capacity variable with `_capacity`. +> Also you can freely decide in which order you want to declare the variables. +> +> For example, when you have multiple arrays in your struct with 8-bit `size_type` (because in your use case you don't expect more than 255 elements), +> it is favorable to group all pointers and then declare the size and capacity variables to avoid padding between the array declarations. ## Array Reallocator @@ -66,7 +116,9 @@ ```C #include <cx/array_list.h> -cx_array_add(target, size, capacity, elem_size, elem, reallocator) +int cx_array_add(void **target, void *size, void *capacity, + size_t elem_size, const void *elem, + CxArrayReallocator *reallocator); #define cx_array_simple_add(ARRAY, elem)