Dynarr 0.0.1
C dynamic array
Loading...
Searching...
No Matches
dynarr.c
Go to the documentation of this file.
1
7#include "dynarr.h"
8#include "vector.h"
9
10#include <assert.h> /* assert */
11#include <string.h> /* memcpy, memset */
12#include <math.h> /* ceil, floor */
13#include <stdio.h> /* fprintf */
14
22typedef struct dynarr_header_t
23{
25 size_t size;
26 size_t initial_cap;
30}
32
33
34/* *
35* === Forward Declarations === *
36* */
37
41static dynarr_opts_t get_opts(const dynarr_t *const dynarr);
42
46static dynarr_header_t *get_dynarr_header(const dynarr_t *const dynarr);
47
55static dynarr_status_t grow(dynarr_t **const dynarr, const size_t amount_to_add);
56
60static dynarr_status_t shrink(dynarr_t **const dynarr, const size_t amount_to_remove);
61
65static void free_space_at(dynarr_t *const dynarr, const size_t index, const size_t amount);
66
71static void make_space_at(dynarr_t *const dynarr, const size_t index, /*mut*/ size_t amount);
72
78static size_t binary_find_insert_place(const dynarr_t *const dynarr,
79 const void *value,
80 const size_t start,
81 const size_t end,
82 const compare_t cmp,
83 void *param);
84
85/* *
86* === API Implementation === *
87* */
88
89dynarr_t *dynarr_create_(const dynarr_opts_t *const opts)
90{
91 assert(opts);
92 assert(opts->element_size);
93
94 const size_t grow_at = ceil(opts->initial_cap * opts->grow_threshold);
95 const size_t next_shrink_at = floor(grow_at * opts->shrink_threshold);
96 assert(next_shrink_at <= grow_at);
97
98 dynarr_t *dynarr = vector_create (
99 .element_size = opts->element_size,
100 .initial_cap = opts->initial_cap,
101 .ext_header_size = sizeof(dynarr_header_t) + opts->ext_header_size,
102 .alloc_opts = opts->alloc_opts,
103 );
104
105 if (NULL == dynarr) return NULL;
106
107 dynarr_header_t *header = get_dynarr_header(dynarr);
108 *header = (dynarr_header_t){
110 .size = 0,
111 .initial_cap = opts->initial_cap,
112 .grow_factor = opts->grow_factor,
113 .grow_threshold = opts->grow_threshold,
114 .shrink_threshold = opts->shrink_threshold
115 };
116
117 return dynarr;
118}
119
120
121void* dynarr_get_ext_header(const dynarr_t *const dynarr)
122{
123 assert(dynarr);
124 assert((0 < get_dynarr_header(dynarr)->ext_header_size) && "extension header was not alloc'd.");
125 return (char*) vector_get_ext_header(dynarr) + sizeof(dynarr_header_t);
126}
127
128
129dynarr_t *dynarr_clone(const dynarr_t *const dynarr)
130{
131 assert(dynarr);
132 return vector_clone(dynarr);
133}
134
135
136void dynarr_destroy(dynarr_t *const dynarr)
137{
138 assert(dynarr);
139 vector_destroy(dynarr);
140}
141
142
143void dynarr_clear(dynarr_t *const dynarr)
144{
145 assert(dynarr);
146 get_dynarr_header(dynarr)->size = 0;
147}
148
149
150size_t dynarr_size(const dynarr_t *const dynarr)
151{
152 assert(dynarr);
153 return get_dynarr_header(dynarr)->size;
154}
155
156
157size_t dynarr_initial_capacity(const dynarr_t *const dynarr)
158{
159 assert(dynarr);
160 return get_dynarr_header(dynarr)->initial_cap;
161}
162
163
164size_t dynarr_capacity(const dynarr_t *const dynarr)
165{
166 assert(dynarr);
167 return vector_capacity(dynarr);
168}
169
170
171void *dynarr_get(const dynarr_t *const dynarr, const size_t index)
172{
173 assert(dynarr);
174 assert((index < dynarr_size(dynarr)) && "Index out of bounds.");
175 return vector_get(dynarr, index);
176}
177
178
179void dynarr_set(dynarr_t *const dynarr, const size_t index, const void *value)
180{
181 assert(dynarr);
182 assert((index < dynarr_size(dynarr)) && "Index out of bounds.");
183 assert(value);
184 vector_set(dynarr, index, value);
185}
186
187
188void dynarr_set_zero(dynarr_t *const dynarr, const size_t index)
189{
190 assert(dynarr);
191 assert((index < dynarr_size(dynarr)) && "Index out of bounds.");
192 vector_set_zero(dynarr, index);
193}
194
195
196void *dynarr_first(const dynarr_t *const dynarr)
197{
198 assert(dynarr);
199 assert((0 < dynarr_size(dynarr)) && "No elements in the array!");
200 return dynarr_get(dynarr, 0);
201}
202
203
204void *dynarr_last(const dynarr_t *const dynarr)
205{
206 assert(dynarr);
207 assert((0 < dynarr_size(dynarr)) && "No elements in the array!");
208 const size_t last = dynarr_size(dynarr) - 1;
209 return dynarr_get(dynarr, last);
210}
211
212
213void *dynarr_binary_find(const dynarr_t *const dynarr,
214 const void *const value,
215 const compare_t cmp,
216 void *const param)
217{
218 assert(dynarr);
219 assert(value);
220 assert(cmp);
221 return vector_binary_find(dynarr, value, dynarr_size(dynarr), cmp,
222 param);
223}
224
225
226ssize_t dynarr_binary_find_index(const dynarr_t *const dynarr,
227 const void *const value,
228 const compare_t cmp,
229 void *const param)
230{
231 assert(dynarr);
232 assert(value);
233 assert(cmp);
234 return vector_binary_find_index(dynarr, value, dynarr_size(dynarr),
235 cmp, param);
236}
237
238
239dynarr_status_t dynarr_append(dynarr_t **const dynarr, const void *const value)
240{
241 assert(dynarr && *dynarr);
242 assert(value);
243
244 return dynarr_insert(dynarr, dynarr_size(*dynarr), value);
245}
246
247
248dynarr_status_t dynarr_prepend(dynarr_t **const dynarr, const void *const value)
249{
250 assert(dynarr && *dynarr);
251 assert(value);
252
253 return dynarr_insert(dynarr, 0, value);
254}
255
256
257dynarr_status_t dynarr_pop_back(dynarr_t **const dynarr)
258{
259 assert(dynarr && *dynarr);
260 return dynarr_remove(dynarr, dynarr_size(*dynarr) - 1);
261}
262
263
264dynarr_status_t dynarr_pop_front(dynarr_t **const dynarr)
265{
266 assert(dynarr && *dynarr);
267 return dynarr_remove(dynarr, 0);
268}
269
270
271dynarr_status_t dynarr_insert(dynarr_t **const dynarr,
272 const size_t index,
273 const void *value)
274{
275 assert(dynarr && *dynarr);
276 assert(index <= dynarr_size(*dynarr));
277 assert(value);
278
279 dynarr_status_t status = grow(dynarr, 1);
280
281 if (DYNARR_SUCCESS != status) return status;
282
283 make_space_at(*dynarr, index, 1);
284 dynarr_set(*dynarr, index, value);
285
286 return DYNARR_SUCCESS;
287}
288
289
290dynarr_status_t dynarr_spread_insert(dynarr_t **const dynarr,
291 const size_t index,
292 const size_t amount,
293 const void *const value)
294{
295 assert(dynarr && *dynarr);
296 assert(index <= dynarr_size(*dynarr));
297 assert(value);
298
299 dynarr_status_t status = grow(dynarr, amount);
300 if (DYNARR_SUCCESS != status) return status;
301
302 make_space_at(*dynarr, index, amount);
303 dynarr_set(*dynarr, index, value);
304 vector_spread(*dynarr, index, amount);
305
306 return DYNARR_SUCCESS;
307}
308
309
310size_t dynarr_binary_find_insert_place(const dynarr_t *const dynarr,
311 const void *const value,
312 const compare_t cmp,
313 void *param)
314{
315 assert(dynarr);
316 assert(value);
317 assert(cmp);
318
319 return binary_find_insert_place(dynarr, value, 0, dynarr_size(dynarr), cmp, param);
320}
321
322
323dynarr_status_t dynarr_binary_insert(dynarr_t **const dynarr,
324 const void *const value,
325 const compare_t cmp,
326 void *param,
327 size_t *const index)
328{
329 assert(dynarr && *dynarr);
330 assert(value);
331 assert(cmp);
332
333 size_t place = dynarr_binary_find_insert_place(*dynarr, value, cmp, param);
334 dynarr_status_t status = dynarr_insert(dynarr, place, value);
335
336 if (DYNARR_SUCCESS != status) return status;
337
338 if (index) *index = place; /* optionally return index of inserted element */
339 return DYNARR_SUCCESS;
340}
341
342
344 const void *const value,
345 const compare_t cmp, void *param,
346 size_t *const index)
347{
348 assert(dynarr && *dynarr);
349 assert(value);
350 assert(cmp);
351
352 ssize_t found = dynarr_binary_find_index(*dynarr, value, cmp, param);
353 if (found) return DYNARR_SUCCESS;
354
355 return dynarr_binary_insert(dynarr, value, cmp, param, index);
356}
357
358
360 const void *const value,
361 const compare_t cmp,
362 void *const param,
363 size_t *const index)
364{
365 assert(dynarr && *dynarr);
366 assert(value);
367 assert(cmp);
368
369 size_t place = dynarr_binary_find_insert_place(*dynarr, value, cmp, param);
370 dynarr_status_t status = grow(dynarr, 1);
371
372 if (DYNARR_SUCCESS != status) return status;
373
374 make_space_at(*dynarr, place, 1);
375 *index = place;
376
377 return DYNARR_SUCCESS;
378}
379
380
381dynarr_status_t dynarr_remove(dynarr_t **const dynarr, const size_t index)
382{
383 assert(dynarr && *dynarr);
384 return dynarr_remove_range(dynarr, index, 1);
385}
386
387
388dynarr_status_t dynarr_remove_range(dynarr_t **const dynarr,
389 const size_t index,
390 const size_t amount)
391{
392 assert(dynarr && *dynarr);
393 assert(amount > 0);
394
395 if (0 == dynarr_size(*dynarr)) return DYNARR_SUCCESS; /* nothing to remove */
396
397 free_space_at(*dynarr, index, amount);
398 return shrink(dynarr, amount);
399}
400
401
402dynarr_status_t dynarr_remove_if(dynarr_t **const dynarr,
403 const predicate_t predicate,
404 const size_t limit,
405 void *const param)
406{
407 assert(dynarr && *dynarr);
408
409 size_t removed = 0;
410 for (size_t i = dynarr_size(*dynarr); i > 0 && removed < limit; --i) /* going in reverse */
411 {
412 if (predicate(dynarr_get(*dynarr, i - 1), param))
413 {
414 free_space_at(*dynarr, i - 1, 1);
415 ++removed;
416 }
417 }
418
419 return shrink(dynarr, removed);
420}
421
422
423dynarr_t *dynarr_binary_merge(const dynarr_t *const first,
424 const dynarr_t *const second,
425 const compare_t cmp,
426 void *const param)
427{
428 assert(first);
429 assert(second);
430 assert(cmp);
431
432 // copy opts from first dynarr
433 // NOTE: maybe its relevant to allow for preallocation without using .initial_cap,
434 // like dynarr_create_prealoc(opts, prealoc_size) ?
435 dynarr_t *merged = dynarr_create_(TMP_REF(dynarr_opts_t, get_opts(first)));
436 if (!merged) return NULL;
437
438 dynarr_status_t status = 0;
439 const size_t first_size = dynarr_size(first);
440 const size_t second_size = dynarr_size(second);
441 size_t first_i = 0;
442 size_t second_i = 0;
443
444 for (; first_i < first_size && second_i < second_size ;)
445 {
446 const void *f = dynarr_get(first, first_i);
447 const void *s = dynarr_get(second, second_i);
448 ssize_t res = cmp(f, s, param);
449 if (0 == res)
450 {
451 status = dynarr_append(&merged, f);
452 ++first_i; ++second_i;
453 }
454 else if (0 > res)
455 {
456 status = dynarr_append(&merged, f);
457 ++first_i;
458 }
459 else // 0 < res
460 {
461 status = dynarr_append(&merged, s);
462 ++second_i;
463 }
464
465 if (DYNARR_SUCCESS != status)
466 {
467 dynarr_destroy(merged);
468 return NULL;
469 }
470 }
471
472 if (first_size == second_size) return merged;
473
474 // copy rest
475 {
476 const dynarr_t *src;
477 size_t src_i;
478 size_t src_size;
479 if (first_size > second_size)
480 {
481 src = first;
482 src_i = first_i;
483 src_size = first_size;
484 }
485 else {
486 src = second;
487 src_i = second_i;
488 src_size = second_size;
489 }
490
491 for (; src_i < src_size; ++src_i)
492 {
493 status = dynarr_append(&merged, dynarr_get(src, src_i));
494 if (DYNARR_SUCCESS != status)
495 {
496 dynarr_destroy(merged);
497 return NULL;
498 }
499 }
500 }
501
502 return merged;
503}
504
505
506int dynarr_foreach(const dynarr_t *const dynarr,
507 const foreach_t func,
508 void *const param)
509{
510 assert(dynarr);
511 assert(func);
512 return vector_foreach(dynarr, dynarr_size(dynarr), func, param);
513}
514
515
516int dynarr_aggregate(const dynarr_t *const dynarr,
517 const aggregate_t func,
518 void *const acc,
519 void *const param)
520{
521 assert(dynarr);
522 assert(func);
523
524 return vector_aggregate(dynarr, dynarr_size(dynarr), func, acc, param);
525}
526
527
528int dynarr_transform(dynarr_t *const dynarr,
529 const transform_t func,
530 void *const param)
531{
532 assert(dynarr);
533 assert(func);
534
535 return dynarr_foreach(dynarr, (foreach_t)func, param);
536}
537
538/* *
539* === Static Functions === *
540* */
541
542static dynarr_opts_t get_opts(const dynarr_t *const dynarr)
543{
544 const dynarr_header_t *header = get_dynarr_header(dynarr);
545 return (dynarr_opts_t) {
546 .element_size = vector_element_size(dynarr),
547 .initial_cap = dynarr_initial_capacity(dynarr),
548 .alloc_opts = vector_alloc_opts(dynarr),
549 .ext_header_size = header->ext_header_size,
550 .grow_factor = header->grow_factor,
551 .grow_threshold = header->grow_threshold,
552 .shrink_threshold = header->shrink_threshold,
553 };
554}
555
556
557static dynarr_header_t *get_dynarr_header(const dynarr_t *const dynarr)
558{
559 return (dynarr_header_t*) vector_get_ext_header(dynarr);
560}
561
562
563static dynarr_status_t grow(dynarr_t **const dynarr, const size_t amount_to_add)
564{
565 const dynarr_header_t *const header = get_dynarr_header(*dynarr);
566 const size_t size = dynarr_size(*dynarr) + amount_to_add;
567 double capacity = dynarr_capacity(*dynarr);
568 size_t grow_at = capacity * header->grow_threshold;
569
570 while (size >= grow_at)
571 {
572 capacity *= header->grow_factor;
573 grow_at = capacity * header->grow_threshold;
574 }
575
576 const size_t new_cap = ceil(capacity);
577 if (new_cap == dynarr_capacity(*dynarr))
578 {
579 return DYNARR_SUCCESS;
580 }
581
583}
584
585
586static dynarr_status_t shrink(dynarr_t **const dynarr, const size_t amount_to_remove)
587{
588 const dynarr_header_t *const header = get_dynarr_header(*dynarr);
589 const size_t size = dynarr_size(*dynarr) - amount_to_remove;
590 double capacity = dynarr_capacity(*dynarr);
591 size_t shrink_at = capacity * header->shrink_threshold;
592
593 while (size < shrink_at)
594 {
595 capacity /= header->grow_factor;
596 shrink_at = capacity * header->shrink_threshold;
597 }
598
599 const size_t initial_cap = dynarr_initial_capacity(*dynarr);
600 size_t new_cap = floor(capacity);
601 new_cap = new_cap < initial_cap ? initial_cap : new_cap;
602
603 if (dynarr_capacity(*dynarr) == new_cap)
604 {
605 return DYNARR_SUCCESS;
606 }
607
609}
610
611
612static void free_space_at(dynarr_t *const dynarr, const size_t index, const size_t amount)
613{
614 const size_t size = dynarr_size(dynarr);
615 dynarr_header_t *header = get_dynarr_header(dynarr);
616
617 if (index >= size)
618 {
619 return; // already free
620 }
621
622 const size_t rest_from_index = size - index;
623
624 if (amount >= rest_from_index)
625 {
626 header->size -= rest_from_index;
627 }
628 else
629 {
630 const size_t element_size = vector_element_size(dynarr);
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;
634
635 memmove(to, from, element_size * rest);
636 header->size -= amount;
637 }
638}
639
640
641static void make_space_at(dynarr_t *const dynarr, const size_t index, size_t amount)
642{
643 const size_t size = dynarr_size(dynarr);
644 dynarr_header_t *header = get_dynarr_header(dynarr);
645
646 if (index > size)
647 {
648 amount += index - size;
649 }
650
651 if (index < size)
652 {
653 const size_t element_size = vector_element_size(dynarr);
654 char *from = (char*) dynarr_get(dynarr, 0) + element_size * index;
655 char *to = from + element_size * amount;
656
657 memmove(to, from, element_size * (size - index));
658 }
659
660 header->size += amount;
661}
662
663
664static size_t binary_find_insert_place(const dynarr_t *const dynarr,
665 const void *value,
666 const size_t start,
667 const size_t end,
668 const compare_t cmp,
669 void *param)
670{
671 if (start == end)
672 {
673 return start;
674 }
675
676 const size_t middle = (start + end) / 2;
677 const void *middle_value = dynarr_get(dynarr, middle);
678
679 if (0 == cmp(value, middle_value, param))
680 {
681 return middle + 1;
682 }
683
684 if (0 < cmp(value, middle_value, param))
685 {
686 return binary_find_insert_place(dynarr, value, middle + 1, end, cmp, param);
687 }
688
689 return binary_find_insert_place(dynarr, value, start, middle, cmp, param);
690}
691
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)
Definition dynarr.c:664
static dynarr_opts_t get_opts(const dynarr_t *const dynarr)
Definition dynarr.c:542
static dynarr_header_t * get_dynarr_header(const dynarr_t *const dynarr)
Definition dynarr.c:557
Describes dynarr public interface.
dynarr_status_t
Represents operation error codes.
Definition dynarr.h:43
@ DYNARR_GROW_ERROR
Allocation error on grow.
Definition dynarr.h:46
@ DYNARR_SHRINK_ERROR
Success status inherited from VECTOR_ALLOC_ERROR.
Definition dynarr.h:49
@ DYNARR_SUCCESS
Success status inherited from VECTOR_SUCCESS.
Definition dynarr.h:44
static dynarr_status_t grow(dynarr_t **const dynarr, const size_t amount_to_add)
Definition dynarr.c:563
static dynarr_status_t shrink(dynarr_t **const dynarr, const size_t amount_to_remove)
Definition dynarr.c:586
static void free_space_at(dynarr_t *const dynarr, const size_t index, const size_t amount)
Definition dynarr.c:612
static void make_space_at(dynarr_t *const dynarr, const size_t index, size_t amount)
Definition dynarr.c:641
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.
Definition dynarr.c:290
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.
Definition dynarr.c:423
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.
Definition dynarr.c:388
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.
Definition dynarr.c:239
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.
Definition dynarr.c:359
int dynarr_foreach(const dynarr_t *const dynarr, const foreach_t func, void *const param)
Definition dynarr.c:506
void dynarr_set(dynarr_t *const dynarr, const size_t index, const void *value)
Sets element at given index to a value.
Definition dynarr.c:179
dynarr_status_t dynarr_pop_back(dynarr_t **const dynarr)
Removes an element from the tail of a dynarr.
Definition dynarr.c:257
dynarr_status_t dynarr_pop_front(dynarr_t **const dynarr)
Removes an element from the head of a dynarr.
Definition dynarr.c:264
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.
Definition dynarr.c:343
dynarr_status_t dynarr_prepend(dynarr_t **const dynarr, const void *const value)
Prepends an element to the head of a dynarr.
Definition dynarr.c:248
void * dynarr_first(const dynarr_t *const dynarr)
Access first element of a dynarr.
Definition dynarr.c:196
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.
Definition dynarr.c:310
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.
Definition dynarr.c:204
int dynarr_transform(dynarr_t *const dynarr, const transform_t func, void *const param)
Definition dynarr.c:528
void dynarr_set_zero(dynarr_t *const dynarr, const size_t index)
Sets element at given index to a zero value.
Definition dynarr.c:188
void * dynarr_get(const dynarr_t *const dynarr, const size_t index)
Returns pointer for the element at index.
Definition dynarr.c:171
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.
Definition dynarr.c:402
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.
Definition dynarr.c:271
int dynarr_aggregate(const dynarr_t *const dynarr, const aggregate_t func, void *const acc, void *const param)
Definition dynarr.c:516
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.
Definition dynarr.c:323
dynarr_status_t dynarr_remove(dynarr_t **const dynarr, const size_t index)
Removes an element from a dynarr.
Definition dynarr.c:381
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.
Definition dynarr.c:143
void * dynarr_get_ext_header(const dynarr_t *const dynarr)
Retrieve a location of extended header.
Definition dynarr.c:121
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.
Definition dynarr.c:129
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.
Definition dynarr.c:89
void vector_destroy(vector_t *const vector)
void dynarr_destroy(dynarr_t *const dynarr)
Deallocates a dynamic array.
Definition dynarr.c:136
size_t dynarr_capacity(const dynarr_t *const dynarr)
Access current capacity of the dynarr.
Definition dynarr.c:164
size_t dynarr_initial_capacity(const dynarr_t *const dynarr)
Access initial capacity property.
Definition dynarr.c:157
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.
Definition dynarr.c:150
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.
Definition dynarr.c:226
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.
Definition dynarr.c:213
float grow_threshold
Fraction of the capacity need to be used to trigger growing.
Definition dynarr.c:28
float grow_factor
Multiplier that is applied to dynarr capactity on resize.
Definition dynarr.c:27
size_t initial_cap
Amount of elements preallocated, (dynarr won't shrink below that amount).
Definition dynarr.c:26
size_t size
Tracked amount of stored elements.
Definition dynarr.c:25
float shrink_threshold
Fraction of the capacity in use at which srink will be performed.
Definition dynarr.c:29
size_t ext_header_size
Size of further extended header (after dynarr)
Definition dynarr.c:24
Dynarr creating options.
Definition dynarr.h:25
float grow_threshold
Fraction of the capacity need to be used to trigger growing.
Definition dynarr.h:31
size_t element_size
Definition dynarr.h:28
alloc_opts_t alloc_opts
Definition dynarr.h:26
float shrink_threshold
Fraction of the capacity in use at which srink will be performed.
Definition dynarr.h:32
size_t initial_cap
Definition dynarr.h:29
size_t ext_header_size
Definition dynarr.h:27
float grow_factor
Multiplier that is applied to dynarr capactity on resize.
Definition dynarr.h:30
vector_status_t
#define TMP_REF(type, value)