diff options
author | Bad Diode <bd@badd10de.dev> | 2021-10-29 15:37:28 +0200 |
---|---|---|
committer | Bad Diode <bd@badd10de.dev> | 2021-10-29 15:37:28 +0200 |
commit | e73a4c16a2269cdb2f5e7d66fb9839e4c44e14de (patch) | |
tree | c44721b005b7a0623e7acc7103ca8e21a25ff422 /src/darray.h | |
parent | fcc131afdd029c606ea39f3557bc3d33a075b1de (diff) | |
download | bdl-e73a4c16a2269cdb2f5e7d66fb9839e4c44e14de.tar.gz bdl-e73a4c16a2269cdb2f5e7d66fb9839e4c44e14de.zip |
Prepare third compiler implementation
Diffstat (limited to 'src/darray.h')
-rwxr-xr-x | src/darray.h | 81 |
1 files changed, 81 insertions, 0 deletions
diff --git a/src/darray.h b/src/darray.h new file mode 100755 index 0000000..fa4e293 --- /dev/null +++ b/src/darray.h | |||
@@ -0,0 +1,81 @@ | |||
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 | // Return the value stored at the OFFSET position from the tail of the array. | ||
29 | #define array_peek(ARR, OFFSET) (ARR)[array_head(ARR)->size - 1 - (OFFSET)] | ||
30 | |||
31 | // Insert N bytes from the SRC array into the ARR dynamic array. | ||
32 | #define array_insert(ARR, SRC, N) \ | ||
33 | ((ARR) = _array_insert(ARR, SRC, N, sizeof(*(ARR)))) | ||
34 | |||
35 | // Free the memory from the original allocated position. | ||
36 | #define array_free(ARR) ((ARR) ? free(array_head(ARR)), (ARR) = NULL : 0) | ||
37 | |||
38 | static inline void * | ||
39 | _array_reserve(size_t num_elem, size_t type_size) { | ||
40 | char *p = malloc(num_elem * type_size + sizeof(ArrayHeader)); | ||
41 | p += sizeof(ArrayHeader); | ||
42 | array_head(p)->size = 0; | ||
43 | array_head(p)->cap = num_elem; | ||
44 | return p; | ||
45 | } | ||
46 | |||
47 | static inline void * | ||
48 | _array_maybe_grow(void *arr, size_t type_size) { | ||
49 | ArrayHeader *head = array_head(arr); | ||
50 | if (head->cap == head->size) { | ||
51 | if (head->cap == 0) { | ||
52 | head->cap++; | ||
53 | } else { | ||
54 | head->cap *= 2; | ||
55 | } | ||
56 | head = realloc(head, head->cap * type_size + sizeof(ArrayHeader)); | ||
57 | } | ||
58 | arr = (char *)head + sizeof(ArrayHeader); | ||
59 | return arr; | ||
60 | } | ||
61 | |||
62 | static inline | ||
63 | char * _array_insert(char *arr, const char *src, size_t n_bytes, size_t type_size) { | ||
64 | ArrayHeader *head = array_head(arr); | ||
65 | size_t new_size = n_bytes + head->size; | ||
66 | if (new_size > head->cap * type_size) { | ||
67 | if (head->cap == 0) { | ||
68 | head->cap = 1; | ||
69 | } | ||
70 | while (new_size >= head->cap * type_size) { | ||
71 | head->cap *= 2; | ||
72 | } | ||
73 | head = realloc(head, head->cap * type_size + sizeof(ArrayHeader)); | ||
74 | } | ||
75 | arr = (char *)head + sizeof(ArrayHeader); | ||
76 | memcpy((arr + head->size), src, n_bytes); | ||
77 | head->size = new_size; | ||
78 | return arr; | ||
79 | } | ||
80 | |||
81 | #endif // BDL_DARRAY_H | ||