// Special thanks to https://bytesbeneath.com/p/dynamic-arrays-in-c #include "dyn_arr.h" #include #include #include #include #define ARRAY_GROWTH_MULTIPLIER 1.3 #define ARRAY_SHRINK_TRIGGER 2 void *dyn_arr_init(size_t item_size, size_t capacity) { void *dyna_ptr = NULL; size_t size = item_size * capacity + sizeof(dyna_header); dyna_header *header = malloc(size); if (header) { header->item_size = item_size; header->capacity = capacity; header->length = 0; dyna_ptr = header + 1; } return dyna_ptr; } void *dyna_ensure_capacity(void *array, int64_t item_count) { size_t item_size = dyna_item_size(array); dyna_header *header = dyna_get_header(array); size_t minimum_capacity = header->length + item_count; size_t maximum_capacity = (header->length + item_count) * ARRAY_SHRINK_TRIGGER; // Return if capacity is in acceptable range. if (header->capacity > minimum_capacity && header->capacity < maximum_capacity) { return header + 1; } size_t new_capacity = minimum_capacity * ARRAY_GROWTH_MULTIPLIER; // Return if the array is valid and so small it's not worth reallocating if (header->capacity > minimum_capacity && new_capacity <= ARRAY_INITIAL_CAPACITY) { return header + 1; } size_t new_size = sizeof(dyna_header) + new_capacity * item_size; header = realloc(header, new_size); header->capacity = new_capacity; return header + 1; } void dyna_deinit(void *array) { free(dyna_get_header(array)); array = NULL; } bool dyna_empty(void *array) { if (dyna_length(array) == 0) { return true; } return false; }