dynamic-array/src/dyn_arr.c

74 lines
1.9 KiB
C

// Special thanks to https://bytesbeneath.com/p/dynamic-arrays-in-c
#include "dyn_arr.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define ARRAY_GROWTH_MULTIPLIER 1.3
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->capacity = capacity;
header->length = 0;
dyna_ptr = header + 1;
}
return dyna_ptr;
}
void *dyna_ensure_capacity(void *array, size_t item_count, size_t item_size) {
dyna_header *header = dyna_get_header(array);
size_t minimum_capacity = header->length + item_count;
if (header->capacity > minimum_capacity) {
return header + 1;
}
size_t new_capacity = header->capacity * ARRAY_GROWTH_MULTIPLIER;
while (new_capacity < minimum_capacity) {
new_capacity *= ARRAY_GROWTH_MULTIPLIER;
}
size_t new_size = sizeof(dyna_header) + new_capacity * item_size;
header = realloc(header, new_size);
header->capacity = new_capacity;
return header + 1;
}
void dyn_arr_pop(void *array, size_t item_size) {
if (dyna_empty(array)) {
return;
}
dyna_length(array)--;
// Shrink if smaller than growth factor, may break if growth factor is > 2
if (dyna_length(array) >
(2 - ARRAY_GROWTH_MULTIPLIER) * dyna_capacity(array)) {
return;
}
size_t new_capacity = dyna_length(array) * ARRAY_GROWTH_MULTIPLIER;
dyna_capacity(array) = new_capacity;
size_t new_size = sizeof(dyna_header) + new_capacity * item_size;
dyna_header *header = dyna_get_header(array);
header = realloc(dyna_get_header(array), new_size);
}
void dyna_deinit(void *array) {
dyna_header *header = dyna_get_header(array);
header = NULL;
free(dyna_get_header(array));
}
bool dyna_empty(void *array) {
if (dyna_length(array) == 0) {
return true;
}
return false;
}