2 RetroRay - integrated standalone vintage modeller/renderer
3 Copyright (C) 2023 John Tsiombikas <nuclear@mutantstargoat.com>
5 This program is free software: you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation, either version 3 of the License, or
8 (at your option) any later version.
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
15 You should have received a copy of the GNU General Public License
16 along with this program. If not, see <https://www.gnu.org/licenses/>.
25 /* The array descriptor keeps auxilliary information needed to manipulate
26 * the dynamic array. It's allocated adjacent to the array buffer.
31 int bufsz; /* not including the descriptor */
34 #define DESC(x) ((struct arrdesc*)((char*)(x) - sizeof(struct arrdesc)))
36 void *darr_alloc(int elem, int szelem)
40 desc = malloc_nf(elem * szelem + sizeof *desc);
41 desc->nelem = desc->max_elem = elem;
42 desc->szelem = szelem;
43 desc->bufsz = elem * szelem;
44 return (char*)desc + sizeof *desc;
47 void darr_free(void *da)
54 void *darr_resize_impl(void *da, int elem)
62 newsz = desc->szelem * elem;
63 desc = realloc_nf(desc, newsz + sizeof *desc);
65 desc->nelem = desc->max_elem = elem;
67 return (char*)desc + sizeof *desc;
70 int darr_empty(void *da)
72 return DESC(da)->nelem ? 0 : 1;
75 int darr_size(void *da)
77 return DESC(da)->nelem;
81 void *darr_clear_impl(void *da)
83 return darr_resize_impl(da, 0);
87 void *darr_push_impl(void *da, void *item)
95 if(nelem >= desc->max_elem) {
97 int newsz = desc->max_elem ? desc->max_elem * 2 : 1;
99 da = darr_resize_impl(da, newsz);
105 memcpy((char*)da + desc->nelem * desc->szelem, item, desc->szelem);
111 void *darr_pop_impl(void *da)
113 struct arrdesc *desc;
119 if(!nelem) return da;
121 if(nelem <= desc->max_elem / 3) {
123 int newsz = desc->max_elem / 2;
125 da = darr_resize_impl(da, newsz);
134 void *darr_finalize(void *da)
136 struct arrdesc *desc = DESC(da);
137 memmove(desc, da, desc->bufsz);