summaryrefslogtreecommitdiff
path: root/dynarr.h
blob: c3cbe4d0af8c0522992493e5910da60939dc575d (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
61
62
63
64
65
66
67
68
69
70
71
72
#ifndef DYNARR_H
#define DYNARR_H

#include "arena.h"

#define DYNARR(t) struct { t *data; ptrdiff_t len, cap; }

#define ZDA_FIT(da, c, zn) ((typeof((da)->data))\
	zda_fit((void **)&(da)->data, sizeof((da)->data[0]),\
			_Alignof(typeof((da)->data[0])), \
			c, &(da)->cap, zn))

#define ZDA_FIT_ALIGN(da, c, a, zn) ((typeof((da)->data))\
	zda_fit((void **)&(da)->data, sizeof((da)->data[0]), a,\
			c, &(da)->cap, zn))

#define ZDA_GROW(da, n, zn) ZDA_FIT(da, (da)->len + n, zn)

#define ZDA_PUSH(zn, da, ...)\
	(ZDA_GROW(da, 1, zn)[(da)->len] = (__VA_ARGS__), (da)->len++)

#define ZDA_INIT_CAP 32

#define DA_FIT(da, c) ((typeof((da)->data))\
	da_fit((void **)&(da)->data, sizeof((da)->data[0]), c, &(da)->cap))

#define DA_FIT_ALIGN(da, c, a) ((typeof((da)->data))\
	da_fit((void **)&(da)->data, sizeof((da)->data[0]), a, c, &(da)->cap)

#define DA_GROW(da, n) DA_FIT(da, (da)->len + n)
#define DA_PUSH(da, ...) (DA_GROW(da, 1)[(da)->len++] = (__VA_ARGS__))
#define DA_INIT_CAP 32

void *da_fit(void **data, ptrdiff_t size, ptrdiff_t fit, ptrdiff_t *cap);
void *zda_fit(void **data, ptrdiff_t size, ptrdiff_t align, ptrdiff_t fit, ptrdiff_t *cap, Arena *a);

#ifdef DYNARR_IMPL

#include <stdio.h>
#include <stdlib.h>
#include <stdio.h>

void *da_fit(void **data, ptrdiff_t size, ptrdiff_t fit, ptrdiff_t *cap) {
	ptrdiff_t c = *cap;
	if (c >= fit) return *data;
	if (!c) c = DA_INIT_CAP;
	while (c < fit) c <<= 1;
	size_t sz = c * size;
	void *p = *data ? realloc(*data, sz) : malloc(sz);
	if (!p) {
		fprintf(stderr, "dynamic array resize failure\n");
		abort();
	}
	*cap = c;
	*data = p;
	return p;
}

void *zda_fit(void **data, ptrdiff_t size, ptrdiff_t align, ptrdiff_t fit, ptrdiff_t *cap, Arena *a) {
	ptrdiff_t C = *cap;
	ptrdiff_t c = C;
	if (c >= fit) return *data;
	if (!c) c = ZDA_INIT_CAP;
	while (c < fit) c <<= 1;
	void *p = arena_realloc(a, *data, C * size, c * size, align);
	*cap = c;
	*data = p;
	return p;
}

#endif
#endif