19 sparse_foreach_t func;
27 sparse_aggregate_t func;
30adapt_aggregate_param_t;
42static ssize_t cmp_pairs_by_index(
const void *
const value,
const void *
const element,
void *
const param);
49static ssize_t cmp_index_to_pair(
const void *
const value,
const void *
const element,
void *
const param);
51static bool match_by_index(
const void *
const element,
void *
const index);
55static sparse_header_t *get_sparse_header(
const sparse_t *
const array);
57static int adapt_foreach(
const void *
const element,
void *
const param);
59static int adapt_aggregate(
const void *
const element,
void *
const acc,
void *
const param);
66sparse_t *sparse_create_(
const sparse_opts_t *
const opts)
75 .element_size =
sizeof(
size_t) + calc_aligned_size(opts->element_size, ALIGNMENT),
76 .initial_cap = opts->initial_cap,
77 .ext_header_size =
sizeof(sparse_header_t),
78 .grow_factor = opts->grow_factor,
79 .grow_threshold = opts->grow_threshold,
80 .shrink_threshold = opts->shrink_threshold
83 if (!array)
return NULL;
86 *ext_header = (sparse_header_t) {
87 .element_size = opts->element_size
94sparse_t *sparse_clone(
const sparse_t *
const array)
101void sparse_destroy(sparse_t *
const array)
108size_t sparse_element_size(
const sparse_t *
const array)
111 return get_sparse_header(array)->element_size;
115size_t sparse_first_index(
const sparse_t *
const array)
118 assert(sparse_size(array) != 0);
125size_t sparse_last_index(
const sparse_t *
const array)
128 assert(sparse_size(array) != 0);
135size_t sparse_first_free_index(
const sparse_t *
const array)
139 const size_t size = sparse_size(array);
142 for (
size_t i = 0; i < size; ++i)
144 pair_t *pair = (pair_t *)
dynarr_get(array, i);
145 if (pair->index > index)
149 index = pair->index + 1;
155size_t sparse_last_free_index(
const sparse_t *
const array)
158 if (sparse_size(array) == 0)
return 0;
164size_t sparse_size(
const sparse_t *
const array)
171sparse_status_t sparse_insert(sparse_t **
const array,
const size_t index,
const void *
const value)
173 assert(array && *array);
177 if (vector_binary_find(*array, &index,
dynarr_size(*array), cmp_index_to_pair, NULL))
179 return SPARSE_INSERT_INDEX_OVERRIDE;
184 if (DYNARR_SUCCESS != status)
return (sparse_status_t)status;
188 memcpy(pair->value, value, sparse_element_size(*array));
190 return SPARSE_SUCCESS;
194sparse_status_t sparse_insert_reserve(sparse_t **
const array,
const size_t index)
196 assert(array && *array);
199 if (vector_binary_find(*array, &index,
dynarr_size(*array), cmp_index_to_pair, NULL))
201 return SPARSE_INSERT_INDEX_OVERRIDE;
206 if (DYNARR_SUCCESS != status)
return (sparse_status_t)status;
211 return SPARSE_SUCCESS;
215sparse_status_t sparse_remove(sparse_t **
const array,
const size_t index)
217 assert(array && *array);
221 if (DYNARR_SHRINK_ERROR == status)
return SPARSE_ALLOC_ERROR;
222 return SPARSE_SUCCESS;
226void* sparse_get(
const sparse_t *
const array,
const size_t index)
229 pair_t *p = (pair_t *)vector_binary_find(array, &index,
dynarr_size(array), cmp_index_to_pair, NULL);
235bool sparse_is_empty_element(
const sparse_t *
const array,
const size_t index)
238 return !vector_binary_find(array, &index,
dynarr_size(array), cmp_index_to_pair, NULL);
242int sparse_foreach(
const sparse_t *
const sparse,
243 const sparse_foreach_t func,
249 adapt_foreach_param_t aparam = {
258int sparse_aggregate(
const sparse_t *
const sparse,
259 const sparse_aggregate_t func,
266 adapt_aggregate_param_t aparam = {
275int sparse_transform(sparse_t *
const sparse,
276 const sparse_transform_t func,
282 return sparse_foreach(sparse, (sparse_foreach_t)func, param);
290static ssize_t cmp_pairs_by_index(
const void *
const value,
const void *
const element,
void *
const param)
293 return (ssize_t) ((
const pair_t *)value)->index - ((
const pair_t *)element)->index;
297static ssize_t cmp_index_to_pair(
const void *
const value,
const void *
const element,
void *
const param)
300 return (ssize_t)*(
size_t*) value - ((
const pair_t *) element)->index;
304static bool match_by_index(
const void *
const element,
void *
const index)
306 return ((pair_t*)element)->index == *(
size_t*)index;
310static sparse_header_t *get_sparse_header(
const sparse_t *
const array)
316static int adapt_foreach(
const void *
const element,
void *
const param)
318 const pair_t *p = element;
319 adapt_foreach_param_t *adapt = param;
320 return adapt->func(p->index, &p->value, adapt->param);
324static int adapt_aggregate(
const void *
const element,
void *
const acc,
void *
const param)
326 const pair_t *p = element;
327 adapt_aggregate_param_t *adapt = param;
328 return adapt->func(p->index, &p->value, acc, adapt->param);
#define dynarr_create(...)
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)
int dynarr_foreach(const dynarr_t *const dynarr, const foreach_t func, void *const param)
void * dynarr_get_ext_header(const dynarr_t *const dynarr)
dynarr_t * dynarr_clone(const dynarr_t *const dynarr)
void * dynarr_first(const dynarr_t *const dynarr)
void * dynarr_last(const dynarr_t *const dynarr)
void * dynarr_get(const dynarr_t *const dynarr, const size_t index)
dynarr_status_t dynarr_remove_if(dynarr_t **const dynarr, const predicate_t predicate, const size_t limit, void *const param)
int dynarr_aggregate(const dynarr_t *const dynarr, const aggregate_t func, void *const acc, void *const param)
void dynarr_destroy(dynarr_t *const dynarr)
size_t dynarr_size(const dynarr_t *const dynarr)