aboutsummaryrefslogtreecommitdiffstats
path: root/src/bytecode/darray.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/bytecode/darray.h')
-rw-r--r--src/bytecode/darray.h78
1 files changed, 78 insertions, 0 deletions
diff --git a/src/bytecode/darray.h b/src/bytecode/darray.h
new file mode 100644
index 0000000..db6234d
--- /dev/null
+++ b/src/bytecode/darray.h
@@ -0,0 +1,78 @@
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// Insert N bytes from the SRC array into the ARR dynamic array.
29#define array_insert(ARR, SRC, N) \
30 ((ARR) = _array_insert(ARR, SRC, N, sizeof(*(ARR))))
31
32// Free the memory from the original allocated position.
33#define array_free(ARR) ((ARR) ? free(array_head(ARR)), (ARR) = NULL : 0)
34
35static inline void *
36_array_reserve(size_t num_elem, size_t type_size) {
37 char *p = malloc(num_elem * type_size + sizeof(ArrayHeader));
38 p += sizeof(ArrayHeader);
39 array_head(p)->size = 0;
40 array_head(p)->cap = num_elem;
41 return p;
42}
43
44static inline void *
45_array_maybe_grow(void *arr, size_t type_size) {
46 ArrayHeader *head = array_head(arr);
47 if (head->cap == head->size) {
48 if (head->cap == 0) {
49 head->cap++;
50 } else {
51 head->cap *= 2;
52 }
53 head = realloc(head, head->cap * type_size + sizeof(ArrayHeader));
54 }
55 arr = (char *)head + sizeof(ArrayHeader);
56 return arr;
57}
58
59static inline
60char * _array_insert(char *arr, const char *src, size_t n_bytes, size_t type_size) {
61 ArrayHeader *head = array_head(arr);
62 size_t new_size = n_bytes + head->size;
63 if (new_size >= head->cap * type_size) {
64 if (head->cap == 0) {
65 head->cap = 1;
66 }
67 while (new_size >= head->cap * type_size) {
68 head->cap *= 2;
69 }
70 head = realloc(head, head->cap * type_size + sizeof(ArrayHeader));
71 }
72 arr = (char *)head + sizeof(ArrayHeader);
73 memcpy((arr + head->size), src, n_bytes);
74 head->size = new_size;
75 return arr;
76}
77
78#endif // BDL_DARRAY_H