aboutsummaryrefslogtreecommitdiffstats
path: root/src/bootstrap/darray.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/bootstrap/darray.h')
-rw-r--r--src/bootstrap/darray.h55
1 files changed, 55 insertions, 0 deletions
diff --git a/src/bootstrap/darray.h b/src/bootstrap/darray.h
new file mode 100644
index 0000000..bb49cdd
--- /dev/null
+++ b/src/bootstrap/darray.h
@@ -0,0 +1,55 @@
1#ifndef BDL_DARRAY_H
2#define BDL_DARRAY_H
3
4#include <string.h>
5
6typedef struct ArrayHeader {
7 size_t size;
8 size_t cap;
9} ArrayHeader;
10
11// Header/Size/capacity accessors.
12#define array_head(ARR) ((ArrayHeader *)((char *)(ARR) - sizeof(ArrayHeader)))
13#define array_size(ARR) ((ARR) ? array_head(ARR)->size : 0)
14#define array_cap(ARR) ((ARR) ? array_head(ARR)->cap : 0)
15
16// Initialize a dynamic array ARR with N elements. The initialization doesn't
17// zero out the data, so thread carefully..
18#define array_init(ARR,N) ((ARR) = _array_reserve(N, sizeof(*(ARR))))
19
20// Push a given element T to the dynamic array ARR.
21#define array_push(ARR, T) \
22 ((ARR) = _array_maybe_grow(ARR, sizeof(T)), \
23 (ARR)[array_head(ARR)->size++] = (T))
24
25// Return the last element of the array. Can be used to build stacks.
26#define array_pop(ARR) (ARR)[--array_head(ARR)->size]
27
28// Free the memory from the original allocated position.
29#define array_free(ARR) ((ARR) ? free(array_head(ARR)), (ARR) = NULL : 0)
30
31static inline void *
32_array_reserve(size_t num_elem, size_t type_size) {
33 char *p = malloc(num_elem * type_size + sizeof(ArrayHeader));
34 p += sizeof(ArrayHeader);
35 array_head(p)->size = 0;
36 array_head(p)->cap = num_elem;
37 return p;
38}
39
40static inline void *
41_array_maybe_grow(void *arr, size_t type_size) {
42 ArrayHeader *head = array_head(arr);
43 if (head->cap == head->size) {
44 if (head->cap == 0) {
45 head->cap++;
46 } else {
47 head->cap *= 2;
48 }
49 head = realloc(head, head->cap * type_size + sizeof(ArrayHeader));
50 }
51 arr = (char *)head + sizeof(ArrayHeader);
52 return arr;
53}
54
55#endif // BDL_DARRAY_H