diff -r bb196054f3fd -r 84fc42b04d3b src/array_list.c --- a/src/array_list.c Mon Dec 02 20:58:17 2024 +0100 +++ b/src/array_list.c Thu Dec 05 01:51:47 2024 +0100 @@ -89,6 +89,96 @@ // LOW LEVEL ARRAY LIST FUNCTIONS +int cx_array_reserve( + void **array, + void *size, + void *capacity, + unsigned width, + size_t elem_size, + size_t elem_count, + CxArrayReallocator *reallocator +) { + // assert pointers + assert(array != NULL); + assert(size != NULL); + assert(capacity != NULL); + assert(reallocator != NULL); + + // determine size and capacity + size_t oldcap; + size_t oldsize; + size_t max_size; + if (width == 0 || width == __WORDSIZE) { + oldcap = *(size_t*) capacity; + oldsize = *(size_t*) size; + max_size = SIZE_MAX; + } else if (width == 16) { + oldcap = *(uint16_t*) capacity; + oldsize = *(uint16_t*) size; + max_size = UINT16_MAX; + } else if (width == 8) { + oldcap = *(uint8_t*) capacity; + oldsize = *(uint8_t*) size; + max_size = UINT8_MAX; + } +#if __WORDSIZE == 64 + else if (width == 32) { + oldcap = *(uint32_t*) capacity; + oldsize = *(uint32_t*) size; + max_size = UINT32_MAX; + } +#endif + else { + errno = EINVAL; + return 1; + } + + // assert that the array is allocated when it has capacity + assert(*array != NULL || oldcap == 0); + + // determine new capacity + size_t newcap = oldsize + elem_count; + + // check for overflow + if (newcap > max_size) { + errno = EOVERFLOW; + return 1; + } + + // reallocate if possible + if (newcap > oldcap) { + // calculate new capacity (next number divisible by 16) + newcap = newcap - (newcap % 16) + 16; + + // perform reallocation + void *newmem = reallocator->realloc( + *array, newcap, elem_size, reallocator + ); + if (newmem == NULL) { + return 1; + } + + // store new pointer + *array = newmem; + + // store new capacity + if (width == 0 || width == __WORDSIZE) { + *(size_t*) capacity = newcap; + } else if (width == 16) { + *(uint16_t*) capacity = newcap; + } else if (width == 8) { + *(uint8_t*) capacity = newcap; + } +#if __WORDSIZE == 64 + else if (width == 32) { + *(uint32_t*) capacity = newcap; + } +#endif + } + + return 0; +} + int cx_array_copy( void **target, void *size,