8 #define INITIAL_CAPACITY 64
13 #define CHECK(x) _check(x)
20 assert(v->capacity > 0);
21 assert(v->length <= v->capacity);
22 assert(v->length < SIZE_MAX);
27 v_new(void (*elt_dtor)(void *))
29 vector *v = malloc(sizeof *v);
30 void **elts = malloc(INITIAL_CAPACITY * sizeof *elts);
38 .capacity = INITIAL_CAPACITY,
56 v_length(const vector *v)
58 return v ? v->length : SIZE_MAX;
62 v_set_length(vector *v, size_t len)
64 if (!v || len == SIZE_MAX)
66 if (v->elt_dtor) /* free any, if necessary */
67 for (size_t i = len; i < v->length; i++)
68 v->elt_dtor(v->elts[i]);
69 if (!v_reserve_capacity(v, len))
71 for (size_t i = v->length; i < len; i++)
80 v_capacity(const vector *v)
82 return v ? v->capacity : 0;
86 v_reserve_capacity(vector *v, size_t desired)
90 if (desired <= v->capacity)
92 size_t n = v->capacity;
93 while (n < desired && n < SIZE_MAX/2)
96 n = desired; /* desired >= SIZE_MAX/2 */
97 void **enlarged = realloc(v->elts, n);
108 v_is_empty(const vector *v)
110 return v_length(v) == 0;
114 v_at(const vector *v, size_t i)
116 if (!v || i >= v->length)
125 v_first(const vector *v)
131 v_last(const vector *v)
133 /* when length is 0, length-1 is SIZE_MAX */
134 return v_at(v, v_length(v)-1);
138 v_append(vector *v, void *e)
140 return v_insert(v, v_length(v), e);
144 v_prepend(vector *v, void *e)
146 return v_insert(v, 0, e);
150 v_remove_first(vector *v)
152 return v_remove(v, 0, 1);
156 v_remove_last(vector *v)
158 return v_remove(v, v_length(v)-1, 1);
162 v_swap(vector *v, size_t i, size_t j)
164 if (!v || i >= v->length || j >= v->length)
166 void *t = v->elts[i];
167 v->elts[i] = v->elts[j];
181 v_find_index(const vector *v, const void *needle,
182 int (*cmp)(const void *, const void *))
186 for (size_t i = 0; i < v->length; i++)
187 if (cmp(v->elts[i], needle) == 0)
193 v_find_index_last(const vector *v, const void *needle,
194 int (*cmp)(const void *, const void *))
198 for (size_t i = v->length-1; i < SIZE_MAX; i--)
199 if (cmp(v->elts[i], needle) == 0)