41#if defined(CVEC_ONLY_INT) || defined(CVEC_ONLY_DOUBLE) || defined(CVEC_ONLY_STR) || defined(CVEC_ONLY_VOID)
45 #ifndef CVEC_ONLY_DOUBLE
46 #define CVEC_NO_DOUBLE
51 #ifndef CVEC_ONLY_VOID
56#if defined(CVEC_MALLOC) && defined(CVEC_FREE) && defined(CVEC_REALLOC)
58#elif !defined(CVEC_MALLOC) && !defined(CVEC_FREE) && !defined(CVEC_REALLOC)
61#error "Must define all or none of CVEC_MALLOC, CVEC_FREE, and CVEC_REALLOC."
66#define CVEC_MALLOC(sz) malloc(sz)
67#define CVEC_REALLOC(p, sz) realloc(p, sz)
68#define CVEC_FREE(p) free(p)
73#define CVEC_MEMMOVE(dst, src, sz) memmove(dst, src, sz)
78#define CVEC_ASSERT(x) assert(x)
83#define CVEC_SIZE_T size_t
126#define cvec_shrink_to_fit_i(vec) cvec_set_cap_i((vec), (vec)->size)
139#ifndef CVEC_NO_DOUBLE
170#define cvec_shrink_to_fit_d(vec) cvec_set_cap_d((vec), (vec)->size)
198#define CVEC_STRDUP cvec_strdup
214#define cvec_popm_str(vec) (vec)->a[--(vec)->size]
217#define cvec_replacem_str(vec, i, s, ret) ((ret) = (vec)->a[i], (vec)->a[i] = (s))
226#define cvec_shrink_to_fit_str(vec) cvec_set_cap_str((vec), (vec)->size)
258#define CVEC_GET_VOID(VEC, TYPE, I) ((TYPE*)&(VEC)->a[(I)*(VEC)->elem_size])
286#define cvec_shrink_to_fit_void(vec) cvec_set_cap_void((vec), (vec)->size)
305#define CVEC_NEW_DECLS(TYPE) \
306 typedef struct cvector_##TYPE { \
312 extern cvec_sz CVEC_##TYPE##_SZ; \
314 int cvec_##TYPE(cvector_##TYPE* vec, cvec_sz size, cvec_sz capacity); \
315 int cvec_init_##TYPE(cvector_##TYPE* vec, TYPE* vals, cvec_sz num); \
317 cvector_##TYPE* cvec_##TYPE##_heap(cvec_sz size, cvec_sz capacity); \
318 cvector_##TYPE* cvec_init_##TYPE##_heap(TYPE* vals, cvec_sz num); \
320 int cvec_copyc_##TYPE(void* dest, void* src); \
321 int cvec_copy_##TYPE(cvector_##TYPE* dest, cvector_##TYPE* src); \
323 int cvec_push_##TYPE(cvector_##TYPE* vec, TYPE a); \
324 TYPE cvec_pop_##TYPE(cvector_##TYPE* vec); \
326 int cvec_extend_##TYPE(cvector_##TYPE* vec, cvec_sz num); \
327 int cvec_insert_##TYPE(cvector_##TYPE* vec, cvec_sz i, TYPE a); \
328 int cvec_insert_array_##TYPE(cvector_##TYPE* vec, cvec_sz i, TYPE* a, cvec_sz num); \
329 TYPE cvec_replace_##TYPE(cvector_##TYPE* vec, cvec_sz i, TYPE a); \
330 void cvec_erase_##TYPE(cvector_##TYPE* vec, cvec_sz start, cvec_sz end); \
331 int cvec_reserve_##TYPE(cvector_##TYPE* vec, cvec_sz size); \
332 int cvec_set_cap_##TYPE(cvector_##TYPE* vec, cvec_sz size); \
333 void cvec_set_val_sz_##TYPE(cvector_##TYPE* vec, TYPE val); \
334 void cvec_set_val_cap_##TYPE(cvector_##TYPE* vec, TYPE val); \
336 TYPE* cvec_back_##TYPE(cvector_##TYPE* vec); \
338 void cvec_clear_##TYPE(cvector_##TYPE* vec); \
339 void cvec_free_##TYPE##_heap(void* vec); \
340 void cvec_free_##TYPE(void* vec);
342#define CVEC_NEW_DEFS(TYPE, RESIZE_MACRO) \
343 cvec_sz CVEC_##TYPE##_SZ = 50; \
345 cvector_##TYPE* cvec_##TYPE##_heap(cvec_sz size, cvec_sz capacity) \
347 cvector_##TYPE* vec; \
348 if (!(vec = (cvector_##TYPE*)CVEC_MALLOC(sizeof(cvector_##TYPE)))) { \
349 CVEC_ASSERT(vec != NULL); \
354 vec->capacity = (capacity > vec->size || (vec->size && capacity == vec->size)) \
356 : vec->size + CVEC_##TYPE##_SZ; \
358 if (!(vec->a = (TYPE*)CVEC_MALLOC(vec->capacity * sizeof(TYPE)))) { \
359 CVEC_ASSERT(vec->a != NULL); \
367 cvector_##TYPE* cvec_init_##TYPE##_heap(TYPE* vals, cvec_sz num) \
369 cvector_##TYPE* vec; \
371 if (!(vec = (cvector_##TYPE*)CVEC_MALLOC(sizeof(cvector_##TYPE)))) { \
372 CVEC_ASSERT(vec != NULL); \
376 vec->capacity = num + CVEC_##TYPE##_SZ; \
378 if (!(vec->a = (TYPE*)CVEC_MALLOC(vec->capacity * sizeof(TYPE)))) { \
379 CVEC_ASSERT(vec->a != NULL); \
384 CVEC_MEMMOVE(vec->a, vals, sizeof(TYPE) * num); \
389 int cvec_##TYPE(cvector_##TYPE* vec, cvec_sz size, cvec_sz capacity) \
392 vec->capacity = (capacity > vec->size || (vec->size && capacity == vec->size)) \
394 : vec->size + CVEC_##TYPE##_SZ; \
396 if (!(vec->a = (TYPE*)CVEC_MALLOC(vec->capacity * sizeof(TYPE)))) { \
397 CVEC_ASSERT(vec->a != NULL); \
398 vec->size = vec->capacity = 0; \
405 int cvec_init_##TYPE(cvector_##TYPE* vec, TYPE* vals, cvec_sz num) \
407 vec->capacity = num + CVEC_##TYPE##_SZ; \
409 if (!(vec->a = (TYPE*)CVEC_MALLOC(vec->capacity * sizeof(TYPE)))) { \
410 CVEC_ASSERT(vec->a != NULL); \
411 vec->size = vec->capacity = 0; \
415 CVEC_MEMMOVE(vec->a, vals, sizeof(TYPE) * num); \
420 int cvec_copyc_##TYPE(void* dest, void* src) \
422 cvector_##TYPE* vec1 = (cvector_##TYPE*)dest; \
423 cvector_##TYPE* vec2 = (cvector_##TYPE*)src; \
427 vec1->capacity = 0; \
429 return cvec_copy_##TYPE(vec1, vec2); \
432 int cvec_copy_##TYPE(cvector_##TYPE* dest, cvector_##TYPE* src) \
435 if (!(tmp = (TYPE*)CVEC_REALLOC(dest->a, src->capacity*sizeof(TYPE)))) { \
436 CVEC_ASSERT(tmp != NULL); \
441 CVEC_MEMMOVE(dest->a, src->a, src->size*sizeof(TYPE)); \
442 dest->size = src->size; \
443 dest->capacity = src->capacity; \
447 int cvec_push_##TYPE(cvector_##TYPE* vec, TYPE a) \
451 if (vec->capacity > vec->size) { \
452 vec->a[vec->size++] = a; \
454 tmp_sz = RESIZE_MACRO(vec->capacity); \
455 if (!(tmp = (TYPE*)CVEC_REALLOC(vec->a, sizeof(TYPE) * tmp_sz))) { \
456 CVEC_ASSERT(tmp != NULL); \
460 vec->a[vec->size++] = a; \
461 vec->capacity = tmp_sz; \
466 TYPE cvec_pop_##TYPE(cvector_##TYPE* vec) { return vec->a[--vec->size]; } \
468 TYPE* cvec_back_##TYPE(cvector_##TYPE* vec) { return &vec->a[vec->size - 1]; } \
470 int cvec_extend_##TYPE(cvector_##TYPE* vec, cvec_sz num) \
474 if (vec->capacity < vec->size + num) { \
475 tmp_sz = vec->capacity + num + CVEC_##TYPE##_SZ; \
476 if (!(tmp = (TYPE*)CVEC_REALLOC(vec->a, sizeof(TYPE) * tmp_sz))) { \
477 CVEC_ASSERT(tmp != NULL); \
481 vec->capacity = tmp_sz; \
488 int cvec_insert_##TYPE(cvector_##TYPE* vec, cvec_sz i, TYPE a) \
492 if (vec->capacity > vec->size) { \
493 CVEC_MEMMOVE(&vec->a[i + 1], &vec->a[i], (vec->size - i) * sizeof(TYPE)); \
496 tmp_sz = RESIZE_MACRO(vec->capacity); \
497 if (!(tmp = (TYPE*)CVEC_REALLOC(vec->a, sizeof(TYPE) * tmp_sz))) { \
498 CVEC_ASSERT(tmp != NULL); \
502 CVEC_MEMMOVE(&vec->a[i + 1], &vec->a[i], (vec->size - i) * sizeof(TYPE)); \
504 vec->capacity = tmp_sz; \
511 int cvec_insert_array_##TYPE(cvector_##TYPE* vec, cvec_sz i, TYPE* a, cvec_sz num) \
515 if (vec->capacity < vec->size + num) { \
516 tmp_sz = vec->capacity + num + CVEC_##TYPE##_SZ; \
517 if (!(tmp = (TYPE*)CVEC_REALLOC(vec->a, sizeof(TYPE) * tmp_sz))) { \
518 CVEC_ASSERT(tmp != NULL); \
522 vec->capacity = tmp_sz; \
525 CVEC_MEMMOVE(&vec->a[i + num], &vec->a[i], (vec->size - i) * sizeof(TYPE)); \
526 CVEC_MEMMOVE(&vec->a[i], a, num * sizeof(TYPE)); \
531 TYPE cvec_replace_##TYPE(cvector_##TYPE* vec, cvec_sz i, TYPE a) \
533 TYPE tmp = vec->a[i]; \
538 void cvec_erase_##TYPE(cvector_##TYPE* vec, cvec_sz start, cvec_sz end) \
540 cvec_sz d = end - start + 1; \
541 CVEC_MEMMOVE(&vec->a[start], &vec->a[end + 1], (vec->size - 1 - end) * sizeof(TYPE)); \
545 int cvec_reserve_##TYPE(cvector_##TYPE* vec, cvec_sz size) \
548 if (vec->capacity < size) { \
549 if (!(tmp = (TYPE*)CVEC_REALLOC(vec->a, sizeof(TYPE) * (size + CVEC_##TYPE##_SZ)))) { \
550 CVEC_ASSERT(tmp != NULL); \
554 vec->capacity = size + CVEC_##TYPE##_SZ; \
559 int cvec_set_cap_##TYPE(cvector_##TYPE* vec, cvec_sz size) \
562 if (size < vec->size) { \
566 if (!(tmp = (TYPE*)CVEC_REALLOC(vec->a, sizeof(TYPE) * size))) { \
567 CVEC_ASSERT(tmp != NULL); \
571 vec->capacity = size; \
575 void cvec_set_val_sz_##TYPE(cvector_##TYPE* vec, TYPE val) \
578 for (i = 0; i < vec->size; i++) { \
583 void cvec_set_val_cap_##TYPE(cvector_##TYPE* vec, TYPE val) \
586 for (i = 0; i < vec->capacity; i++) { \
591 void cvec_clear_##TYPE(cvector_##TYPE* vec) { vec->size = 0; } \
593 void cvec_free_##TYPE##_heap(void* vec) \
595 cvector_##TYPE* tmp = (cvector_##TYPE*)vec; \
601 void cvec_free_##TYPE(void* vec) \
603 cvector_##TYPE* tmp = (cvector_##TYPE*)vec; \
610#define CVEC_NEW_DECLS2(TYPE) \
611 typedef struct cvector_##TYPE { \
615 void (*elem_free)(void*); \
616 int (*elem_init)(void*, void*); \
619 extern cvec_sz CVEC_##TYPE##_SZ; \
621 int cvec_##TYPE(cvector_##TYPE* vec, cvec_sz size, cvec_sz capacity, void (*elem_free)(void*), \
622 int (*elem_init)(void*, void*)); \
623 int cvec_init_##TYPE(cvector_##TYPE* vec, TYPE* vals, cvec_sz num, void (*elem_free)(void*), \
624 int (*elem_init)(void*, void*)); \
626 cvector_##TYPE* cvec_##TYPE##_heap(cvec_sz size, cvec_sz capacity, void (*elem_free)(void*), \
627 int (*elem_init)(void*, void*)); \
628 cvector_##TYPE* cvec_init_##TYPE##_heap(TYPE* vals, cvec_sz num, void (*elem_free)(void*), \
629 int (*elem_init)(void*, void*)); \
631 int cvec_copyc_##TYPE(void* dest, void* src); \
632 int cvec_copy_##TYPE(cvector_##TYPE* dest, cvector_##TYPE* src); \
634 int cvec_push_##TYPE(cvector_##TYPE* vec, TYPE* val); \
635 void cvec_pop_##TYPE(cvector_##TYPE* vec, TYPE* ret); \
637 int cvec_pushm_##TYPE(cvector_##TYPE* vec, TYPE* a); \
638 void cvec_popm_##TYPE(cvector_##TYPE* vec, TYPE* ret); \
639 int cvec_insertm_##TYPE(cvector_##TYPE* vec, cvec_sz i, TYPE* a); \
640 int cvec_insert_arraym_##TYPE(cvector_##TYPE* vec, cvec_sz i, TYPE* a, cvec_sz num); \
641 void cvec_replacem_##TYPE(cvector_##TYPE* vec, cvec_sz i, TYPE* a, TYPE* ret); \
643 int cvec_extend_##TYPE(cvector_##TYPE* vec, cvec_sz num); \
644 int cvec_insert_##TYPE(cvector_##TYPE* vec, cvec_sz i, TYPE* a); \
645 int cvec_insert_array_##TYPE(cvector_##TYPE* vec, cvec_sz i, TYPE* a, cvec_sz num); \
646 int cvec_replace_##TYPE(cvector_##TYPE* vec, cvec_sz i, TYPE* a, TYPE* ret); \
647 void cvec_erase_##TYPE(cvector_##TYPE* vec, cvec_sz start, cvec_sz end); \
648 void cvec_remove_##TYPE(cvector_##TYPE* vec, cvec_sz start, cvec_sz end); \
649 int cvec_reserve_##TYPE(cvector_##TYPE* vec, cvec_sz size); \
650 int cvec_set_cap_##TYPE(cvector_##TYPE* vec, cvec_sz size); \
651 int cvec_set_val_sz_##TYPE(cvector_##TYPE* vec, TYPE* val); \
652 int cvec_set_val_cap_##TYPE(cvector_##TYPE* vec, TYPE* val); \
654 TYPE* cvec_back_##TYPE(cvector_##TYPE* vec); \
656 void cvec_clear_##TYPE(cvector_##TYPE* vec); \
657 void cvec_free_##TYPE##_heap(void* vec); \
658 void cvec_free_##TYPE(void* vec);
660#define CVEC_NEW_DEFS2(TYPE, RESIZE_MACRO) \
661 cvec_sz CVEC_##TYPE##_SZ = 20; \
663 cvector_##TYPE* cvec_##TYPE##_heap(cvec_sz size, cvec_sz capacity, void (*elem_free)(void*), \
664 int (*elem_init)(void*, void*)) \
666 cvector_##TYPE* vec; \
667 if (!(vec = (cvector_##TYPE*)CVEC_MALLOC(sizeof(cvector_##TYPE)))) { \
668 CVEC_ASSERT(vec != NULL); \
673 vec->capacity = (capacity > vec->size || (vec->size && capacity == vec->size)) \
675 : vec->size + CVEC_##TYPE##_SZ; \
677 if (!(vec->a = (TYPE*)CVEC_MALLOC(vec->capacity * sizeof(TYPE)))) { \
678 CVEC_ASSERT(vec->a != NULL); \
683 vec->elem_free = elem_free; \
684 vec->elem_init = elem_init; \
689 cvector_##TYPE* cvec_init_##TYPE##_heap(TYPE* vals, cvec_sz num, void (*elem_free)(void*), \
690 int (*elem_init)(void*, void*)) \
692 cvector_##TYPE* vec; \
695 if (!(vec = (cvector_##TYPE*)CVEC_MALLOC(sizeof(cvector_##TYPE)))) { \
696 CVEC_ASSERT(vec != NULL); \
700 vec->capacity = num + CVEC_##TYPE##_SZ; \
702 if (!(vec->a = (TYPE*)CVEC_MALLOC(vec->capacity * sizeof(TYPE)))) { \
703 CVEC_ASSERT(vec->a != NULL); \
709 for (i = 0; i < num; ++i) { \
710 if (!elem_init(&vec->a[i], &vals[i])) { \
718 CVEC_MEMMOVE(vec->a, vals, sizeof(TYPE) * num); \
721 vec->elem_free = elem_free; \
722 vec->elem_init = elem_init; \
727 int cvec_##TYPE(cvector_##TYPE* vec, cvec_sz size, cvec_sz capacity, void (*elem_free)(void*), \
728 int (*elem_init)(void*, void*)) \
731 vec->capacity = (capacity > vec->size || (vec->size && capacity == vec->size)) \
733 : vec->size + CVEC_##TYPE##_SZ; \
735 if (!(vec->a = (TYPE*)CVEC_MALLOC(vec->capacity * sizeof(TYPE)))) { \
736 CVEC_ASSERT(vec->a != NULL); \
737 vec->size = vec->capacity = 0; \
741 vec->elem_free = elem_free; \
742 vec->elem_init = elem_init; \
747 int cvec_init_##TYPE(cvector_##TYPE* vec, TYPE* vals, cvec_sz num, void (*elem_free)(void*), \
748 int (*elem_init)(void*, void*)) \
752 vec->capacity = num + CVEC_##TYPE##_SZ; \
754 if (!(vec->a = (TYPE*)CVEC_MALLOC(vec->capacity * sizeof(TYPE)))) { \
755 CVEC_ASSERT(vec->a != NULL); \
756 vec->size = vec->capacity = 0; \
761 for (i = 0; i < num; ++i) { \
762 if (!elem_init(&vec->a[i], &vals[i])) { \
768 CVEC_MEMMOVE(vec->a, vals, sizeof(TYPE) * num); \
771 vec->elem_free = elem_free; \
772 vec->elem_init = elem_init; \
777 int cvec_copyc_##TYPE(void* dest, void* src) \
779 cvector_##TYPE* vec1 = (cvector_##TYPE*)dest; \
780 cvector_##TYPE* vec2 = (cvector_##TYPE*)src; \
784 vec1->capacity = 0; \
786 return cvec_copy_##TYPE(vec1, vec2); \
789 int cvec_copy_##TYPE(cvector_##TYPE* dest, cvector_##TYPE* src) \
793 if (!(tmp = (TYPE*)CVEC_REALLOC(dest->a, src->capacity*sizeof(TYPE)))) { \
794 CVEC_ASSERT(tmp != NULL); \
799 if (src->elem_init) { \
800 for (i=0; i<src->size; ++i) { \
801 if (!src->elem_init(&dest->a[i], &src->a[i])) { \
807 CVEC_MEMMOVE(dest->a, src->a, src->size*sizeof(TYPE)); \
810 dest->size = src->size; \
811 dest->capacity = src->capacity; \
812 dest->elem_free = src->elem_free; \
813 dest->elem_init = src->elem_init; \
817 int cvec_push_##TYPE(cvector_##TYPE* vec, TYPE* a) \
821 if (vec->capacity == vec->size) { \
822 tmp_sz = RESIZE_MACRO(vec->capacity); \
823 if (!(tmp = (TYPE*)CVEC_REALLOC(vec->a, sizeof(TYPE) * tmp_sz))) { \
824 CVEC_ASSERT(tmp != NULL); \
828 vec->capacity = tmp_sz; \
830 if (vec->elem_init) { \
831 if (!vec->elem_init(&vec->a[vec->size], a)) { \
836 CVEC_MEMMOVE(&vec->a[vec->size], a, sizeof(TYPE)); \
843 int cvec_pushm_##TYPE(cvector_##TYPE* vec, TYPE* a) \
847 if (vec->capacity == vec->size) { \
848 tmp_sz = RESIZE_MACRO(vec->capacity); \
849 if (!(tmp = (TYPE*)CVEC_REALLOC(vec->a, sizeof(TYPE) * tmp_sz))) { \
850 CVEC_ASSERT(tmp != NULL); \
854 vec->capacity = tmp_sz; \
856 CVEC_MEMMOVE(&vec->a[vec->size], a, sizeof(TYPE)); \
862 void cvec_pop_##TYPE(cvector_##TYPE* vec, TYPE* ret) \
865 CVEC_MEMMOVE(ret, &vec->a[--vec->size], sizeof(TYPE)); \
870 if (vec->elem_free) { \
871 vec->elem_free(&vec->a[vec->size]); \
875 void cvec_popm_##TYPE(cvector_##TYPE* vec, TYPE* ret) \
879 CVEC_MEMMOVE(ret, &vec->a[vec->size], sizeof(TYPE)); \
883 TYPE* cvec_back_##TYPE(cvector_##TYPE* vec) { return &vec->a[vec->size - 1]; } \
885 int cvec_extend_##TYPE(cvector_##TYPE* vec, cvec_sz num) \
889 if (vec->capacity < vec->size + num) { \
890 tmp_sz = vec->capacity + num + CVEC_##TYPE##_SZ; \
891 if (!(tmp = (TYPE*)CVEC_REALLOC(vec->a, sizeof(TYPE) * tmp_sz))) { \
892 CVEC_ASSERT(tmp != NULL); \
896 vec->capacity = tmp_sz; \
903 int cvec_insert_##TYPE(cvector_##TYPE* vec, cvec_sz i, TYPE* a) \
907 if (vec->capacity == vec->size) { \
908 tmp_sz = RESIZE_MACRO(vec->capacity); \
909 if (!(tmp = (TYPE*)CVEC_REALLOC(vec->a, sizeof(TYPE) * tmp_sz))) { \
910 CVEC_ASSERT(tmp != NULL); \
915 vec->capacity = tmp_sz; \
917 CVEC_MEMMOVE(&vec->a[i + 1], &vec->a[i], (vec->size - i) * sizeof(TYPE)); \
919 if (vec->elem_init) { \
920 if (!vec->elem_init(&vec->a[i], a)) { \
925 CVEC_MEMMOVE(&vec->a[i], a, sizeof(TYPE)); \
932 int cvec_insertm_##TYPE(cvector_##TYPE* vec, cvec_sz i, TYPE* a) \
936 if (vec->capacity == vec->size) { \
937 tmp_sz = RESIZE_MACRO(vec->capacity); \
938 if (!(tmp = (TYPE*)CVEC_REALLOC(vec->a, sizeof(TYPE) * tmp_sz))) { \
939 CVEC_ASSERT(tmp != NULL); \
944 vec->capacity = tmp_sz; \
946 CVEC_MEMMOVE(&vec->a[i + 1], &vec->a[i], (vec->size - i) * sizeof(TYPE)); \
948 CVEC_MEMMOVE(&vec->a[i], a, sizeof(TYPE)); \
954 int cvec_insert_array_##TYPE(cvector_##TYPE* vec, cvec_sz i, TYPE* a, cvec_sz num) \
958 if (vec->capacity < vec->size + num) { \
959 tmp_sz = vec->capacity + num + CVEC_##TYPE##_SZ; \
960 if (!(tmp = (TYPE*)CVEC_REALLOC(vec->a, sizeof(TYPE) * tmp_sz))) { \
961 CVEC_ASSERT(tmp != NULL); \
965 vec->capacity = tmp_sz; \
968 CVEC_MEMMOVE(&vec->a[i + num], &vec->a[i], (vec->size - i) * sizeof(TYPE)); \
969 if (vec->elem_init) { \
970 for (j = 0; j < num; ++j) { \
971 if (!vec->elem_init(&vec->a[j + i], &a[j])) { \
977 CVEC_MEMMOVE(&vec->a[i], a, num * sizeof(TYPE)); \
983 int cvec_insert_arraym_##TYPE(cvector_##TYPE* vec, cvec_sz i, TYPE* a, cvec_sz num) \
987 if (vec->capacity < vec->size + num) { \
988 tmp_sz = vec->capacity + num + CVEC_##TYPE##_SZ; \
989 if (!(tmp = (TYPE*)CVEC_REALLOC(vec->a, sizeof(TYPE) * tmp_sz))) { \
990 CVEC_ASSERT(tmp != NULL); \
994 vec->capacity = tmp_sz; \
997 CVEC_MEMMOVE(&vec->a[i + num], &vec->a[i], (vec->size - i) * sizeof(TYPE)); \
999 CVEC_MEMMOVE(&vec->a[i], a, num * sizeof(TYPE)); \
1004 int cvec_replace_##TYPE(cvector_##TYPE* vec, cvec_sz i, TYPE* a, TYPE* ret) \
1007 CVEC_MEMMOVE(ret, &vec->a[i], sizeof(TYPE)); \
1008 } else if (vec->elem_free) { \
1009 vec->elem_free(&vec->a[i]); \
1012 if (vec->elem_init) { \
1013 if (!vec->elem_init(&vec->a[i], a)) { \
1018 CVEC_MEMMOVE(&vec->a[i], a, sizeof(TYPE)); \
1023 void cvec_replacem_##TYPE(cvector_##TYPE* vec, cvec_sz i, TYPE* a, TYPE* ret) \
1026 CVEC_MEMMOVE(ret, &vec->a[i], sizeof(TYPE)); \
1029 CVEC_MEMMOVE(&vec->a[i], a, sizeof(TYPE)); \
1032 void cvec_erase_##TYPE(cvector_##TYPE* vec, cvec_sz start, cvec_sz end) \
1035 cvec_sz d = end - start + 1; \
1036 if (vec->elem_free) { \
1037 for (i = start; i <= end; i++) { \
1038 vec->elem_free(&vec->a[i]); \
1041 CVEC_MEMMOVE(&vec->a[start], &vec->a[end + 1], (vec->size - 1 - end) * sizeof(TYPE)); \
1045 void cvec_remove_##TYPE(cvector_##TYPE* vec, cvec_sz start, cvec_sz end) \
1047 cvec_sz d = end - start + 1; \
1048 CVEC_MEMMOVE(&vec->a[start], &vec->a[end + 1], (vec->size - 1 - end) * sizeof(TYPE)); \
1052 int cvec_reserve_##TYPE(cvector_##TYPE* vec, cvec_sz size) \
1055 if (vec->capacity < size) { \
1056 if (!(tmp = (TYPE*)CVEC_REALLOC(vec->a, sizeof(TYPE) * (size + CVEC_##TYPE##_SZ)))) { \
1057 CVEC_ASSERT(tmp != NULL); \
1061 vec->capacity = size + CVEC_##TYPE##_SZ; \
1066 int cvec_set_cap_##TYPE(cvector_##TYPE* vec, cvec_sz size) \
1070 if (size < vec->size) { \
1071 if (vec->elem_free) { \
1072 for (i = vec->size - 1; i >= size; i--) { \
1073 vec->elem_free(&vec->a[i]); \
1079 vec->capacity = size; \
1081 if (!(tmp = (TYPE*)CVEC_REALLOC(vec->a, sizeof(TYPE) * size))) { \
1082 CVEC_ASSERT(tmp != NULL); \
1089 int cvec_set_val_sz_##TYPE(cvector_##TYPE* vec, TYPE* val) \
1093 if (vec->elem_free) { \
1094 for (i = 0; i < vec->size; i++) { \
1095 vec->elem_free(&vec->a[i]); \
1099 if (vec->elem_init) { \
1100 for (i = 0; i < vec->size; i++) { \
1101 if (!vec->elem_init(&vec->a[i], val)) { \
1107 for (i = 0; i < vec->size; i++) { \
1108 CVEC_MEMMOVE(&vec->a[i], val, sizeof(TYPE)); \
1114 int cvec_set_val_cap_##TYPE(cvector_##TYPE* vec, TYPE* val) \
1117 if (vec->elem_free) { \
1118 for (i = 0; i < vec->size; i++) { \
1119 vec->elem_free(&vec->a[i]); \
1121 vec->size = vec->capacity; \
1124 if (vec->elem_init) { \
1125 for (i = 0; i < vec->capacity; i++) { \
1126 if (!vec->elem_init(&vec->a[i], val)) { \
1132 for (i = 0; i < vec->capacity; i++) { \
1133 CVEC_MEMMOVE(&vec->a[i], val, sizeof(TYPE)); \
1139 void cvec_clear_##TYPE(cvector_##TYPE* vec) \
1142 if (vec->elem_free) { \
1143 for (i = 0; i < vec->size; ++i) { \
1144 vec->elem_free(&vec->a[i]); \
1150 void cvec_free_##TYPE##_heap(void* vec) \
1153 cvector_##TYPE* tmp = (cvector_##TYPE*)vec; \
1155 if (tmp->elem_free) { \
1156 for (i = 0; i < tmp->size; i++) { \
1157 tmp->elem_free(&tmp->a[i]); \
1160 CVEC_FREE(tmp->a); \
1164 void cvec_free_##TYPE(void* vec) \
1167 cvector_##TYPE* tmp = (cvector_##TYPE*)vec; \
1168 if (tmp->elem_free) { \
1169 for (i = 0; i < tmp->size; i++) { \
1170 tmp->elem_free(&tmp->a[i]); \
1174 CVEC_FREE(tmp->a); \
1177 tmp->capacity = 0; \
1186#ifdef CVECTOR_IMPLEMENTATION
1192#define CVEC_I_ALLOCATOR(x) ((x+1) * 2)
1337 if (!(tmp = (
int*)
CVEC_REALLOC(vec->
a,
sizeof(
int)*tmp_sz))) {
1345 vec->
a[vec->
size++] = a;
1352 return vec->
a[--vec->
size];
1358 return &vec->
a[vec->
size-1];
1369 if (!(tmp = (
int*)
CVEC_REALLOC(vec->
a,
sizeof(
int)*tmp_sz))) {
1391 if (!(tmp = (
int*)
CVEC_REALLOC(vec->
a,
sizeof(
int)*tmp_sz))) {
1417 if (!(tmp = (
int*)
CVEC_REALLOC(vec->
a,
sizeof(
int)*tmp_sz))) {
1434 int tmp = vec->
a[i];
1473 if (size < vec->size) {
1477 if (!(tmp = (
int*)
CVEC_REALLOC(vec->
a,
sizeof(
int)*size))) {
1490 for (i=0; i<vec->
size; i++) {
1530#ifndef CVEC_NO_DOUBLE
1534#define CVEC_D_ALLOCATOR(x) ((x+1) * 2)
1680 if (!(tmp = (
double*)
CVEC_REALLOC(vec->
a,
sizeof(
double)*tmp_sz))) {
1687 vec->
a[vec->
size++] = a;
1694 return vec->
a[--vec->
size];
1700 return &vec->
a[vec->
size-1];
1711 if (!(tmp = (
double*)
CVEC_REALLOC(vec->
a,
sizeof(
double)*tmp_sz))) {
1733 if (!(tmp = (
double*)
CVEC_REALLOC(vec->
a,
sizeof(
double)*tmp_sz))) {
1759 if (!(tmp = (
double*)
CVEC_REALLOC(vec->
a,
sizeof(
double)*tmp_sz))) {
1776 double tmp = vec->
a[i];
1815 if (size < vec->size)
1818 if (!(tmp = (
double*)
CVEC_REALLOC(vec->
a,
sizeof(
double)*size))) {
1831 for(i=0; i<vec->
size; i++) {
1874#define CVEC_STR_ALLOCATOR(x) ((x+1) * 2)
1876#if CVEC_STRDUP == cvec_strdup
1927 memset(vec->
a, 0, vec->
capacity*
sizeof(
char*));
1952 for(i=0; i<num; i++) {
1975 memset(vec->
a, 0, vec->
capacity*
sizeof(
char*));
1995 for(i=0; i<num; i++) {
2043 for (i=0; i<src->
size; ++i) {
2061 if (!(tmp = (
char**)
CVEC_REALLOC(vec->
a,
sizeof(
char*)*tmp_sz))) {
2080 if (!(tmp = (
char**)
CVEC_REALLOC(vec->
a,
sizeof(
char*)*tmp_sz))) {
2088 vec->
a[vec->
size++] = a;
2100 strcpy(ret, vec->
a[vec->
size]);
2107 return &vec->
a[vec->
size-1];
2119 if (!(tmp = (
char**)
CVEC_REALLOC(vec->
a,
sizeof(
char*)*tmp_sz))) {
2127 memset(&vec->
a[vec->
size], 0, num*
sizeof(
char*));
2142 if (!(tmp = (
char**)
CVEC_REALLOC(vec->
a,
sizeof(
char*)*tmp_sz))) {
2165 if (!(tmp = (
char**)
CVEC_REALLOC(vec->
a,
sizeof(
char*)*tmp_sz))) {
2190 if (!(tmp = (
char**)
CVEC_REALLOC(vec->
a,
sizeof(
char*)*tmp_sz))) {
2199 for (j=0; j<num; ++j) {
2216 if (!(tmp = (
char**)
CVEC_REALLOC(vec->
a,
sizeof(
char*)*tmp_sz))) {
2238 strcpy(ret, vec->
a[i]);
2252 for (i=start; i<=end; i++) {
2291 if (size < vec->size) {
2292 for(i=vec->
size-1; i>size-1; i--) {
2299 if (!(tmp = (
char**)
CVEC_REALLOC(vec->
a,
sizeof(
char*)*size))) {
2312 for(i=0; i<vec->
size; i++) {
2341 for (i=0; i<vec->
size; i++) {
2355 for (i=0; i<tmp->
size; i++) {
2369 for (i=0; i<tmp->
size; i++) {
2384#define CVEC_VOID_ALLOCATOR(x) ((x+1) * 2)
2466 for (i=0; i<num; ++i) {
2467 if (!elem_init(&vec->
a[i*elem_sz], &((
cvec_u8*)vals)[i*elem_sz])) {
2524 for (i=0; i<num; ++i) {
2525 if (!elem_init(&vec->
a[i*elem_sz], &((
cvec_u8*)vals)[i*elem_sz])) {
2582 for (i=0; i<src->
size; ++i) {
2794 for (j=0; j<num; ++j) {
2875 for (i=start; i<=end; i++) {
2914 if (size < vec->size) {
2916 for (i=vec->
size-1; i>=size; i--) {
2939 for(i=0; i<vec->
size; i++) {
2945 for (i=0; i<vec->
size; i++) {
2952 for (i=0; i<vec->
size; i++) {
2968 for (i=0; i<vec->
size; i++) {
2995 for (i=0; i<vec->
size; ++i) {
3011 for (i=0; i<tmp->
size; i++) {
3026 for (i=0; i<tmp->
size; i++) {
int cvec_init_str(cvector_str *vec, char **vals, cvec_sz num)
Same as cvec_init_str_heap() except the vector passed in was declared on the stack so it isn't alloca...
void cvec_clear_str(cvector_str *vec)
Clears the contents of vector (frees all strings) and sets size to 0.
int cvec_insert_array_d(cvector_d *vec, cvec_sz i, double *a, cvec_sz num)
Insert the first num elements of array a at index i.
char ** cvec_back_str(cvector_str *vec)
Return pointer to last element.
int cvec_set_val_sz_void(cvector_void *vec, void *val)
Set all size elements to val.
int cvec_insert_d(cvector_d *vec, cvec_sz i, double a)
Insert a at index i (0 based).
int cvec_insert_i(cvector_i *vec, cvec_sz i, int a)
Insert a at index i (0 based).
int cvec_copyc_void(void *dest, void *src)
Makes dest a copy of src.
void cvec_free_i_heap(void *vec)
Frees everything so don't use vec after calling this.
int cvec_copy_str(cvector_str *dest, cvector_str *src)
Makes dest a copy of src.
int cvec_insert_array_void(cvector_void *vec, cvec_sz i, void *a, cvec_sz num)
Insert the first num elements of array a at index i.
int cvec_copy_void(cvector_void *dest, cvector_void *src)
Makes dest a copy of src.
void cvec_free_i(void *vec)
Frees the internal array and zeros out the members to maintain a consistent state.
void cvec_free_d(void *vec)
Frees the internal array and zeros out the members to maintain a consistent state.
int cvec_reserve_void(cvector_void *vec, cvec_sz size)
Makes sure capacity >= size (the parameter not the member).
int cvec_set_cap_str(cvector_str *vec, cvec_sz size)
Set capacity to size.
cvector_void * cvec_void_heap(cvec_sz size, cvec_sz capacity, cvec_sz elem_sz, void(*elem_free)(void *), int(*elem_init)(void *, void *))
Creates a new vector on the heap.
#define CVEC_REALLOC(p, sz)
int cvec_pop_i(cvector_i *vec)
Remove and return the last element (size decreased 1).
int cvec_extend_str(cvector_str *vec, cvec_sz num)
Increase the size of the array num items.
void cvec_set_val_cap_str(cvector_str *vec, char *val)
Fills entire allocated array (capacity) with val.
int cvec_copyc_i(void *dest, void *src)
Makes dest a copy of src.
cvector_str * cvec_init_str_heap(char **vals, cvec_sz num)
Create (on the heap) and initialize cvector_str with num elements of vals.
void cvec_erase_d(cvector_d *vec, cvec_sz start, cvec_sz end)
Erases elements from start to end inclusive.
int cvec_pushm_void(cvector_void *vec, void *a)
Same as push except no elem_init even if it's set.
int cvec_replace_i(cvector_i *vec, cvec_sz i, int a)
Replace value at index i with a, return original value.
int cvec_insert_arraym_void(cvector_void *vec, cvec_sz i, void *a, cvec_sz num)
Same as insert_array but no elem_init even if defined.
int cvec_copyc_str(void *dest, void *src)
Makes dest a copy of src.
cvector_d * cvec_d_heap(cvec_sz size, cvec_sz capacity)
Creates a new cvector_d on the heap.
int cvec_insert_array_i(cvector_i *vec, cvec_sz i, int *a, cvec_sz num)
Insert the first num elements of array a at index i.
void cvec_set_val_cap_d(cvector_d *vec, double val)
Fills entire allocated array (capacity) with val.
int cvec_replace_void(cvector_void *vec, cvec_sz i, void *a, void *ret)
Replace value at i with a, return old value in ret if non-NULL.
void cvec_remove_void(cvector_void *vec, cvec_sz start, cvec_sz end)
Same as erase except it does not call elem_free.
int cvec_copy_d(cvector_d *dest, cvector_d *src)
Makes dest a copy of src.
int cvec_init_void(cvector_void *vec, void *vals, cvec_sz num, cvec_sz elem_sz, void(*elem_free)(void *), int(*elem_init)(void *, void *))
Same as init_vec_heap() except the vector passed in was declared on the stack so it isn't allocated i...
int cvec_copy_i(cvector_i *dest, cvector_i *src)
Makes dest a copy of src.
int cvec_set_cap_i(cvector_i *vec, cvec_sz size)
Set capacity to size.
cvector_i * cvec_init_i_heap(int *vals, cvec_sz num)
Create (on the heap) and initialize cvector_i with num elements of vals.
cvector_void * cvec_init_void_heap(void *vals, cvec_sz num, cvec_sz elem_sz, void(*elem_free)(void *), int(*elem_init)(void *, void *))
Create (on the heap) and initialize vector with num elements of vals.
int cvec_reserve_d(cvector_d *vec, cvec_sz size)
Make sure capacity is at least size(parameter not member).
#define CVEC_MEMMOVE(dst, src, sz)
void cvec_erase_void(cvector_void *vec, cvec_sz start, cvec_sz end)
Erases elements from start to end inclusive.
int cvec_extend_d(cvector_d *vec, cvec_sz num)
Increase the size of the array num items.
void * cvec_get_void(cvector_void *vec, cvec_sz i)
Return a void pointer to the ith element.
int cvec_reserve_i(cvector_i *vec, cvec_sz size)
Make sure capacity is at least size(parameter not member).
int cvec_push_void(cvector_void *vec, void *a)
Append a to end of vector (size increased 1).
int cvec_copyc_d(void *dest, void *src)
Makes dest a copy of src.
int cvec_insertm_void(cvector_void *vec, cvec_sz i, void *a)
Same as insert but no elem_init even if defined.
void cvec_set_val_sz_str(cvector_str *vec, char *val)
Sets all size elements to val.
int cvec_void(cvector_void *vec, cvec_sz size, cvec_sz capacity, cvec_sz elem_sz, void(*elem_free)(void *), int(*elem_init)(void *, void *))
Same as cvec_void_heap() except the vector passed in was declared on the stack so it isn't allocated ...
void * cvec_back_void(cvector_void *vec)
Return pointer to last element.
int cvec_insert_array_str(cvector_str *vec, cvec_sz i, char **a, cvec_sz num)
Insert the first num elements of array a at index i.
double cvec_replace_d(cvector_d *vec, cvec_sz i, double a)
Replace value at index i with a, return original value.
cvector_i * cvec_i_heap(cvec_sz size, cvec_sz capacity)
Creates a new cvector_i on the heap.
int cvec_push_i(cvector_i *vec, int a)
Append a to end of vector (size increased 1).
void cvec_erase_i(cvector_i *vec, cvec_sz start, cvec_sz end)
Erases elements from start to end inclusive.
int cvec_insertm_str(cvector_str *vec, cvec_sz i, char *a)
Same as insert except no CVEC_STRDUP.
void cvec_set_val_sz_d(cvector_d *vec, double val)
Set all size elements to val.
int cvec_init_i(cvector_i *vec, int *vals, cvec_sz num)
Same as cvec_init_i_heap() except the vector passed in was declared on the stack so it isn't allocate...
char * cvec_strdup(const char *str)
Useful utility function since strdup isn't in standard C.
void cvec_erase_str(cvector_str *vec, cvec_sz start, cvec_sz end)
Erases strings from start to end inclusive.
void cvec_free_str(void *vec)
Frees the internal array and zeros out the members to maintain a consistent state.
void cvec_pop_void(cvector_void *vec, void *ret)
Remove the last element (size decreased 1).
cvector_str * cvec_str_heap(cvec_sz size, cvec_sz capacity)
Create a new cvector_str on the heap.
int cvec_i(cvector_i *vec, cvec_sz size, cvec_sz capacity)
Same as cvec_i_heap() except the vector passed in was declared on the stack so it isn't allocated in ...
int cvec_set_cap_void(cvector_void *vec, cvec_sz size)
Set capacity to size.
cvector_d * cvec_init_d_heap(double *vals, cvec_sz num)
Create (on the heap) and initialize cvector_d with num elements of vals.
int cvec_push_str(cvector_str *vec, char *a)
Append a to end of vector (size increased 1).
int cvec_insert_arraym_str(cvector_str *vec, cvec_sz i, char **a, cvec_sz num)
Same as insert_array except no CVEC_STRDUP.
int cvec_d(cvector_d *vec, cvec_sz size, cvec_sz capacity)
Same as cvec_d_heap() except the vector passed in was declared on the stack so it isn't allocated in ...
void cvec_free_void(void *vec)
Frees the internal array and sets it, size, and capacity to NULL/0 to maintain a consistent state.
int cvec_set_cap_d(cvector_d *vec, cvec_sz size)
Set capacity to size.
int cvec_pushm_str(cvector_str *vec, char *a)
same as push but without calling CVEC_STRDUP(a), m suffix is for "move"
void cvec_replacem_void(cvector_void *vec, cvec_sz i, void *a, void *ret)
Same as replace but no elem_free or elem_init even if they're defined.
void cvec_replace_str(cvector_str *vec, cvec_sz i, char *a, char *ret)
Replace string at i with a.
cvec_sz CVEC_VOID_START_SZ
void cvec_pop_str(cvector_str *vec, char *ret)
Remove the last element (size decreased 1).
void cvec_free_str_heap(void *vec)
Frees contents (individual strings and array) and frees vector so don't use after calling this.
int cvec_set_val_cap_void(cvector_void *vec, void *val)
Fills entire allocated array (capacity) with val.
void cvec_free_void_heap(void *vec)
Frees everything so don't use vec after calling this.
int cvec_push_d(cvector_d *vec, double a)
Append a to end of vector (size increased 1).
void cvec_clear_i(cvector_i *vec)
Sets size to 0 (does not clear contents).
int cvec_reserve_str(cvector_str *vec, cvec_sz size)
Makes sure the vector capacity is >= size (parameter not member).
int cvec_extend_void(cvector_void *vec, cvec_sz num)
Increase the size of the array num items.
int cvec_insert_str(cvector_str *vec, cvec_sz i, char *a)
Insert a at index i (0 based).
int cvec_extend_i(cvector_i *vec, cvec_sz num)
Increase the size of the array num items.
void cvec_set_val_cap_i(cvector_i *vec, int val)
Fills entire allocated array (capacity) with val.
double * cvec_back_d(cvector_d *vec)
Return pointer to last element.
void cvec_remove_str(cvector_str *vec, cvec_sz start, cvec_sz end)
Same as erase except it does not call CVEC_FREE.
int cvec_str(cvector_str *vec, cvec_sz size, cvec_sz capacity)
Same as cvec_str_heap() except the vector passed in was declared on the stack so it isn't allocated i...
void cvec_clear_d(cvector_d *vec)
Sets size to 0 (does not clear contents).
void cvec_set_val_sz_i(cvector_i *vec, int val)
Set all size elements to val.
void cvec_clear_void(cvector_void *vec)
Sets size to 0 (does not change contents unless elem_free is set then it will elem_free all size elem...
void cvec_free_d_heap(void *vec)
Frees everything so don't use vec after calling this.
int cvec_init_d(cvector_d *vec, double *vals, cvec_sz num)
Same as cvec_init_d_heap() except the vector passed in was declared on the stack so it isn't allocate...
double cvec_pop_d(cvector_d *vec)
Remove and return the last element (size decreased 1).
int * cvec_back_i(cvector_i *vec)
Return pointer to last element.
void cvec_popm_void(cvector_void *vec, void *ret)
Same as pop except no elem_free even if it's set.
int cvec_insert_void(cvector_void *vec, cvec_sz i, void *a)
Insert a at index i (0 based).
cvec_sz CVEC_STR_START_SZ
#define CVEC_D_ALLOCATOR(x)
#define CVEC_I_ALLOCATOR(x)
#define CVEC_STR_ALLOCATOR(x)
#define CVEC_VOID_ALLOCATOR(x)
Data structure for double vector.
cvec_sz size
Current size (amount you use when manipulating array directly).
cvec_sz capacity
Allocated size of array; always >= size.
Data structure for int vector.
cvec_sz size
Current size (amount you use when manipulating array directly).
cvec_sz capacity
Allocated size of array; always >= size.
Data structure for string vector.
cvec_sz capacity
Allocated size of array; always >= size.
cvec_sz size
Current size (amount you use when manipulating array directly).
Data structure for generic type (cast to void) vectors.
cvec_sz size
Current size (amount you should use when manipulating array directly).
cvec_sz elem_size
Size in bytes of type stored (sizeof(T) where T is type).
cvec_sz capacity
Allocated size of array; always >= size.
void(* elem_free)(void *)
int(* elem_init)(void *, void *)