diff options
Diffstat (limited to 'src/bootstrap/darray.h')
-rw-r--r-- | src/bootstrap/darray.h | 55 |
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 | |||
6 | typedef 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 | |||
31 | static 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 | |||
40 | static 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 | ||