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;
73 void *dynarr_clear(void *da)
75 return dynarr_resize(da, 0);
79 void *dynarr_push(void *da, void *item)
87 if(nelem >= desc->max_elem) {
90 int newsz = desc->max_elem ? desc->max_elem * 2 : 1;
92 if(!(tmp = dynarr_resize(da, newsz))) {
93 fprintf(stderr, "failed to resize\n");
102 memcpy((char*)da + desc->nelem * desc->szelem, item, desc->szelem);
108 void *dynarr_pop(void *da)
110 struct arrdesc *desc;
116 if(!nelem) return da;
118 if(nelem <= desc->max_elem / 3) {
121 int newsz = desc->max_elem / 2;
123 if(!(tmp = dynarr_resize(da, newsz))) {
124 fprintf(stderr, "failed to resize\n");
136 void *dynarr_finalize(void *da)
138 struct arrdesc *desc = DESC(da);
139 memmove(desc, da, desc->bufsz);