1 /* dynarr - dynamic resizable C array data structure
2 * author: John Tsiombikas <nuclear@member.fsf.org>
3 * license: public domain
10 /* The array descriptor keeps auxilliary information needed to manipulate
11 * the dynamic array. It's allocated adjacent to the array buffer.
16 int bufsz; /* not including the descriptor */
19 #define DESC(x) ((struct arrdesc*)((char*)(x) - sizeof(struct arrdesc)))
21 void *dynarr_alloc(int elem, int szelem)
25 if(!(desc = malloc(elem * szelem + sizeof *desc))) {
28 desc->nelem = desc->max_elem = elem;
29 desc->szelem = szelem;
30 desc->bufsz = elem * szelem;
31 return (char*)desc + sizeof *desc;
34 void dynarr_free(void *da)
41 void *dynarr_resize(void *da, int elem)
50 newsz = desc->szelem * elem;
52 if(!(tmp = realloc(desc, newsz + sizeof *desc))) {
57 desc->nelem = desc->max_elem = elem;
59 return (char*)desc + sizeof *desc;
62 int dynarr_empty(void *da)
64 return DESC(da)->nelem ? 0 : 1;
67 int dynarr_size(void *da)
69 return DESC(da)->nelem;
74 void *dynarr_push(void *da, void *item)
82 if(nelem >= desc->max_elem) {
85 int newsz = desc->max_elem ? desc->max_elem * 2 : 1;
87 if(!(tmp = dynarr_resize(da, newsz))) {
88 fprintf(stderr, "failed to resize\n");
97 memcpy((char*)da + desc->nelem++ * desc->szelem, item, desc->szelem);
102 void *dynarr_pop(void *da)
104 struct arrdesc *desc;
110 if(!nelem) return da;
112 if(nelem <= desc->max_elem / 3) {
115 int newsz = desc->max_elem / 2;
117 if(!(tmp = dynarr_resize(da, newsz))) {
118 fprintf(stderr, "failed to resize\n");