65static void free_space_at(dynarr_t *
const dynarr,
const size_t index,
const size_t amount);
71static void make_space_at(dynarr_t *
const dynarr,
const size_t index,
size_t amount);
96 assert(next_shrink_at <= grow_at);
105 if (NULL == dynarr)
return NULL;
124 assert((0 <
get_dynarr_header(dynarr)->ext_header_size) &&
"extension header was not alloc'd.");
171void *
dynarr_get(
const dynarr_t *
const dynarr,
const size_t index)
174 assert((index <
dynarr_size(dynarr)) &&
"Index out of bounds.");
179void dynarr_set(dynarr_t *
const dynarr,
const size_t index,
const void *value)
182 assert((index <
dynarr_size(dynarr)) &&
"Index out of bounds.");
191 assert((index <
dynarr_size(dynarr)) &&
"Index out of bounds.");
199 assert((0 <
dynarr_size(dynarr)) &&
"No elements in the array!");
207 assert((0 <
dynarr_size(dynarr)) &&
"No elements in the array!");
214 const void *
const value,
227 const void *
const value,
241 assert(dynarr && *dynarr);
250 assert(dynarr && *dynarr);
259 assert(dynarr && *dynarr);
266 assert(dynarr && *dynarr);
275 assert(dynarr && *dynarr);
293 const void *
const value)
295 assert(dynarr && *dynarr);
311 const void *
const value,
324 const void *
const value,
329 assert(dynarr && *dynarr);
338 if (index) *index = place;
344 const void *
const value,
345 const compare_t cmp,
void *param,
348 assert(dynarr && *dynarr);
360 const void *
const value,
365 assert(dynarr && *dynarr);
383 assert(dynarr && *dynarr);
392 assert(dynarr && *dynarr);
398 return shrink(dynarr, amount);
403 const predicate_t predicate,
407 assert(dynarr && *dynarr);
410 for (
size_t i =
dynarr_size(*dynarr); i > 0 && removed < limit; --i)
412 if (predicate(
dynarr_get(*dynarr, i - 1), param))
419 return shrink(dynarr, removed);
424 const dynarr_t *
const second,
436 if (!merged)
return NULL;
444 for (; first_i < first_size && second_i < second_size ;)
448 ssize_t res = cmp(f, s, param);
452 ++first_i; ++second_i;
472 if (first_size == second_size)
return merged;
479 if (first_size > second_size)
483 src_size = first_size;
488 src_size = second_size;
491 for (; src_i < src_size; ++src_i)
507 const foreach_t func,
517 const aggregate_t func,
529 const transform_t func,
566 const size_t size =
dynarr_size(*dynarr) + amount_to_add;
570 while (size >= grow_at)
576 const size_t new_cap = ceil(capacity);
589 const size_t size =
dynarr_size(*dynarr) - amount_to_remove;
593 while (size < shrink_at)
600 size_t new_cap = floor(capacity);
601 new_cap = new_cap < initial_cap ? initial_cap : new_cap;
612static void free_space_at(dynarr_t *
const dynarr,
const size_t index,
const size_t amount)
622 const size_t rest_from_index = size - index;
624 if (amount >= rest_from_index)
626 header->
size -= rest_from_index;
631 size_t rest = rest_from_index - amount;
632 char *to = (
char*)
dynarr_get(dynarr, 0) + element_size * index;
633 char *from = to + element_size * amount;
635 memmove(to, from, element_size * rest);
636 header->
size -= amount;
641static void make_space_at(dynarr_t *
const dynarr,
const size_t index,
size_t amount)
648 amount += index - size;
654 char *from = (
char*)
dynarr_get(dynarr, 0) + element_size * index;
655 char *to = from + element_size * amount;
657 memmove(to, from, element_size * (size - index));
660 header->
size += amount;
676 const size_t middle = (start + end) / 2;
677 const void *middle_value =
dynarr_get(dynarr, middle);
679 if (0 == cmp(value, middle_value, param))
684 if (0 < cmp(value, middle_value, param))
static size_t binary_find_insert_place(const dynarr_t *const dynarr, const void *value, const size_t start, const size_t end, const compare_t cmp, void *param)
static dynarr_opts_t get_opts(const dynarr_t *const dynarr)
static dynarr_header_t * get_dynarr_header(const dynarr_t *const dynarr)
Describes dynarr public interface.
dynarr_status_t
Represents operation error codes.
@ DYNARR_GROW_ERROR
Allocation error on grow.
@ DYNARR_SHRINK_ERROR
Success status inherited from VECTOR_ALLOC_ERROR.
@ DYNARR_SUCCESS
Success status inherited from VECTOR_SUCCESS.
static dynarr_status_t grow(dynarr_t **const dynarr, const size_t amount_to_add)
static dynarr_status_t shrink(dynarr_t **const dynarr, const size_t amount_to_remove)
static void free_space_at(dynarr_t *const dynarr, const size_t index, const size_t amount)
static void make_space_at(dynarr_t *const dynarr, const size_t index, size_t amount)
int(* foreach_t)(const void *const element, void *const param)
dynarr_status_t dynarr_spread_insert(dynarr_t **const dynarr, const size_t index, const size_t amount, const void *const value)
Insert single value as an element range.
dynarr_t * dynarr_binary_merge(const dynarr_t *const first, const dynarr_t *const second, const compare_t cmp, void *const param)
Non-destructive merge of two sorted dynarrs.
dynarr_status_t dynarr_remove_range(dynarr_t **const dynarr, const size_t index, const size_t amount)
Removes range of elements from a dynarr.
int vector_aggregate(const vector_t *const vector, const size_t limit, const aggregate_t func, void *const acc, void *const param)
dynarr_status_t dynarr_append(dynarr_t **const dynarr, const void *const value)
Appends an element to the tail of a dynarr.
dynarr_status_t dynarr_binary_reserve(dynarr_t **const dynarr, const void *const value, const compare_t cmp, void *const param, size_t *const index)
Reserve space for an element in sorted dynarr.
int dynarr_foreach(const dynarr_t *const dynarr, const foreach_t func, void *const param)
void dynarr_set(dynarr_t *const dynarr, const size_t index, const void *value)
Sets element at given index to a value.
dynarr_status_t dynarr_pop_back(dynarr_t **const dynarr)
Removes an element from the tail of a dynarr.
dynarr_status_t dynarr_pop_front(dynarr_t **const dynarr)
Removes an element from the head of a dynarr.
dynarr_status_t dynarr_binary_insert_uniq(dynarr_t **const dynarr, const void *const value, const compare_t cmp, void *param, size_t *const index)
Binary unique insert.
dynarr_status_t dynarr_prepend(dynarr_t **const dynarr, const void *const value)
Prepends an element to the head of a dynarr.
void * dynarr_first(const dynarr_t *const dynarr)
Access first element of a dynarr.
size_t dynarr_binary_find_insert_place(const dynarr_t *const dynarr, const void *const value, const compare_t cmp, void *param)
Binary search for binary insert support.
void vector_spread(vector_t *const vector, const size_t index, const size_t amount)
void * dynarr_last(const dynarr_t *const dynarr)
Access last element if a dynarr.
int dynarr_transform(dynarr_t *const dynarr, const transform_t func, void *const param)
void dynarr_set_zero(dynarr_t *const dynarr, const size_t index)
Sets element at given index to a zero value.
void * dynarr_get(const dynarr_t *const dynarr, const size_t index)
Returns pointer for the element at index.
void * vector_get(const vector_t *const vector, const size_t index)
int vector_foreach(const vector_t *const vector, const size_t limit, const foreach_t func, void *const param)
dynarr_status_t dynarr_remove_if(dynarr_t **const dynarr, const predicate_t predicate, const size_t limit, void *const param)
Removes limit elements that match predicate.
void vector_set(vector_t *const vector, const size_t index, const void *const value)
dynarr_status_t dynarr_insert(dynarr_t **const dynarr, const size_t index, const void *value)
Inserts new element into a dynarr.
int dynarr_aggregate(const dynarr_t *const dynarr, const aggregate_t func, void *const acc, void *const param)
dynarr_status_t dynarr_binary_insert(dynarr_t **const dynarr, const void *const value, const compare_t cmp, void *param, size_t *const index)
Binary insert.
dynarr_status_t dynarr_remove(dynarr_t **const dynarr, const size_t index)
Removes an element from a dynarr.
void vector_set_zero(vector_t *const vector, const size_t index)
void dynarr_clear(dynarr_t *const dynarr)
Clean (reset) contents of the dynarr.
void * dynarr_get_ext_header(const dynarr_t *const dynarr)
Retrieve a location of extended header.
void * vector_get_ext_header(const vector_t *const vector)
#define vector_create(...)
dynarr_t * dynarr_clone(const dynarr_t *const dynarr)
Duplicate a dynarr.
vector_status_t vector_resize(vector_t **const vector, const size_t capacity, const vector_status_t error)
vector_t * vector_clone(const vector_t *const vector)
dynarr_t * dynarr_create_(const dynarr_opts_t *const opts)
Constructor of the dynamic array.
void vector_destroy(vector_t *const vector)
void dynarr_destroy(dynarr_t *const dynarr)
Deallocates a dynamic array.
size_t dynarr_capacity(const dynarr_t *const dynarr)
Access current capacity of the dynarr.
size_t dynarr_initial_capacity(const dynarr_t *const dynarr)
Access initial capacity property.
size_t vector_element_size(const vector_t *const vector)
size_t vector_capacity(const vector_t *const vector)
size_t dynarr_size(const dynarr_t *const dynarr)
Access size property of a dynarr.
alloc_opts_t vector_alloc_opts(const vector_t *const vector)
void * vector_binary_find(const vector_t *const vector, const void *const value, const size_t limit, const compare_t cmp, void *param)
ssize_t dynarr_binary_find_index(const dynarr_t *const dynarr, const void *const value, const compare_t cmp, void *const param)
Binary search for the element with matching value.
ssize_t vector_binary_find_index(const vector_t *const vector, const void *const value, const size_t limit, const compare_t cmp, void *const param)
void * dynarr_binary_find(const dynarr_t *const dynarr, const void *const value, const compare_t cmp, void *const param)
Binary search for the element with matching value.
float grow_threshold
Fraction of the capacity need to be used to trigger growing.
float shrink_threshold
Fraction of the capacity in use at which srink will be performed.
float grow_factor
Multiplier that is applied to dynarr capactity on resize.
#define TMP_REF(type, value)