-
Notifications
You must be signed in to change notification settings - Fork 0
/
arena.h
58 lines (49 loc) · 1.74 KB
/
arena.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
#ifndef GEN_ARENA
#define GEN_ARENA
#include "macros.h"
#include <assert.h>
#include <stdlib.h>
#define arena_t(type_t) struct CONCAT(arena_, type_t)
#define arena_init_fn(type_t) CONCAT(arena_init_, type_t)
#define arena_deinit_fn(type_t) CONCAT(arena_deinit_, type_t)
#define arena_reserve_fn(type_t) CONCAT(arena_reserve_, type_t)
#define arena_at(arena, pos) (arena).ptr[pos]
#define arena_init(type, sz) arena_init_fn(type)(sz)
#define arena_associated(arena_fn, arena_ref, ...) \
arena_type(arena_fn, \
*(arena_ref)->ptr)(arena_ref __VA_OPT__(, ) __VA_ARGS__)
#define arena_deinit(arena_ref) arena_associated(arena_deinit_fn, arena_ref)
#define arena_reserve(arena_ref, sz) \
arena_associated(arena_reserve_fn, arena_ref, sz)
#define arena_declare(type_t) \
arena_t(type_t) { \
type_t * ptr; \
size_t storage; \
}; \
arena_t(type_t) arena_init_fn(type_t)(size_t); \
void arena_deinit_fn(type_t)(arena_t(type_t) *); \
void arena_reserve_fn(type_t)(arena_t(type_t) *, size_t); \
#define arena_define(type_t) \
arena_t(type_t) arena_init_fn(type_t)(size_t size) { \
return (arena_t(type_t)){ \
.ptr = calloc(size, sizeof(type_t)), \
.storage = size, \
}; \
} \
void arena_deinit_fn(type_t)(arena_t(type_t) * arena) { \
if (!arena) return; \
if (arena->ptr) free(arena->ptr); \
*arena = (arena_t(type_t)){0}; \
} \
void arena_reserve_fn(type_t)(arena_t(type_t) * arena, \
size_t storage) { \
if (storage <= arena->storage) return; \
*arena = (arena_t(type_t)){ \
.ptr = realloc(arena->ptr, storage * sizeof(type_t)), \
.storage = storage, \
}; \
}
#define arena_deduced(type_t) \
static_assert(arena_type(sizeof, (type_t){0}) == sizeof(type_t), \
STRING(type_t) " arena");
#endif // !GEN_ARENA