dynamic-array/src/dyn_arr.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;
}