7 /* The array descriptor keeps auxilliary information needed to manipulate
8 * the dynamic array. It's allocated adjacent to the array buffer.
13 int bufsz; /* not including the descriptor */
16 #define DESC(x) ((struct arrdesc*)((char*)(x) - sizeof(struct arrdesc)))
18 void *darr_alloc(int elem, int szelem)
22 desc = malloc_nf(elem * szelem + sizeof *desc);
23 desc->nelem = desc->max_elem = elem;
24 desc->szelem = szelem;
25 desc->bufsz = elem * szelem;
26 return (char*)desc + sizeof *desc;
29 void darr_free(void *da)
36 void *darr_resize_impl(void *da, int elem)
44 newsz = desc->szelem * elem;
45 desc = realloc_nf(desc, newsz + sizeof *desc);
47 desc->nelem = desc->max_elem = elem;
49 return (char*)desc + sizeof *desc;
52 int darr_empty(void *da)
54 return DESC(da)->nelem ? 0 : 1;
57 int darr_size(void *da)
59 return DESC(da)->nelem;
63 void *darr_clear_impl(void *da)
65 return darr_resize_impl(da, 0);
69 void *darr_push_impl(void *da, void *item)
77 if(nelem >= desc->max_elem) {
79 int newsz = desc->max_elem ? desc->max_elem * 2 : 1;
81 da = darr_resize_impl(da, newsz);
87 memcpy((char*)da + desc->nelem * desc->szelem, item, desc->szelem);
93 void *darr_pop_impl(void *da)
101 if(!nelem) return da;
103 if(nelem <= desc->max_elem / 3) {
105 int newsz = desc->max_elem / 2;
107 da = darr_resize_impl(da, newsz);
116 void *darr_finalize(void *da)
118 struct arrdesc *desc = DESC(da);
119 memmove(desc, da, desc->bufsz);