45 #if defined(CVEC_ONLY_INT) || defined(CVEC_ONLY_DOUBLE) || defined(CVEC_ONLY_STR) || defined(CVEC_ONLY_VOID)
49 #ifndef CVEC_ONLY_DOUBLE
50 #define CVEC_NO_DOUBLE
55 #ifndef CVEC_ONLY_VOID
60 #if defined(CVEC_MALLOC) && defined(CVEC_FREE) && defined(CVEC_REALLOC)
62 #elif !defined(CVEC_MALLOC) && !defined(CVEC_FREE) && !defined(CVEC_REALLOC)
65 #error "Must define all or none of CVEC_MALLOC, CVEC_FREE, and CVEC_REALLOC."
69 #define CVEC_MALLOC(sz) malloc(sz)
70 #define CVEC_REALLOC(p, sz) realloc(p, sz)
71 #define CVEC_FREE(p) free(p)
76 #define CVEC_MEMMOVE(dst, src, sz) memmove(dst, src, sz)
81 #define CVEC_ASSERT(x) assert(x)
85 #define CVEC_SIZE_T size_t
137 #ifndef CVEC_NO_DOUBLE
195 #define CVEC_STRDUP cvec_strdup
211 #define cvec_popm_str(vec) (vec).a[--(vec).size]
214 #define cvec_replacem_str(vec, i, s, ret) ((ret) = (vec).a[i], (vec).a[i] = (s))
254 #define CVEC_GET_VOID(VEC, TYPE, I) ((TYPE*)&(VEC)->a[(I)*(VEC)->elem_size])
300 #define CVEC_NEW_DECLS(TYPE) \
301 typedef struct cvector_##TYPE { \
307 extern cvec_sz CVEC_##TYPE##_SZ; \
309 int cvec_##TYPE(cvector_##TYPE* vec, cvec_sz size, cvec_sz capacity); \
310 int cvec_init_##TYPE(cvector_##TYPE* vec, TYPE* vals, cvec_sz num); \
312 cvector_##TYPE* cvec_##TYPE##_heap(cvec_sz size, cvec_sz capacity); \
313 cvector_##TYPE* cvec_init_##TYPE##_heap(TYPE* vals, cvec_sz num); \
315 int cvec_copyc_##TYPE(void* dest, void* src); \
316 int cvec_copy_##TYPE(cvector_##TYPE* dest, cvector_##TYPE* src); \
318 int cvec_push_##TYPE(cvector_##TYPE* vec, TYPE a); \
319 TYPE cvec_pop_##TYPE(cvector_##TYPE* vec); \
321 int cvec_extend_##TYPE(cvector_##TYPE* vec, cvec_sz num); \
322 int cvec_insert_##TYPE(cvector_##TYPE* vec, cvec_sz i, TYPE a); \
323 int cvec_insert_array_##TYPE(cvector_##TYPE* vec, cvec_sz i, TYPE* a, cvec_sz num); \
324 TYPE cvec_replace_##TYPE(cvector_##TYPE* vec, cvec_sz i, TYPE a); \
325 void cvec_erase_##TYPE(cvector_##TYPE* vec, cvec_sz start, cvec_sz end); \
326 int cvec_reserve_##TYPE(cvector_##TYPE* vec, cvec_sz size); \
327 int cvec_set_cap_##TYPE(cvector_##TYPE* vec, cvec_sz size); \
328 void cvec_set_val_sz_##TYPE(cvector_##TYPE* vec, TYPE val); \
329 void cvec_set_val_cap_##TYPE(cvector_##TYPE* vec, TYPE val); \
331 TYPE* cvec_back_##TYPE(cvector_##TYPE* vec); \
333 void cvec_clear_##TYPE(cvector_##TYPE* vec); \
334 void cvec_free_##TYPE##_heap(void* vec); \
335 void cvec_free_##TYPE(void* vec);
337 #define CVEC_NEW_DEFS(TYPE, RESIZE_MACRO) \
338 cvec_sz CVEC_##TYPE##_SZ = 50; \
340 cvector_##TYPE* cvec_##TYPE##_heap(cvec_sz size, cvec_sz capacity) \
342 cvector_##TYPE* vec; \
343 if (!(vec = (cvector_##TYPE*)CVEC_MALLOC(sizeof(cvector_##TYPE)))) { \
344 CVEC_ASSERT(vec != NULL); \
349 vec->capacity = (capacity > vec->size || (vec->size && capacity == vec->size)) \
351 : vec->size + CVEC_##TYPE##_SZ; \
353 if (!(vec->a = (TYPE*)CVEC_MALLOC(vec->capacity * sizeof(TYPE)))) { \
354 CVEC_ASSERT(vec->a != NULL); \
362 cvector_##TYPE* cvec_init_##TYPE##_heap(TYPE* vals, cvec_sz num) \
364 cvector_##TYPE* vec; \
366 if (!(vec = (cvector_##TYPE*)CVEC_MALLOC(sizeof(cvector_##TYPE)))) { \
367 CVEC_ASSERT(vec != NULL); \
371 vec->capacity = num + CVEC_##TYPE##_SZ; \
373 if (!(vec->a = (TYPE*)CVEC_MALLOC(vec->capacity * sizeof(TYPE)))) { \
374 CVEC_ASSERT(vec->a != NULL); \
379 CVEC_MEMMOVE(vec->a, vals, sizeof(TYPE) * num); \
384 int cvec_##TYPE(cvector_##TYPE* vec, cvec_sz size, cvec_sz capacity) \
387 vec->capacity = (capacity > vec->size || (vec->size && capacity == vec->size)) \
389 : vec->size + CVEC_##TYPE##_SZ; \
391 if (!(vec->a = (TYPE*)CVEC_MALLOC(vec->capacity * sizeof(TYPE)))) { \
392 CVEC_ASSERT(vec->a != NULL); \
393 vec->size = vec->capacity = 0; \
400 int cvec_init_##TYPE(cvector_##TYPE* vec, TYPE* vals, cvec_sz num) \
402 vec->capacity = num + CVEC_##TYPE##_SZ; \
404 if (!(vec->a = (TYPE*)CVEC_MALLOC(vec->capacity * sizeof(TYPE)))) { \
405 CVEC_ASSERT(vec->a != NULL); \
406 vec->size = vec->capacity = 0; \
410 CVEC_MEMMOVE(vec->a, vals, sizeof(TYPE) * num); \
415 int cvec_copyc_##TYPE(void* dest, void* src) \
417 cvector_##TYPE* vec1 = (cvector_##TYPE*)dest; \
418 cvector_##TYPE* vec2 = (cvector_##TYPE*)src; \
422 vec1->capacity = 0; \
424 return cvec_copy_##TYPE(vec1, vec2); \
427 int cvec_copy_##TYPE(cvector_##TYPE* dest, cvector_##TYPE* src) \
430 if (!(tmp = (TYPE*)CVEC_REALLOC(dest->a, src->capacity*sizeof(TYPE)))) { \
431 CVEC_ASSERT(tmp != NULL); \
436 CVEC_MEMMOVE(dest->a, src->a, src->size*sizeof(TYPE)); \
437 dest->size = src->size; \
438 dest->capacity = src->capacity; \
442 int cvec_push_##TYPE(cvector_##TYPE* vec, TYPE a) \
446 if (vec->capacity > vec->size) { \
447 vec->a[vec->size++] = a; \
449 tmp_sz = RESIZE_MACRO(vec->capacity); \
450 if (!(tmp = (TYPE*)CVEC_REALLOC(vec->a, sizeof(TYPE) * tmp_sz))) { \
451 CVEC_ASSERT(tmp != NULL); \
455 vec->a[vec->size++] = a; \
456 vec->capacity = tmp_sz; \
461 TYPE cvec_pop_##TYPE(cvector_##TYPE* vec) { return vec->a[--vec->size]; } \
463 TYPE* cvec_back_##TYPE(cvector_##TYPE* vec) { return &vec->a[vec->size - 1]; } \
465 int cvec_extend_##TYPE(cvector_##TYPE* vec, cvec_sz num) \
469 if (vec->capacity < vec->size + num) { \
470 tmp_sz = vec->capacity + num + CVEC_##TYPE##_SZ; \
471 if (!(tmp = (TYPE*)CVEC_REALLOC(vec->a, sizeof(TYPE) * tmp_sz))) { \
472 CVEC_ASSERT(tmp != NULL); \
476 vec->capacity = tmp_sz; \
483 int cvec_insert_##TYPE(cvector_##TYPE* vec, cvec_sz i, TYPE a) \
487 if (vec->capacity > vec->size) { \
488 CVEC_MEMMOVE(&vec->a[i + 1], &vec->a[i], (vec->size - i) * sizeof(TYPE)); \
491 tmp_sz = RESIZE_MACRO(vec->capacity); \
492 if (!(tmp = (TYPE*)CVEC_REALLOC(vec->a, sizeof(TYPE) * tmp_sz))) { \
493 CVEC_ASSERT(tmp != NULL); \
497 CVEC_MEMMOVE(&vec->a[i + 1], &vec->a[i], (vec->size - i) * sizeof(TYPE)); \
499 vec->capacity = tmp_sz; \
506 int cvec_insert_array_##TYPE(cvector_##TYPE* vec, cvec_sz i, TYPE* a, cvec_sz num) \
510 if (vec->capacity < vec->size + num) { \
511 tmp_sz = vec->capacity + num + CVEC_##TYPE##_SZ; \
512 if (!(tmp = (TYPE*)CVEC_REALLOC(vec->a, sizeof(TYPE) * tmp_sz))) { \
513 CVEC_ASSERT(tmp != NULL); \
517 vec->capacity = tmp_sz; \
520 CVEC_MEMMOVE(&vec->a[i + num], &vec->a[i], (vec->size - i) * sizeof(TYPE)); \
521 CVEC_MEMMOVE(&vec->a[i], a, num * sizeof(TYPE)); \
526 TYPE cvec_replace_##TYPE(cvector_##TYPE* vec, cvec_sz i, TYPE a) \
528 TYPE tmp = vec->a[i]; \
533 void cvec_erase_##TYPE(cvector_##TYPE* vec, cvec_sz start, cvec_sz end) \
535 cvec_sz d = end - start + 1; \
536 CVEC_MEMMOVE(&vec->a[start], &vec->a[end + 1], (vec->size - 1 - end) * sizeof(TYPE)); \
540 int cvec_reserve_##TYPE(cvector_##TYPE* vec, cvec_sz size) \
543 if (vec->capacity < size) { \
544 if (!(tmp = (TYPE*)CVEC_REALLOC(vec->a, sizeof(TYPE) * (size + CVEC_##TYPE##_SZ)))) { \
545 CVEC_ASSERT(tmp != NULL); \
549 vec->capacity = size + CVEC_##TYPE##_SZ; \
554 int cvec_set_cap_##TYPE(cvector_##TYPE* vec, cvec_sz size) \
557 if (size < vec->size) { \
561 if (!(tmp = (TYPE*)CVEC_REALLOC(vec->a, sizeof(TYPE) * size))) { \
562 CVEC_ASSERT(tmp != NULL); \
566 vec->capacity = size; \
570 void cvec_set_val_sz_##TYPE(cvector_##TYPE* vec, TYPE val) \
573 for (i = 0; i < vec->size; i++) { \
578 void cvec_set_val_cap_##TYPE(cvector_##TYPE* vec, TYPE val) \
581 for (i = 0; i < vec->capacity; i++) { \
586 void cvec_clear_##TYPE(cvector_##TYPE* vec) { vec->size = 0; } \
588 void cvec_free_##TYPE##_heap(void* vec) \
590 cvector_##TYPE* tmp = (cvector_##TYPE*)vec; \
596 void cvec_free_##TYPE(void* vec) \
598 cvector_##TYPE* tmp = (cvector_##TYPE*)vec; \
604 #define CVEC_NEW_DECLS2(TYPE) \
605 typedef struct cvector_##TYPE { \
609 void (*elem_free)(void*); \
610 int (*elem_init)(void*, void*); \
613 extern cvec_sz CVEC_##TYPE##_SZ; \
615 int cvec_##TYPE(cvector_##TYPE* vec, cvec_sz size, cvec_sz capacity, void (*elem_free)(void*), \
616 int (*elem_init)(void*, void*)); \
617 int cvec_init_##TYPE(cvector_##TYPE* vec, TYPE* vals, cvec_sz num, void (*elem_free)(void*), \
618 int (*elem_init)(void*, void*)); \
620 cvector_##TYPE* cvec_##TYPE##_heap(cvec_sz size, cvec_sz capacity, void (*elem_free)(void*), \
621 int (*elem_init)(void*, void*)); \
622 cvector_##TYPE* cvec_init_##TYPE##_heap(TYPE* vals, cvec_sz num, void (*elem_free)(void*), \
623 int (*elem_init)(void*, void*)); \
625 int cvec_copyc_##TYPE(void* dest, void* src); \
626 int cvec_copy_##TYPE(cvector_##TYPE* dest, cvector_##TYPE* src); \
628 int cvec_push_##TYPE(cvector_##TYPE* vec, TYPE* val); \
629 void cvec_pop_##TYPE(cvector_##TYPE* vec, TYPE* ret); \
631 int cvec_pushm_##TYPE(cvector_##TYPE* vec, TYPE* a); \
632 void cvec_popm_##TYPE(cvector_##TYPE* vec, TYPE* ret); \
633 int cvec_insertm_##TYPE(cvector_##TYPE* vec, cvec_sz i, TYPE* a); \
634 int cvec_insert_arraym_##TYPE(cvector_##TYPE* vec, cvec_sz i, TYPE* a, cvec_sz num); \
635 void cvec_replacem_##TYPE(cvector_##TYPE* vec, cvec_sz i, TYPE* a, TYPE* ret); \
637 int cvec_extend_##TYPE(cvector_##TYPE* vec, cvec_sz num); \
638 int cvec_insert_##TYPE(cvector_##TYPE* vec, cvec_sz i, TYPE* a); \
639 int cvec_insert_array_##TYPE(cvector_##TYPE* vec, cvec_sz i, TYPE* a, cvec_sz num); \
640 int cvec_replace_##TYPE(cvector_##TYPE* vec, cvec_sz i, TYPE* a, TYPE* ret); \
641 void cvec_erase_##TYPE(cvector_##TYPE* vec, cvec_sz start, cvec_sz end); \
642 void cvec_remove_##TYPE(cvector_##TYPE* vec, cvec_sz start, cvec_sz end); \
643 int cvec_reserve_##TYPE(cvector_##TYPE* vec, cvec_sz size); \
644 int cvec_set_cap_##TYPE(cvector_##TYPE* vec, cvec_sz size); \
645 int cvec_set_val_sz_##TYPE(cvector_##TYPE* vec, TYPE* val); \
646 int cvec_set_val_cap_##TYPE(cvector_##TYPE* vec, TYPE* val); \
648 TYPE* cvec_back_##TYPE(cvector_##TYPE* vec); \
650 void cvec_clear_##TYPE(cvector_##TYPE* vec); \
651 void cvec_free_##TYPE##_heap(void* vec); \
652 void cvec_free_##TYPE(void* vec);
654 #define CVEC_NEW_DEFS2(TYPE, RESIZE_MACRO) \
655 cvec_sz CVEC_##TYPE##_SZ = 20; \
657 cvector_##TYPE* cvec_##TYPE##_heap(cvec_sz size, cvec_sz capacity, void (*elem_free)(void*), \
658 int (*elem_init)(void*, void*)) \
660 cvector_##TYPE* vec; \
661 if (!(vec = (cvector_##TYPE*)CVEC_MALLOC(sizeof(cvector_##TYPE)))) { \
662 CVEC_ASSERT(vec != NULL); \
667 vec->capacity = (capacity > vec->size || (vec->size && capacity == vec->size)) \
669 : vec->size + CVEC_##TYPE##_SZ; \
671 if (!(vec->a = (TYPE*)CVEC_MALLOC(vec->capacity * sizeof(TYPE)))) { \
672 CVEC_ASSERT(vec->a != NULL); \
677 vec->elem_free = elem_free; \
678 vec->elem_init = elem_init; \
683 cvector_##TYPE* cvec_init_##TYPE##_heap(TYPE* vals, cvec_sz num, void (*elem_free)(void*), \
684 int (*elem_init)(void*, void*)) \
686 cvector_##TYPE* vec; \
689 if (!(vec = (cvector_##TYPE*)CVEC_MALLOC(sizeof(cvector_##TYPE)))) { \
690 CVEC_ASSERT(vec != NULL); \
694 vec->capacity = num + CVEC_##TYPE##_SZ; \
696 if (!(vec->a = (TYPE*)CVEC_MALLOC(vec->capacity * sizeof(TYPE)))) { \
697 CVEC_ASSERT(vec->a != NULL); \
703 for (i = 0; i < num; ++i) { \
704 if (!elem_init(&vec->a[i], &vals[i])) { \
712 CVEC_MEMMOVE(vec->a, vals, sizeof(TYPE) * num); \
715 vec->elem_free = elem_free; \
716 vec->elem_init = elem_init; \
721 int cvec_##TYPE(cvector_##TYPE* vec, cvec_sz size, cvec_sz capacity, void (*elem_free)(void*), \
722 int (*elem_init)(void*, void*)) \
725 vec->capacity = (capacity > vec->size || (vec->size && capacity == vec->size)) \
727 : vec->size + CVEC_##TYPE##_SZ; \
729 if (!(vec->a = (TYPE*)CVEC_MALLOC(vec->capacity * sizeof(TYPE)))) { \
730 CVEC_ASSERT(vec->a != NULL); \
731 vec->size = vec->capacity = 0; \
735 vec->elem_free = elem_free; \
736 vec->elem_init = elem_init; \
741 int cvec_init_##TYPE(cvector_##TYPE* vec, TYPE* vals, cvec_sz num, void (*elem_free)(void*), \
742 int (*elem_init)(void*, void*)) \
746 vec->capacity = num + CVEC_##TYPE##_SZ; \
748 if (!(vec->a = (TYPE*)CVEC_MALLOC(vec->capacity * sizeof(TYPE)))) { \
749 CVEC_ASSERT(vec->a != NULL); \
750 vec->size = vec->capacity = 0; \
755 for (i = 0; i < num; ++i) { \
756 if (!elem_init(&vec->a[i], &vals[i])) { \
762 CVEC_MEMMOVE(vec->a, vals, sizeof(TYPE) * num); \
765 vec->elem_free = elem_free; \
766 vec->elem_init = elem_init; \
771 int cvec_copyc_##TYPE(void* dest, void* src) \
773 cvector_##TYPE* vec1 = (cvector_##TYPE*)dest; \
774 cvector_##TYPE* vec2 = (cvector_##TYPE*)src; \
778 vec1->capacity = 0; \
780 return cvec_copy_##TYPE(vec1, vec2); \
783 int cvec_copy_##TYPE(cvector_##TYPE* dest, cvector_##TYPE* src) \
787 if (!(tmp = (TYPE*)CVEC_REALLOC(dest->a, src->capacity*sizeof(TYPE)))) { \
788 CVEC_ASSERT(tmp != NULL); \
793 if (src->elem_init) { \
794 for (i=0; i<src->size; ++i) { \
795 if (!src->elem_init(&dest->a[i], &src->a[i])) { \
801 CVEC_MEMMOVE(dest->a, src->a, src->size*sizeof(TYPE)); \
804 dest->size = src->size; \
805 dest->capacity = src->capacity; \
806 dest->elem_free = src->elem_free; \
807 dest->elem_init = src->elem_init; \
811 int cvec_push_##TYPE(cvector_##TYPE* vec, TYPE* a) \
815 if (vec->capacity == vec->size) { \
816 tmp_sz = RESIZE_MACRO(vec->capacity); \
817 if (!(tmp = (TYPE*)CVEC_REALLOC(vec->a, sizeof(TYPE) * tmp_sz))) { \
818 CVEC_ASSERT(tmp != NULL); \
822 vec->capacity = tmp_sz; \
824 if (vec->elem_init) { \
825 if (!vec->elem_init(&vec->a[vec->size], a)) { \
830 CVEC_MEMMOVE(&vec->a[vec->size], a, sizeof(TYPE)); \
837 int cvec_pushm_##TYPE(cvector_##TYPE* vec, TYPE* a) \
841 if (vec->capacity == vec->size) { \
842 tmp_sz = RESIZE_MACRO(vec->capacity); \
843 if (!(tmp = (TYPE*)CVEC_REALLOC(vec->a, sizeof(TYPE) * tmp_sz))) { \
844 CVEC_ASSERT(tmp != NULL); \
848 vec->capacity = tmp_sz; \
850 CVEC_MEMMOVE(&vec->a[vec->size], a, sizeof(TYPE)); \
856 void cvec_pop_##TYPE(cvector_##TYPE* vec, TYPE* ret) \
859 CVEC_MEMMOVE(ret, &vec->a[--vec->size], sizeof(TYPE)); \
864 if (vec->elem_free) { \
865 vec->elem_free(&vec->a[vec->size]); \
869 void cvec_popm_##TYPE(cvector_##TYPE* vec, TYPE* ret) \
873 CVEC_MEMMOVE(ret, &vec->a[vec->size], sizeof(TYPE)); \
877 TYPE* cvec_back_##TYPE(cvector_##TYPE* vec) { return &vec->a[vec->size - 1]; } \
879 int cvec_extend_##TYPE(cvector_##TYPE* vec, cvec_sz num) \
883 if (vec->capacity < vec->size + num) { \
884 tmp_sz = vec->capacity + num + CVEC_##TYPE##_SZ; \
885 if (!(tmp = (TYPE*)CVEC_REALLOC(vec->a, sizeof(TYPE) * tmp_sz))) { \
886 CVEC_ASSERT(tmp != NULL); \
890 vec->capacity = tmp_sz; \
897 int cvec_insert_##TYPE(cvector_##TYPE* vec, cvec_sz i, TYPE* a) \
901 if (vec->capacity == vec->size) { \
902 tmp_sz = RESIZE_MACRO(vec->capacity); \
903 if (!(tmp = (TYPE*)CVEC_REALLOC(vec->a, sizeof(TYPE) * tmp_sz))) { \
904 CVEC_ASSERT(tmp != NULL); \
909 vec->capacity = tmp_sz; \
911 CVEC_MEMMOVE(&vec->a[i + 1], &vec->a[i], (vec->size - i) * sizeof(TYPE)); \
913 if (vec->elem_init) { \
914 if (!vec->elem_init(&vec->a[i], a)) { \
919 CVEC_MEMMOVE(&vec->a[i], a, sizeof(TYPE)); \
926 int cvec_insertm_##TYPE(cvector_##TYPE* vec, cvec_sz i, TYPE* a) \
930 if (vec->capacity == vec->size) { \
931 tmp_sz = RESIZE_MACRO(vec->capacity); \
932 if (!(tmp = (TYPE*)CVEC_REALLOC(vec->a, sizeof(TYPE) * tmp_sz))) { \
933 CVEC_ASSERT(tmp != NULL); \
938 vec->capacity = tmp_sz; \
940 CVEC_MEMMOVE(&vec->a[i + 1], &vec->a[i], (vec->size - i) * sizeof(TYPE)); \
942 CVEC_MEMMOVE(&vec->a[i], a, sizeof(TYPE)); \
948 int cvec_insert_array_##TYPE(cvector_##TYPE* vec, cvec_sz i, TYPE* a, cvec_sz num) \
952 if (vec->capacity < vec->size + num) { \
953 tmp_sz = vec->capacity + num + CVEC_##TYPE##_SZ; \
954 if (!(tmp = (TYPE*)CVEC_REALLOC(vec->a, sizeof(TYPE) * tmp_sz))) { \
955 CVEC_ASSERT(tmp != NULL); \
959 vec->capacity = tmp_sz; \
962 CVEC_MEMMOVE(&vec->a[i + num], &vec->a[i], (vec->size - i) * sizeof(TYPE)); \
963 if (vec->elem_init) { \
964 for (j = 0; j < num; ++j) { \
965 if (!vec->elem_init(&vec->a[j + i], &a[j])) { \
971 CVEC_MEMMOVE(&vec->a[i], a, num * sizeof(TYPE)); \
977 int cvec_insert_arraym_##TYPE(cvector_##TYPE* vec, cvec_sz i, TYPE* a, cvec_sz num) \
981 if (vec->capacity < vec->size + num) { \
982 tmp_sz = vec->capacity + num + CVEC_##TYPE##_SZ; \
983 if (!(tmp = (TYPE*)CVEC_REALLOC(vec->a, sizeof(TYPE) * tmp_sz))) { \
984 CVEC_ASSERT(tmp != NULL); \
988 vec->capacity = tmp_sz; \
991 CVEC_MEMMOVE(&vec->a[i + num], &vec->a[i], (vec->size - i) * sizeof(TYPE)); \
993 CVEC_MEMMOVE(&vec->a[i], a, num * sizeof(TYPE)); \
998 int cvec_replace_##TYPE(cvector_##TYPE* vec, cvec_sz i, TYPE* a, TYPE* ret) \
1001 CVEC_MEMMOVE(ret, &vec->a[i], sizeof(TYPE)); \
1002 } else if (vec->elem_free) { \
1003 vec->elem_free(&vec->a[i]); \
1006 if (vec->elem_init) { \
1007 if (!vec->elem_init(&vec->a[i], a)) { \
1012 CVEC_MEMMOVE(&vec->a[i], a, sizeof(TYPE)); \
1017 void cvec_replacem_##TYPE(cvector_##TYPE* vec, cvec_sz i, TYPE* a, TYPE* ret) \
1020 CVEC_MEMMOVE(ret, &vec->a[i], sizeof(TYPE)); \
1023 CVEC_MEMMOVE(&vec->a[i], a, sizeof(TYPE)); \
1026 void cvec_erase_##TYPE(cvector_##TYPE* vec, cvec_sz start, cvec_sz end) \
1029 cvec_sz d = end - start + 1; \
1030 if (vec->elem_free) { \
1031 for (i = start; i <= end; i++) { \
1032 vec->elem_free(&vec->a[i]); \
1035 CVEC_MEMMOVE(&vec->a[start], &vec->a[end + 1], (vec->size - 1 - end) * sizeof(TYPE)); \
1039 void cvec_remove_##TYPE(cvector_##TYPE* vec, cvec_sz start, cvec_sz end) \
1041 cvec_sz d = end - start + 1; \
1042 CVEC_MEMMOVE(&vec->a[start], &vec->a[end + 1], (vec->size - 1 - end) * sizeof(TYPE)); \
1046 int cvec_reserve_##TYPE(cvector_##TYPE* vec, cvec_sz size) \
1049 if (vec->capacity < size) { \
1050 if (!(tmp = (TYPE*)CVEC_REALLOC(vec->a, sizeof(TYPE) * (size + CVEC_##TYPE##_SZ)))) { \
1051 CVEC_ASSERT(tmp != NULL); \
1055 vec->capacity = size + CVEC_##TYPE##_SZ; \
1060 int cvec_set_cap_##TYPE(cvector_##TYPE* vec, cvec_sz size) \
1064 if (size < vec->size) { \
1065 if (vec->elem_free) { \
1066 for (i = vec->size - 1; i >= size; i--) { \
1067 vec->elem_free(&vec->a[i]); \
1073 vec->capacity = size; \
1075 if (!(tmp = (TYPE*)CVEC_REALLOC(vec->a, sizeof(TYPE) * size))) { \
1076 CVEC_ASSERT(tmp != NULL); \
1083 int cvec_set_val_sz_##TYPE(cvector_##TYPE* vec, TYPE* val) \
1087 if (vec->elem_free) { \
1088 for (i = 0; i < vec->size; i++) { \
1089 vec->elem_free(&vec->a[i]); \
1093 if (vec->elem_init) { \
1094 for (i = 0; i < vec->size; i++) { \
1095 if (!vec->elem_init(&vec->a[i], val)) { \
1101 for (i = 0; i < vec->size; i++) { \
1102 CVEC_MEMMOVE(&vec->a[i], val, sizeof(TYPE)); \
1108 int cvec_set_val_cap_##TYPE(cvector_##TYPE* vec, TYPE* val) \
1111 if (vec->elem_free) { \
1112 for (i = 0; i < vec->size; i++) { \
1113 vec->elem_free(&vec->a[i]); \
1115 vec->size = vec->capacity; \
1118 if (vec->elem_init) { \
1119 for (i = 0; i < vec->capacity; i++) { \
1120 if (!vec->elem_init(&vec->a[i], val)) { \
1126 for (i = 0; i < vec->capacity; i++) { \
1127 CVEC_MEMMOVE(&vec->a[i], val, sizeof(TYPE)); \
1133 void cvec_clear_##TYPE(cvector_##TYPE* vec) \
1136 if (vec->elem_free) { \
1137 for (i = 0; i < vec->size; ++i) { \
1138 vec->elem_free(&vec->a[i]); \
1144 void cvec_free_##TYPE##_heap(void* vec) \
1147 cvector_##TYPE* tmp = (cvector_##TYPE*)vec; \
1149 if (tmp->elem_free) { \
1150 for (i = 0; i < tmp->size; i++) { \
1151 tmp->elem_free(&tmp->a[i]); \
1154 CVEC_FREE(tmp->a); \
1158 void cvec_free_##TYPE(void* vec) \
1161 cvector_##TYPE* tmp = (cvector_##TYPE*)vec; \
1162 if (tmp->elem_free) { \
1163 for (i = 0; i < tmp->size; i++) { \
1164 tmp->elem_free(&tmp->a[i]); \
1168 CVEC_FREE(tmp->a); \
1171 tmp->capacity = 0; \
1180 #ifdef CVECTOR_IMPLEMENTATION
1186 #define CVEC_I_ALLOCATOR(x) ((x+1) * 2)
1331 if (!(tmp = (
int*)
CVEC_REALLOC(vec->
a,
sizeof(
int)*tmp_sz))) {
1339 vec->
a[vec->
size++] = a;
1346 return vec->
a[--vec->
size];
1352 return &vec->
a[vec->
size-1];
1363 if (!(tmp = (
int*)
CVEC_REALLOC(vec->
a,
sizeof(
int)*tmp_sz))) {
1385 if (!(tmp = (
int*)
CVEC_REALLOC(vec->
a,
sizeof(
int)*tmp_sz))) {
1411 if (!(tmp = (
int*)
CVEC_REALLOC(vec->
a,
sizeof(
int)*tmp_sz))) {
1428 int tmp = vec->
a[i];
1467 if (size < vec->size) {
1471 if (!(tmp = (
int*)
CVEC_REALLOC(vec->
a,
sizeof(
int)*size))) {
1484 for (i=0; i<vec->
size; i++) {
1522 #ifndef CVEC_NO_DOUBLE
1526 #define CVEC_D_ALLOCATOR(x) ((x+1) * 2)
1672 if (!(tmp = (
double*)
CVEC_REALLOC(vec->
a,
sizeof(
double)*tmp_sz))) {
1679 vec->
a[vec->
size++] = a;
1686 return vec->
a[--vec->
size];
1692 return &vec->
a[vec->
size-1];
1703 if (!(tmp = (
double*)
CVEC_REALLOC(vec->
a,
sizeof(
double)*tmp_sz))) {
1725 if (!(tmp = (
double*)
CVEC_REALLOC(vec->
a,
sizeof(
double)*tmp_sz))) {
1751 if (!(tmp = (
double*)
CVEC_REALLOC(vec->
a,
sizeof(
double)*tmp_sz))) {
1768 double tmp = vec->
a[i];
1807 if (size < vec->size)
1810 if (!(tmp = (
double*)
CVEC_REALLOC(vec->
a,
sizeof(
double)*size))) {
1823 for(i=0; i<vec->
size; i++) {
1863 #define CVEC_STR_ALLOCATOR(x) ((x+1) * 2)
1865 #if CVEC_STRDUP == cvec_strdup
1916 memset(vec->
a, 0, vec->
capacity*
sizeof(
char*));
1941 for(i=0; i<num; i++) {
1964 memset(vec->
a, 0, vec->
capacity*
sizeof(
char*));
1984 for(i=0; i<num; i++) {
2032 for (i=0; i<src->
size; ++i) {
2050 if (!(tmp = (
char**)
CVEC_REALLOC(vec->
a,
sizeof(
char*)*tmp_sz))) {
2069 if (!(tmp = (
char**)
CVEC_REALLOC(vec->
a,
sizeof(
char*)*tmp_sz))) {
2077 vec->
a[vec->
size++] = a;
2089 strcpy(ret, vec->
a[vec->
size]);
2096 return &vec->
a[vec->
size-1];
2108 if (!(tmp = (
char**)
CVEC_REALLOC(vec->
a,
sizeof(
char*)*tmp_sz))) {
2116 memset(&vec->
a[vec->
size], 0, num*
sizeof(
char*));
2131 if (!(tmp = (
char**)
CVEC_REALLOC(vec->
a,
sizeof(
char*)*tmp_sz))) {
2154 if (!(tmp = (
char**)
CVEC_REALLOC(vec->
a,
sizeof(
char*)*tmp_sz))) {
2179 if (!(tmp = (
char**)
CVEC_REALLOC(vec->
a,
sizeof(
char*)*tmp_sz))) {
2188 for (j=0; j<num; ++j) {
2205 if (!(tmp = (
char**)
CVEC_REALLOC(vec->
a,
sizeof(
char*)*tmp_sz))) {
2227 strcpy(ret, vec->
a[i]);
2241 for (i=start; i<=end; i++) {
2280 if (size < vec->size) {
2281 for(i=vec->
size-1; i>size-1; i--) {
2288 if (!(tmp = (
char**)
CVEC_REALLOC(vec->
a,
sizeof(
char*)*size))) {
2301 for(i=0; i<vec->
size; i++) {
2330 for (i=0; i<vec->
size; i++) {
2344 for (i=0; i<tmp->
size; i++) {
2357 for (i=0; i<tmp->
size; i++) {
2367 #ifndef CVEC_NO_VOID
2371 #define CVEC_VOID_ALLOCATOR(x) ((x+1) * 2)
2453 for (i=0; i<num; ++i) {
2454 if (!elem_init(&vec->
a[i*elem_sz], &((
cvec_u8*)vals)[i*elem_sz])) {
2511 for (i=0; i<num; ++i) {
2512 if (!elem_init(&vec->
a[i*elem_sz], &((
cvec_u8*)vals)[i*elem_sz])) {
2569 for (i=0; i<src->
size; ++i) {
2781 for (j=0; j<num; ++j) {
2862 for (i=start; i<=end; i++) {
2901 if (size < vec->size) {
2903 for (i=vec->
size-1; i>=size; i--) {
2926 for(i=0; i<vec->
size; i++) {
2932 for (i=0; i<vec->
size; i++) {
2939 for (i=0; i<vec->
size; i++) {
2955 for (i=0; i<vec->
size; i++) {
2982 for (i=0; i<vec->
size; ++i) {
2998 for (i=0; i<tmp->
size; i++) {
3012 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.
cvector_d * cvec_d_heap(cvec_sz size, cvec_sz capacity)
Creates a new cvector_d on the heap.
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.
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_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).
char * cvec_strdup(const char *str)
Useful utility function since strdup isn't in standard C.
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 sets size and capacity to 0.
void cvec_free_d(void *vec)
Frees the internal array and sets size and capacity to 0.
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.
#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.
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_init_d_heap(double *vals, cvec_sz num)
Create (on the heap) and initialize cvector_d with num elements of vals.
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.
cvector_i * cvec_init_i_heap(int *vals, cvec_sz num)
Create (on the heap) and initialize cvector_i with num elements of vals.
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.
void * cvec_back_void(cvector_void *vec)
Return pointer to last element.
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.
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 ...
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.
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...
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 sets size and capacity to 0.
void cvec_pop_void(cvector_void *vec, void *ret)
Remove the last element (size decreased 1).
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.
char ** cvec_back_str(cvector_str *vec)
Return pointer to last element.
cvector_i * cvec_i_heap(cvec_sz size, cvec_sz capacity)
Creates a new cvector_i on the heap.
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_back_i(cvector_i *vec)
Return pointer to last element.
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 size and capacity to 0.
int cvec_set_cap_d(cvector_d *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.
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.
double * cvec_back_d(cvector_d *vec)
Return pointer to last element.
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).
void * cvec_get_void(cvector_void *vec, cvec_sz i)
Return a void pointer to the ith element.
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.
cvector_str * cvec_str_heap(cvec_sz size, cvec_sz capacity)
Create a new cvector_str on the heap.
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.
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_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).
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 *)