summary refs log tree commit diff
path: root/zdynarr.h
blob: dd777d902bf608468aa276035534aecd60773d5a (plain)
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
59
60
#ifndef DYNARR_H
#define DYNARR_H

#include <stdlib.h>
#include <stdint.h>
#include <string.h>

#include "stdwrm.h"
#include "zone.h"

typedef struct { Zone *zone; ZoneFrame *zf; size_t count, capacity; } ZDarrHeader;

#define ZDYNARR(type) type *
#define ZDA_HEADER(da) ((ZDarrHeader*)(da) - 1)

#define ZDA_INIT_CAP 16
#define ZDA_INIT_SZ(da, z, cap) do {\
	ZoneFrame *zda_zf_ptr;\
	char *zda_init_ptr = zn_alloc_zf(z, &zda_zf_ptr, sizeof(ZDarrHeader) + cap * sizeof(*da));\
	if (!zda_init_ptr) { fprintf(stderr, "dynamic array allocation failed\n"); abort(); }\
	da = (void *)(zda_init_ptr + sizeof(ZDarrHeader));\
	*ZDA_HEADER(da) = (ZDarrHeader) { 0, cap };\
} while(0)

#define ZDA_INIT(da, z) ZDA_INIT_SZ(da, z, ZDA_INIT_CAP)

#define ZDA_LEN(da) (ZDA_HEADER(da)->count)
#define ZDA_FIT(da, count) do {\
	size_t zda_fit_cap = ZA_HEADER(da)->capacity;\
	if (count >= zda_fit_cap) {\
		ZoneFrame *zda_zf_ptr = (da)->zf;\
		while (count >= zda_fit_cap) zda_fit_cap <<= 1;\
		char *zda_fit_ptr = zn_zf_realloc((da)->zone, &zda_zf_ptr, ZDA_HEADER(da),\
				sizeof(ZDarrHeader) + ZDA_HEADER(da)->capacity * sizeof(*da),\
				sizeof(ZDarrHeader) + zda_fit_cap * sizeof(*da));\
		if (!zda_fit_ptr) { fprintf(stderr, "dynamic array reallocation failed\n"); abort(); }\
		(da) = (void *)(zda_fit_ptr + sizeof(ZDarrHeader));\
		ZDA_HEADER(da)->capacity = zda_fit_cap;\
		ZDA_HEADER(da)->zf = zda_zf_ptr;\
	}\
} while(0)

#define ZDA_PUSH(da, ...) do {\
	ZDA_FIT(da, ZDA_LEN(da) + 1);\
	(da)[ZDA_HEADER(da)->count++] = (__VA_ARGS__);\
} while(0)

#define ZDA_PUSH_MULT(da, buf, n) do {\
	ZDA_FIT(da, ZDA_LEN(da) + n);\
	memcpy(&(da)[ZDA_HEADER(da)->count], buf, n * sizeof(*(da)));\
	ZDA_HEADER(da)->count += n;\
} while(0)

#define ZDA_FOR(da, name)\
	for (typeof(da) name = (da); name < &(da)[ZDA_LEN(da)]; name++)

#define ZDA_FORVAL(da, name)\
	for (volatile typeof(*(da)) *stdwrm__zda_iter = (da), name; stdwrm__zda_iter < &(da)[ZDA_LEN(da)] && (name = *stdwrm__zda_iter, 1); stdwrm__zda_iter++)

#endif