summary refs log tree commit diff
path: root/dynarr.h
blob: 321325bcbfabf37ac2c8b5312814a3d67245dac6 (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
#ifndef DYNARR_H
#define DYNARR_H

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

typedef struct { size_t count, capacity; } DynArrHeader;

#define DYNARR(type) type *
#define DA_HEADER(da) ((DynArrHeader*)(da) - 1)

#define DA_INIT_CAP 16
#define DA_INIT(da) {\
	char *da_init_ptr = ((char*)malloc(sizeof(DynArrHeader) + DA_INIT_CAP * sizeof(*da)));\
	if (!da_init_ptr) err(1, "dynamic array allocation failed");\
	da = (void *)(da_init_ptr + sizeof(DynArrHeader));\
	*DA_HEADER(da) = (DynArrHeader) { 0, DA_INIT_CAP };\
}

#define DA_FREE(da)\
	free(DA_HEADER(da))

#define DA_LEN(da) (DA_HEADER(da)->count)
#define DA_FIT(da, count)\
	if (count >= DA_HEADER(da)->capacity) {\
		while (count >= DA_HEADER(da)->capacity) DA_HEADER(da)->capacity <<= 1;\
		char *da_fit_ptr = realloc(DA_HEADER(da), sizeof(DynArrHeader) + DA_HEADER(da)->capacity * sizeof(*da));\
		if (!da_fit_ptr) err(1, "dynamic array reallocation failed");\
		(da) = (void *)(da_fit_ptr + sizeof(DynArrHeader));\
	}

#define DA_PUSH(da, item) {\
	DA_FIT(da, DA_LEN(da) + 1);\
	(da)[DA_HEADER(da)->count++] = item;\
}

#define DA_FOR(da, type, name)\
	for (type *name = (da); name < &(da)[DA_LEN(da)]; name++)

#define DA_FORVAL(da, type, name)\
	for (volatile type *da_iter = (da), name; da_iter < &(da)[DA_LEN(da)] && (name = *da_iter, 1); da_iter++)

#endif