8 /* The array descriptor keeps auxilliary information needed to manipulate
9 * the dynamic array. It's allocated adjacent to the array buffer.
14 int bufsz; /* not including the descriptor */
17 #define DESC(x) ((struct arrdesc*)((char*)(x) - sizeof(struct arrdesc)))
19 void *darr_alloc(int elem, int szelem)
23 desc = malloc_nf(elem * szelem + sizeof *desc);
24 desc->nelem = desc->max_elem = elem;
25 desc->szelem = szelem;
26 desc->bufsz = elem * szelem;
27 return (char*)desc + sizeof *desc;
30 void darr_free(void *da)
37 void *darr_resize_impl(void *da, int elem)
45 newsz = desc->szelem * elem;
46 desc = realloc_nf(desc, newsz + sizeof *desc);
48 desc->nelem = desc->max_elem = elem;
50 return (char*)desc + sizeof *desc;
53 int darr_empty(void *da)
55 return DESC(da)->nelem ? 0 : 1;
58 int darr_size(void *da)
60 return DESC(da)->nelem;
64 void *darr_clear_impl(void *da)
66 return darr_resize_impl(da, 0);
70 void *darr_push_impl(void *da, void *item)
78 if(nelem >= desc->max_elem) {
80 int newsz = desc->max_elem ? desc->max_elem * 2 : 1;
82 da = darr_resize_impl(da, newsz);
88 memcpy((char*)da + desc->nelem * desc->szelem, item, desc->szelem);
94 void *darr_pop_impl(void *da)
102 if(!nelem) return da;
104 if(nelem <= desc->max_elem / 3) {
106 int newsz = desc->max_elem / 2;
108 da = darr_resize_impl(da, newsz);
117 void *darr_finalize(void *da)
119 struct arrdesc *desc = DESC(da);
120 memmove(desc, da, desc->bufsz);