summaryrefslogtreecommitdiff
path: root/src/util
diff options
context:
space:
mode:
authorDaniel Hader <[email protected]>2026-06-14 12:58:14 -0500
committerDaniel Hader <[email protected]>2026-06-14 12:58:14 -0500
commit482ea0261cb9f0def49ce3df542b2a7f811262d1 (patch)
tree3bb961316b2ca856409b9f3b2145036ae9f5d704 /src/util
build and test environment using makefile and basic SDL3 setup
Diffstat (limited to 'src/util')
-rw-r--r--src/util/alloc.h13
-rw-r--r--src/util/vec.c98
-rw-r--r--src/util/vec.h38
3 files changed, 149 insertions, 0 deletions
diff --git a/src/util/alloc.h b/src/util/alloc.h
new file mode 100644
index 0000000..17841e4
--- /dev/null
+++ b/src/util/alloc.h
@@ -0,0 +1,13 @@
+#ifndef LEO_ALLOC_H
+#define LEO_ALLOC_H
+
+#include <stddef.h>
+
+struct LEO_Allocator {
+ void *(*alloc)(size_t size);
+ void *(*realloc)(void *ptr, size_t new_size);
+ void (*free)(void *ptr);
+ void *ctx;
+};
+
+#endif
diff --git a/src/util/vec.c b/src/util/vec.c
new file mode 100644
index 0000000..1a37bef
--- /dev/null
+++ b/src/util/vec.c
@@ -0,0 +1,98 @@
+#include <stddef.h>
+#include <string.h>
+
+#include "vec.h"
+#include "alloc.h"
+
+static enum LEO_Vec_Error LEO_Vec_grow(struct LEO_Vec *vec)
+{
+ size_t new_capacity = vec->capacity
+ * LEO_Vec_GROWTH_FACTOR_NUMER
+ / LEO_Vec_GROWTH_FACTOR_DENOM;
+
+ if (new_capacity <= vec->capacity)
+ return LEO_Vec_TOO_BIG;
+
+ vec->capacity = new_capacity;
+ vec->data = vec->allocator.realloc(vec->data,
+ vec->capacity * vec->item_size);
+
+ if (vec->data == NULL)
+ return LEO_Vec_ALLOCATION_FAILURE;
+
+ return LEO_Vec_OK;
+}
+
+enum LEO_Vec_Error LEO_Vec_init(struct LEO_Vec *vec, size_t item_size,
+ struct LEO_Allocator allocator)
+{
+ if (vec == NULL)
+ return LEO_Vec_NULL_VEC_POINTER;
+ if (item_size == 0)
+ return LEO_Vec_INVALID_ITEM_SIZE;
+
+ vec->allocator = allocator;
+ vec->item_size = item_size;
+ vec->length = 0;
+ vec->capacity = LEO_Vec_DEFAULT_CAPACITY;
+ vec->data = vec->allocator.alloc(vec->capacity * vec->item_size);
+
+ if (!vec->data)
+ return LEO_Vec_ALLOCATION_FAILURE;
+
+ return LEO_Vec_OK;
+}
+
+void LEO_Vec_free(struct LEO_Vec *vec)
+{
+ if (vec == NULL)
+ return;
+
+ vec->allocator.free(vec->data);
+ vec->data = NULL;
+}
+
+enum LEO_Vec_Error LEO_Vec_push(struct LEO_Vec *vec, const void *item)
+{
+ if (vec == NULL)
+ return LEO_Vec_NULL_VEC_POINTER;
+ if (item == NULL)
+ return LEO_Vec_NULL_ITEM_POINTER;
+
+ if (vec->length >= vec->capacity) {
+ enum LEO_Vec_Error result = LEO_Vec_grow(vec);
+ if (result != LEO_Vec_OK)
+ return result;
+ }
+
+ unsigned char *dest = (unsigned char *)vec->data + (vec->length++) * vec->item_size;
+ memcpy(dest, item, vec->item_size);
+
+ return LEO_Vec_OK;
+}
+
+enum LEO_Vec_Error LEO_Vec_pop(struct LEO_Vec *vec, void *item)
+{
+ if (vec == NULL)
+ return LEO_Vec_NULL_VEC_POINTER;
+ if (vec->length == 0)
+ return LEO_Vec_OUT_OF_BOUNDS;
+
+ void *src = vec->data + (vec->length--) * vec->item_size;
+ memcpy(item, src, vec->item_size);
+
+ return LEO_Vec_OK;
+}
+
+enum LEO_Vec_Error LEO_Vec_get(struct LEO_Vec *vec, size_t i, void *item)
+{
+ if (vec == NULL)
+ return LEO_Vec_NULL_VEC_POINTER;
+ if (i >= vec->length)
+ return LEO_Vec_OUT_OF_BOUNDS;
+
+ unsigned char *src = (unsigned char *) vec->data + i * vec->item_size;
+ memcpy(item, src, vec->item_size);
+
+ return LEO_Vec_OK;
+}
diff --git a/src/util/vec.h b/src/util/vec.h
new file mode 100644
index 0000000..2b86e17
--- /dev/null
+++ b/src/util/vec.h
@@ -0,0 +1,38 @@
+#ifndef LEO_VEC_H
+#define LEO_VEC_H
+
+#include <stddef.h>
+
+#include "alloc.h"
+
+static const size_t LEO_Vec_GROWTH_FACTOR_NUMER = 3;
+static const size_t LEO_Vec_GROWTH_FACTOR_DENOM = 2;
+static const size_t LEO_Vec_DEFAULT_CAPACITY = 8;
+
+struct LEO_Vec {
+ struct LEO_Allocator allocator;
+ void *data;
+ size_t item_size;
+ size_t length;
+ size_t capacity;
+};
+
+enum LEO_Vec_Error {
+ LEO_Vec_OK = 0,
+ LEO_Vec_NULL_VEC_POINTER = 1,
+ LEO_Vec_NULL_ITEM_POINTER = 2,
+ LEO_Vec_INVALID_ITEM_SIZE = 3,
+ LEO_Vec_ALLOCATION_FAILURE = 4,
+ LEO_Vec_TOO_BIG = 5,
+ LEO_Vec_OUT_OF_BOUNDS = 6,
+};
+
+enum LEO_Vec_Error LEO_Vec_init (struct LEO_Vec *vec, size_t item_size,
+ struct LEO_Allocator allocator);
+
+void LEO_Vec_free (struct LEO_Vec *vec);
+enum LEO_Vec_Error LEO_Vec_push (struct LEO_Vec *vec, const void *item);
+enum LEO_Vec_Error LEO_Vec_pop (struct LEO_Vec *vec, void *item);
+enum LEO_Vec_Error LEO_Vec_get (struct LEO_Vec *vec, size_t i, void *item);
+
+#endif