|
|
@@ -0,0 +1,123 @@
|
|
|
+#ifndef ARENA_H
|
|
|
+#define ARENA_H
|
|
|
+
|
|
|
+#include <stdint.h>
|
|
|
+
|
|
|
+typedef uint8_t err_t;
|
|
|
+
|
|
|
+struct arena {
|
|
|
+ uint8_t *data;
|
|
|
+ size_t cur;
|
|
|
+ size_t cap;
|
|
|
+};
|
|
|
+
|
|
|
+struct void_p_err_t {
|
|
|
+ void *ptr;
|
|
|
+ err_t err;
|
|
|
+};
|
|
|
+
|
|
|
+struct arena_void_p_err_t {
|
|
|
+ struct arena arena;
|
|
|
+ void *ptr;
|
|
|
+ err_t err;
|
|
|
+};
|
|
|
+
|
|
|
+struct arena_err_t {
|
|
|
+ struct arena arena;
|
|
|
+ err_t err;
|
|
|
+};
|
|
|
+
|
|
|
+enum arena_err {
|
|
|
+ ARENA_ERR_OK = 0,
|
|
|
+ ARENA_ERR_MALLOC_FAIL,
|
|
|
+ ARENA_ERR_HIT_CAP
|
|
|
+};
|
|
|
+
|
|
|
+struct arena_err_t arena_create(size_t cap);
|
|
|
+err_t arena_destroy(struct arena arena);
|
|
|
+
|
|
|
+struct void_p_err_t arena_alloc(struct arena *arena, size_t size);
|
|
|
+struct arena_void_p_err_t arena_alloc_pure(struct arena arena, size_t size);
|
|
|
+
|
|
|
+err_t arena_forget(struct arena *arena);
|
|
|
+struct arena_err_t arena_forget_pure(struct arena arena);
|
|
|
+
|
|
|
+#if defined(ARENA_IMP) || defined(IMP)
|
|
|
+
|
|
|
+#include <stdlib.h>
|
|
|
+
|
|
|
+struct arena_err_t
|
|
|
+arena_create(size_t cap)
|
|
|
+{
|
|
|
+ void *data = calloc(cap, sizeof(uint8_t));
|
|
|
+
|
|
|
+ if ( data == NULL ) {
|
|
|
+ return (struct arena_err_t) { .err = ARENA_ERR_MALLOC_FAIL };
|
|
|
+ }
|
|
|
+
|
|
|
+ struct arena arena = {
|
|
|
+ .data = data,
|
|
|
+ .cap = cap,
|
|
|
+ .cur = 0
|
|
|
+ };
|
|
|
+
|
|
|
+ return (struct arena_err_t) { .arena = arena, .err = ARENA_ERR_OK };
|
|
|
+}
|
|
|
+
|
|
|
+err_t
|
|
|
+arena_destroy(struct arena arena)
|
|
|
+{
|
|
|
+ free(arena.data);
|
|
|
+ return ARENA_ERR_OK;
|
|
|
+}
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+struct void_p_err_t
|
|
|
+arena_alloc(struct arena *arena, size_t size)
|
|
|
+{
|
|
|
+ if ( arena->cur + size >= arena->cap ) {
|
|
|
+ return (struct void_p_err_t) {
|
|
|
+ .ptr = NULL,
|
|
|
+ .err = ARENA_ERR_HIT_CAP
|
|
|
+ };
|
|
|
+ }
|
|
|
+
|
|
|
+ void * ptr = (void *) (arena->data + arena->cur);
|
|
|
+ arena->cur += size;
|
|
|
+
|
|
|
+ return (struct void_p_err_t) {
|
|
|
+ .ptr = ptr,
|
|
|
+ .err = ARENA_ERR_OK
|
|
|
+ };
|
|
|
+}
|
|
|
+
|
|
|
+
|
|
|
+struct arena_void_p_err_t
|
|
|
+arena_alloc_pure(struct arena arena, size_t size)
|
|
|
+{
|
|
|
+ struct void_p_err_t vpet = arena_alloc(&arena, size);
|
|
|
+ return (struct arena_void_p_err_t) {
|
|
|
+ .arena = arena,
|
|
|
+ .ptr = vpet.ptr,
|
|
|
+ .err = vpet.err
|
|
|
+ };
|
|
|
+}
|
|
|
+
|
|
|
+err_t
|
|
|
+arena_forget(struct arena *arena)
|
|
|
+{
|
|
|
+ arena->cur = 0;
|
|
|
+ return ARENA_ERR_OK;
|
|
|
+}
|
|
|
+
|
|
|
+struct arena_err_t
|
|
|
+arena_forget_pure(struct arena arena)
|
|
|
+{
|
|
|
+ err_t err = arena_forget(&arena);
|
|
|
+ return (struct arena_err_t) { .arena = arena, .err = err };
|
|
|
+}
|
|
|
+
|
|
|
+#endif /* ARENA_IMP || IMPLEMENTATIONS */
|
|
|
+
|
|
|
+#endif /* ARENA_H */
|