5 #include "internal/alloc.h"
6 #include "derp/vector.h"
7 #include "derp/common.h"
9 #define INITIAL_CAPACITY 64
12 #define CHECK(x) (void)(x)
14 #define CHECK(x) internal_check(x)
17 #define SWAP(x, y) do { void *swaptmp = (x); (x) = (y); (y) = swaptmp; } while (0)
29 internal_check(const vector *v)
32 assert(v->capacity > 0);
33 /* test that capacity is a power of two if not maxed out
34 * https://graphics.stanford.edu/~seander/bithacks.html#DetermineIfPowerOf2
36 if (v->capacity < SIZE_MAX)
37 assert((v->capacity & (v->capacity - 1)) == 0);
38 assert(v->length <= v->capacity);
44 vector *v = internal_malloc(sizeof *v);
45 void **elts = internal_malloc(INITIAL_CAPACITY * sizeof *elts);
53 .capacity = INITIAL_CAPACITY,
61 v_dtor(vector *v, dtor *elt_dtor, void *dtor_aux)
65 v->elt_dtor = elt_dtor;
66 v->dtor_aux = dtor_aux;
75 internal_free(v->elts);
80 v_length(const vector *v)
82 return v ? v->length : 0;
86 v_set_length(vector *v, size_t desired)
90 if (v->elt_dtor) /* free any, if necessary */
91 for (size_t i = desired; i < v->length; i++)
92 v->elt_dtor(v->elts[i], v->dtor_aux);
93 if (v_reserve_capacity(v, desired) < desired)
95 for (size_t i = v->length; i < desired; i++)
104 v_capacity(const vector *v)
106 return v ? v->capacity : 0;
110 v_reserve_capacity(vector *v, size_t desired)
114 if (desired <= v->capacity)
117 size_t n = v->capacity;
118 while (n < desired) {
119 /* Check if doubling would overflow */
120 if (n > SIZE_MAX / 2)
125 void **enlarged = internal_realloc(v->elts, n * sizeof *v->elts);
136 v_is_empty(const vector *v)
138 return v_length(v) == 0;
142 v_at(const vector *v, size_t i)
144 if (!v || i >= v->length)
150 v_first(const vector *v)
156 v_last(const vector *v)
158 /* successfully fails when length is 0 */
159 return v_at(v, v_length(v)-1);
163 v_append(vector *v, void *e)
165 return v_insert(v, v_length(v), e);
169 v_prepend(vector *v, void *e)
171 return v_insert(v, 0, e);
175 v_remove_first(vector *v)
177 return v_remove(v, 0);
181 v_remove_last(vector *v)
183 return v_remove(v, v_length(v)-1);
187 v_remove(vector *v, size_t i)
189 if (!v || i >= v->length)
191 void *elt = v->elts[i];
192 memmove(v->elts+i, v->elts+i+1, (v->length - (i+1)) * sizeof *v->elts);
200 v_insert(vector *v, size_t i, void *elt)
202 if (!v || v_reserve_capacity(v, v->length+1) < v->length+1)
204 memmove(v->elts+i+1, v->elts+i, (v->length - i) * sizeof *v->elts);
213 v_swap(vector *v, size_t i, size_t j)
215 if (!v || i >= v->length || j >= v->length)
217 SWAP(v->elts[i], v->elts[j]);
230 v_find_index(const vector *v, const void *needle,
231 comparator *cmp, void *aux)
235 for (size_t i = 0; i < v->length; i++)
236 if (cmp(v->elts[i], needle, aux) == 0)
242 v_find_last_index(const vector *v, const void *needle,
243 comparator *cmp, void *aux)
247 for (size_t i = v->length-1; i < SIZE_MAX; i--)
248 if (cmp(v->elts[i], needle, aux) == 0)
253 /* from Bentley, https://www.youtube.com/watch?v=QvgYAQzg1z8 */
255 internal_quicksort(vector *v, size_t lo, size_t hi,
256 comparator *cmp, void *aux)
261 for (i = lo+1; i <= hi; i++)
262 if (cmp(v->elts[i], v->elts[lo], aux) < 0)
265 SWAP(v->elts[i], v->elts[m]);
267 SWAP(v->elts[lo], v->elts[m]);
269 if (m > 0) /* avoid wrapping size_t */
270 internal_quicksort(v, lo, m-1, cmp, aux);
271 internal_quicksort(v, m+1, hi, cmp, aux);
275 v_sort(vector *v, comparator *cmp, void *aux)
279 internal_quicksort(v, 0, v->length-1, cmp, aux);
288 size_t n = v_length(v);
291 for (size_t i = n-1; i >= n/2; i--)
292 SWAP(v->elts[i], v->elts[n-i-1]);