63 lines
1.6 KiB
C
63 lines
1.6 KiB
C
// Special thanks to https://bytesbeneath.com/p/dynamic-arrays-in-c
|
|
#include "dyn_arr.h"
|
|
#include <stdint.h>
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
|
|
#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;
|
|
}
|