summaryrefslogtreecommitdiff
path: root/source/kit/dynamic_array.c
diff options
context:
space:
mode:
Diffstat (limited to 'source/kit/dynamic_array.c')
-rw-r--r--source/kit/dynamic_array.c81
1 files changed, 81 insertions, 0 deletions
diff --git a/source/kit/dynamic_array.c b/source/kit/dynamic_array.c
new file mode 100644
index 0000000..ede817b
--- /dev/null
+++ b/source/kit/dynamic_array.c
@@ -0,0 +1,81 @@
+#include "dynamic_array.h"
+
+#include <assert.h>
+
+void kit_da_init(kit_da_void_t *array, i64 element_size, i64 size,
+ kit_allocator_t *alloc) {
+ assert(array != NULL);
+ assert(element_size > 0);
+ assert(size >= 0);
+
+ memset(array, 0, sizeof(kit_da_void_t));
+
+ if (size > 0)
+ array->values = kit_alloc_dispatch(alloc, KIT_ALLOCATE,
+ element_size * size, 0, NULL);
+
+ if (array->values != NULL) {
+ array->capacity = size;
+ array->size = size;
+ }
+
+ array->alloc = alloc;
+}
+
+static i64 eval_capacity(i64 current_cap, i64 required_cap) {
+ if (current_cap == 0)
+ return required_cap;
+ i64 cap = current_cap;
+ while (cap < required_cap) cap *= 2;
+ return cap;
+}
+
+void kit_da_resize(kit_da_void_t *array, i64 element_size, i64 size) {
+ assert(array != NULL);
+ assert(element_size > 0);
+ assert(size >= 0);
+
+ if (size <= array->capacity) {
+ array->size = size;
+ } else {
+ i64 capacity = eval_capacity(array->capacity, size);
+
+ void *bytes = kit_alloc_dispatch(
+ array->alloc, KIT_ALLOCATE, element_size * capacity, 0, NULL);
+
+ if (bytes != NULL) {
+ if (array->size > 0)
+ memcpy(bytes, array->values, element_size * array->size);
+ if (array->values != NULL)
+ kit_alloc_dispatch(array->alloc, KIT_DEALLOCATE, 0, 0,
+ array->values);
+ array->capacity = capacity;
+ array->size = size;
+ array->values = bytes;
+ }
+ }
+}
+
+void kit_da_resize_exact(kit_da_void_t *array, i64 element_size,
+ i64 capacity) {
+ assert(array != NULL);
+ assert(element_size > 0);
+ assert(capacity >= 0);
+
+ void *bytes = capacity <= 0
+ ? NULL
+ : kit_alloc_dispatch(array->alloc, KIT_ALLOCATE,
+ element_size * capacity, 0,
+ NULL);
+
+ if (bytes != NULL || capacity == 0) {
+ if (array->size > 0 && capacity > 0)
+ memcpy(bytes, array->values, element_size * array->size);
+ if (array->values != NULL)
+ kit_alloc_dispatch(array->alloc, KIT_DEALLOCATE, 0, 0,
+ array->values);
+ array->capacity = capacity;
+ array->size = capacity;
+ array->values = bytes;
+ }
+}