Compare commits

..

4 Commits

Author SHA1 Message Date
b2bbb85fcc Merge pull request 'refactor-consistency' (#1) from refactor-consistency into main
Reviewed-on: #1
2026-05-13 20:32:20 -06:00
fb832eab06 refactor: tests adapted and succesfully passed 2026-05-13 20:25:55 -06:00
6c91e1f681 refactor: init and destroy, alloc now first ensures cap
its better usability and is better that it ensures capacity in alloc
like that is what is supposed to be like damn, why i did it like that
2026-05-13 20:10:40 -06:00
f981ba92a8 refactor: Arena is opaque, init returns error code
Is to make it more consistent, i need to change also later arraylist the
init function so its also more consistent, next is making alloc ensure
capacity first so no using it first or some shit.
2026-05-13 19:57:49 -06:00
3 changed files with 87 additions and 71 deletions

View File

@@ -6,11 +6,7 @@
#include <inttypes.h>
#include <stdbool.h>
typedef struct {
uint8_t *buffer;
size_t capacity;
size_t offset;
} Arena;
typedef struct Arena Arena;
typedef enum {
ARENA_OK = 0,
@@ -37,7 +33,7 @@ typedef struct {
bool is_valid;
union {
ArenaErr err;
Arena arena;
Arena *arena;
};
} ArenaResult;
@@ -49,8 +45,8 @@ typedef struct {
};
} ArenaSizeResult;
ArenaResult arena_init(size_t capacity);
void arena_destroy(Arena *arena);
ArenaErr arena_init(Arena **arena, size_t capacity);
ArenaErr arena_destroy(Arena **arena);
ArenaPointer arena_alloc(Arena *arena, size_t size, size_t alignment);
ArenaPointer arena_push(Arena *arena, void *data, size_t size, size_t alignment);

View File

@@ -5,32 +5,56 @@
#include <stdlib.h>
#include <string.h>
struct Arena {
uint8_t *buffer;
size_t capacity;
size_t offset;
};
ArenaResult arena_init(size_t capacity) {
ArenaErr arena_init(Arena **arena, size_t capacity) {
if (arena == NULL) {
return ARENA_NULL_ARG;
}
if (capacity < 1) {
return (ArenaResult) {.is_valid = false, .err = ARENA_INVALID_SIZE};
return ARENA_INVALID_SIZE;
}
Arena *new_arena = malloc(sizeof(Arena));
if (new_arena == NULL) {
return ARENA_BAD_ALLOC;
}
void *buffer = malloc(capacity);
if (buffer == NULL) {
return (ArenaResult) {.is_valid = false, .err = ARENA_BAD_ALLOC};
return ARENA_BAD_ALLOC;
}
Arena new_arena = {
*new_arena = (Arena) {
.buffer = buffer,
.capacity = capacity,
.offset = 0,
};
return (ArenaResult) {.is_valid = true, .arena = new_arena};
*arena = new_arena;
return ARENA_OK;
}
void arena_destroy(Arena *arena) {
free(arena->buffer);
arena->buffer = NULL;
arena->offset = 0;
arena->capacity = 0;
ArenaErr arena_destroy(Arena **arena) {
if (arena == NULL || *arena == NULL) {
return ARENA_NULL_ARG;
}
free((*arena)->buffer);
(*arena)->buffer = NULL;
(*arena)->offset = 0;
(*arena)->capacity = 0;
free(*arena);
*arena = NULL;
return ARENA_OK;
}
ArenaPointer arena_alloc(Arena *arena, size_t size, size_t alignment) {
@@ -51,6 +75,11 @@ ArenaPointer arena_alloc(Arena *arena, size_t size, size_t alignment) {
return (ArenaPointer) {.is_valid = false, .err = padding.err};
}
ArenaErr cap_err = arena_ensure_capacity(arena, size, alignment);
if(cap_err != ARENA_OK) {
return (ArenaPointer) {.is_valid = false, .err = ARENA_OUT_OF_SPACE};
}
if (arena->offset + padding.val + size > arena->capacity) {
return (ArenaPointer) {.is_valid = false, .err = ARENA_OUT_OF_SPACE};
}

View File

@@ -14,23 +14,22 @@
static void test_push_3_ints(void **state) {
(void) state;
ArenaResult value = arena_init(sizeof(int) * 3);
assert_true(value.is_valid);
Arena arena = value.arena;
Arena *arena;
assert_uint_equal(arena_init(&arena, sizeof(int) * 3), ARENA_OK);
int int_to_push = 20;
ArenaPointer result = arena_push(&arena, &int_to_push, sizeof(int), alignof(int));
ArenaPointer result = arena_push(arena, &int_to_push, sizeof(int), alignof(int));
assert_true(result.is_valid);
assert_int_equal(20, *(int*)arena_unwrap_pointer(result));
assert_int_equal(20, *(int*)arena_unwrap_pointer(result));
int_to_push = 30;
result = arena_push(&arena, &int_to_push, sizeof(int), alignof(int));
result = arena_push(arena, &int_to_push, sizeof(int), alignof(int));
assert_true(result.is_valid);
assert_int_equal(30, *(int*)arena_unwrap_pointer(result));
int_to_push = 40;
result = arena_push(&arena, &int_to_push, sizeof(int), alignof(int));
result = arena_push(arena, &int_to_push, sizeof(int), alignof(int));
assert_true(result.is_valid);
assert_int_equal(40, *(int*)arena_unwrap_pointer(result));
@@ -40,32 +39,34 @@ static void test_push_3_ints(void **state) {
static void test_push_3_ints_2_doubles(void **state) {
(void) state;
ArenaResult value = arena_init((sizeof(int) * 3) + (sizeof(double) * 2));
assert_true(value.is_valid);
Arena arena = value.arena;
Arena *arena;
assert_uint_equal(
arena_init(&arena, (sizeof(int) * 3) + (sizeof(double) * 2)),
ARENA_OK
);
int int_to_push = 20;
ArenaPointer result = arena_push(&arena, &int_to_push, sizeof(int), alignof(int));
ArenaPointer result = arena_push(arena, &int_to_push, sizeof(int), alignof(int));
assert_true(result.is_valid);
assert_int_equal(20, *(int*)arena_unwrap_pointer(result));
double double_to_push = 4.57;
result = arena_push(&arena, &double_to_push, sizeof(double), alignof(double));
result = arena_push(arena, &double_to_push, sizeof(double), alignof(double));
assert_true(result.is_valid);
assert_double_equal(4.57, *(double*)arena_unwrap_pointer(result), 1e-6);
int_to_push = 30;
result = arena_push(&arena, &int_to_push, sizeof(int), alignof(int));
result = arena_push(arena, &int_to_push, sizeof(int), alignof(int));
assert_true(result.is_valid);
assert_int_equal(30, *(int*)arena_unwrap_pointer(result));
int_to_push = 40;
result = arena_push(&arena, &int_to_push, sizeof(int), alignof(int));
result = arena_push(arena, &int_to_push, sizeof(int), alignof(int));
assert_true(result.is_valid);
assert_int_equal(40, *(int*)arena_unwrap_pointer(result));
double_to_push = 267.33;
result = arena_push(&arena, &double_to_push, sizeof(double), alignof(double));
result = arena_push(arena, &double_to_push, sizeof(double), alignof(double));
assert_true(result.is_valid);
assert_double_equal(267.33, *(double*)arena_unwrap_pointer(result), 1e-6);
@@ -75,19 +76,17 @@ static void test_push_3_ints_2_doubles(void **state) {
static void test_init_arena_0_cap(void **state) {
(void) state;
ArenaResult arena = arena_init(0);
assert_false(arena.is_valid);
assert_int_equal(arena.err, ARENA_INVALID_SIZE);
Arena *arena;
assert_int_equal(arena_init(&arena, 0), ARENA_INVALID_SIZE);
}
static void test_arena_alloc_size_0(void **state) {
(void) state;
ArenaResult value = arena_init(64);
assert_true(value.is_valid);
Arena arena = value.arena;
Arena *arena;
assert_uint_equal(arena_init(&arena, 64), ARENA_OK);
ArenaPointer pointer = arena_alloc(&arena, 0, alignof(int));
ArenaPointer pointer = arena_alloc(arena, 0, alignof(int));
assert_false(pointer.is_valid);
assert_int_equal(pointer.err, ARENA_INVALID_SIZE);
@@ -97,11 +96,10 @@ static void test_arena_alloc_size_0(void **state) {
static void test_arena_alloc_size_max(void **state) {
(void) state;
ArenaResult value = arena_init(64);
assert_true(value.is_valid);
Arena arena = value.arena;
Arena *arena;
assert_uint_equal(arena_init(&arena, 64), ARENA_OK);
ArenaPointer pointer = arena_alloc(&arena, SIZE_MAX, alignof(int));
ArenaPointer pointer = arena_alloc(arena, SIZE_MAX, alignof(int));
assert_false(pointer.is_valid);
assert_int_equal(pointer.err, ARENA_OUT_OF_SPACE);
@@ -111,11 +109,10 @@ static void test_arena_alloc_size_max(void **state) {
static void test_arena_alloc_align_0(void **state) {
(void) state;
ArenaResult value = arena_init(64);
assert_true(value.is_valid);
Arena arena = value.arena;
Arena *arena;
assert_uint_equal(arena_init(&arena, 64), ARENA_OK);
ArenaPointer pointer = arena_alloc(&arena, sizeof(int), 0);
ArenaPointer pointer = arena_alloc(arena, sizeof(int), 0);
assert_false(pointer.is_valid);
assert_int_equal(pointer.err, ARENA_INVALID_ALIGN);
@@ -125,11 +122,10 @@ static void test_arena_alloc_align_0(void **state) {
static void test_arena_alloc_align_max(void **state) {
(void) state;
ArenaResult value = arena_init(64);
assert_true(value.is_valid);
Arena arena = value.arena;
Arena *arena;
assert_uint_equal(arena_init(&arena, 64), ARENA_OK);
ArenaPointer pointer = arena_alloc(&arena, sizeof(int), SIZE_MAX);
ArenaPointer pointer = arena_alloc(arena, sizeof(int), SIZE_MAX);
assert_false(pointer.is_valid);
assert_int_equal(pointer.err, ARENA_INVALID_ALIGN);
@@ -139,11 +135,10 @@ static void test_arena_alloc_align_max(void **state) {
static void test_arena_align_size_0(void **state) {
(void) state;
ArenaResult value = arena_init(64);
assert_true(value.is_valid);
Arena arena = value.arena;
Arena *arena;
assert_uint_equal(arena_init(&arena, 64), ARENA_OK);
ArenaPointer pointer = arena_alloc(&arena, sizeof(int), 0);
ArenaPointer pointer = arena_alloc(arena, sizeof(int), 0);
assert_false(pointer.is_valid);
assert_int_equal(pointer.err, ARENA_INVALID_ALIGN);
@@ -153,11 +148,10 @@ static void test_arena_align_size_0(void **state) {
static void test_arena_ensure_capacity_size_0(void **state) {
(void) state;
ArenaResult value = arena_init(64);
assert_true(value.is_valid);
Arena arena = value.arena;
Arena *arena;
assert_uint_equal(arena_init(&arena, 64), ARENA_OK);
ArenaErr err = arena_ensure_capacity(&arena, 0, alignof(int));
ArenaErr err = arena_ensure_capacity(arena, 0, alignof(int));
assert_int_equal(err, ARENA_INVALID_SIZE);
arena_destroy(&arena);
@@ -166,11 +160,10 @@ static void test_arena_ensure_capacity_size_0(void **state) {
static void test_arena_ensure_capacity_size_max(void **state) {
(void) state;
ArenaResult value = arena_init(64);
assert_true(value.is_valid);
Arena arena = value.arena;
Arena *arena;
assert_uint_equal(arena_init(&arena, 64), ARENA_OK);
ArenaErr err = arena_ensure_capacity(&arena, SIZE_MAX, alignof(int));
ArenaErr err = arena_ensure_capacity(arena, SIZE_MAX, alignof(int));
assert_int_equal(err, ARENA_INVALID_SIZE);
arena_destroy(&arena);
@@ -179,11 +172,10 @@ static void test_arena_ensure_capacity_size_max(void **state) {
static void test_arena_ensure_capacity_align_0(void **state) {
(void) state;
ArenaResult value = arena_init(64);
assert_true(value.is_valid);
Arena arena = value.arena;
Arena *arena;
assert_uint_equal(arena_init(&arena, 64), ARENA_OK);
ArenaErr err = arena_ensure_capacity(&arena, sizeof(int), 0);
ArenaErr err = arena_ensure_capacity(arena, sizeof(int), 0);
assert_int_equal(err, ARENA_INVALID_ALIGN);
arena_destroy(&arena);
@@ -192,11 +184,10 @@ static void test_arena_ensure_capacity_align_0(void **state) {
static void test_arena_ensure_capacity_align_max(void **state) {
(void) state;
ArenaResult value = arena_init(64);
assert_true(value.is_valid);
Arena arena = value.arena;
Arena *arena;
assert_uint_equal(arena_init(&arena, 64), ARENA_OK);
ArenaErr err = arena_ensure_capacity(&arena, sizeof(int), SIZE_MAX);
ArenaErr err = arena_ensure_capacity(arena, sizeof(int), SIZE_MAX);
assert_int_equal(err, ARENA_INVALID_ALIGN);
arena_destroy(&arena);