5 #include "system/stacktrace.h"
7 #include "system/nth_alloc.h"
10 #define DYNARRAY_INIT_CAPACITY 8
21 Dynarray *create_dynarray(size_t element_size)
25 Dynarray *dynarray = PUSH_LT(lt, nth_calloc(1, sizeof(Dynarray)), free);
26 if (dynarray == NULL) {
31 dynarray->element_size = element_size;
32 dynarray->capacity = DYNARRAY_INIT_CAPACITY;
35 dynarray->data = PUSH_LT(lt, nth_calloc(DYNARRAY_INIT_CAPACITY, element_size), free);
36 if (dynarray->data == NULL) {
43 void destroy_dynarray(Dynarray *dynarray)
45 trace_assert(dynarray);
46 RETURN_LT0(dynarray->lt);
49 void *dynarray_pointer_at(Dynarray *dynarray, size_t index) {
50 trace_assert(index < dynarray->count);
51 return dynarray->data + index * dynarray->element_size;
54 size_t dynarray_count(const Dynarray *dynarray)
56 trace_assert(dynarray);
57 return dynarray->count;
60 void *dynarray_data(Dynarray *dynarray)
62 trace_assert(dynarray);
63 return dynarray->data;
66 void dynarray_clear(Dynarray *dynarray)
68 trace_assert(dynarray);
73 int dynarray_grow(Dynarray *dynarray)
75 if (dynarray->count < dynarray->capacity) {
79 void *new_data = nth_realloc(
81 dynarray->capacity * dynarray->element_size * 2);
82 if (new_data == NULL) {
86 dynarray->data = REPLACE_LT(dynarray->lt, dynarray->data, new_data);
87 if (dynarray->data == NULL) {
91 dynarray->capacity *= 2;
96 int dynarray_push(Dynarray *dynarray, const void *element)
98 trace_assert(dynarray);
99 trace_assert(element);
101 if (dynarray_grow(dynarray) < 0) {
106 (char*) dynarray->data + dynarray->count * dynarray->element_size,
108 dynarray->element_size);
115 bool dynarray_contains(const Dynarray *dynarray,
118 trace_assert(dynarray);
119 trace_assert(element);
121 for (size_t i = 0; i < dynarray->count; ++i) {
122 if (memcmp((const char*)dynarray->data + i * dynarray->element_size,
123 (const char*)element,
124 dynarray->element_size) == 0) {
132 void dynarray_delete_at(Dynarray *dynarray, size_t index)
134 trace_assert(dynarray);
135 trace_assert(index < dynarray->count);
137 dynarray->data + index * dynarray->element_size,
138 dynarray->data + (index + 1) * dynarray->element_size,
139 dynarray->element_size * (dynarray->count - index - 1));
143 void dynarray_insert_before(Dynarray *dynarray, size_t index, void *element)
145 trace_assert(dynarray);
146 trace_assert(element);
147 trace_assert(index <= dynarray->count);
149 dynarray_grow(dynarray);
152 dynarray->data + (index + 1) * dynarray->element_size,
153 dynarray->data + index * dynarray->element_size,
154 dynarray->element_size * (dynarray->count - index));
157 dynarray->data + index * dynarray->element_size,
159 dynarray->element_size);
164 int dynarray_push_empty(Dynarray *dynarray)
166 trace_assert(dynarray);
168 if (dynarray_grow(dynarray) < 0) {
173 (char*) dynarray->data + dynarray->count * dynarray->element_size,
175 dynarray->element_size);
182 // TODO(#980): dynarray_push and dynarray_push_empty have duplicate codez
184 void dynarray_pop(Dynarray *dynarray, void *element)
186 trace_assert(dynarray);
187 trace_assert(dynarray->count > 0);
194 dynarray->data + dynarray->count * dynarray->element_size,
195 dynarray->element_size);
199 void dynarray_replace_at(Dynarray *dynarray, size_t index, void *element)
201 trace_assert(dynarray);
202 trace_assert(element);
203 trace_assert(index < dynarray->count);
206 dynarray->data + index * dynarray->element_size,
208 dynarray->element_size);
211 void dynarray_copy_to(Dynarray *dynarray, void *dest, size_t index)
213 trace_assert(dynarray);
215 trace_assert(index < dynarray->count);
217 memcpy(dest, dynarray->data + index * dynarray->element_size, dynarray->element_size);
220 void dynarray_swap(Dynarray *dynarray, size_t i, size_t j)
222 trace_assert(dynarray);
223 trace_assert(i < dynarray->count);
224 trace_assert(j < dynarray->count);
228 char *a = dynarray_pointer_at(dynarray, i);
229 char *b = dynarray_pointer_at(dynarray, j);
231 for (size_t k = 0; k < dynarray->element_size; ++k) {