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 *ts_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 ts_dynarr_free(void *da)
41 void *ts_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 ts_dynarr_empty(void *da)
64 return DESC(da)->nelem ? 0 : 1;
67 int ts_dynarr_size(void *da)
69 return DESC(da)->nelem;
73 void *ts_dynarr_clear(void *da)
75 return ts_dynarr_resize(da, 0);
79 void *ts_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 = ts_dynarr_resize(da, newsz))) {
93 fprintf(stderr, "failed to resize\n");
102 memcpy((char*)da + desc->nelem++ * desc->szelem, item, desc->szelem);
107 void *ts_dynarr_pop(void *da)
109 struct arrdesc *desc;
115 if(!nelem) return da;
117 if(nelem <= desc->max_elem / 3) {
120 int newsz = desc->max_elem / 2;
122 if(!(tmp = ts_dynarr_resize(da, newsz))) {
123 fprintf(stderr, "failed to resize\n");