CVector 4.3.0
A C++ style vector library in strict ANSI C (C89)
Loading...
Searching...
No Matches
cvector.h
Go to the documentation of this file.
1/*
2
3CVector 4.2.1 MIT Licensed vector (dynamic array) library in strict C89
4http://www.robertwinkler.com/projects/cvector.html
5http://www.robertwinkler.com/projects/cvector/
6
7Besides the docs and all the Doxygen comments, see cvector_tests.c for
8examples of how to use it or look at any of these other projects for
9more practical examples:
10
11https://github.com/rswinkle/C_Interpreter
12https://github.com/rswinkle/CPIM2
13https://github.com/rswinkle/spelling_game
14https://github.com/rswinkle/c_bigint
15http://portablegl.com/
16
17The MIT License (MIT)
18
19Copyright (c) 2011-2025 Robert Winkler
20
21Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated
22documentation files (the "Software"), to deal in the Software without restriction, including without limitation
23the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and
24to permit persons to whom the Software is furnished to do so, subject to the following conditions:
25
26The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
27
28THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
29TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
30THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
31CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
32IN THE SOFTWARE.
33*/
34
35
36/* header starts */
37
38#ifndef CVECTOR_H
39#define CVECTOR_H
40
41#if defined(CVEC_ONLY_INT) || defined(CVEC_ONLY_DOUBLE) || defined(CVEC_ONLY_STR) || defined(CVEC_ONLY_VOID)
42 #ifndef CVEC_ONLY_INT
43 #define CVEC_NO_INT
44 #endif
45 #ifndef CVEC_ONLY_DOUBLE
46 #define CVEC_NO_DOUBLE
47 #endif
48 #ifndef CVEC_ONLY_STR
49 #define CVEC_NO_STR
50 #endif
51 #ifndef CVEC_ONLY_VOID
52 #define CVEC_NO_VOID
53 #endif
54#endif
55
56#if defined(CVEC_MALLOC) && defined(CVEC_FREE) && defined(CVEC_REALLOC)
57/* ok */
58#elif !defined(CVEC_MALLOC) && !defined(CVEC_FREE) && !defined(CVEC_REALLOC)
59/* ok */
60#else
61#error "Must define all or none of CVEC_MALLOC, CVEC_FREE, and CVEC_REALLOC."
62#endif
63
64#ifndef CVEC_MALLOC
65#include <stdlib.h>
66#define CVEC_MALLOC(sz) malloc(sz)
67#define CVEC_REALLOC(p, sz) realloc(p, sz)
68#define CVEC_FREE(p) free(p)
69#endif
70
71#ifndef CVEC_MEMMOVE
72#include <string.h>
73#define CVEC_MEMMOVE(dst, src, sz) memmove(dst, src, sz)
74#endif
75
76#ifndef CVEC_ASSERT
77#include <assert.h>
78#define CVEC_ASSERT(x) assert(x)
79#endif
80
81#ifndef CVEC_SIZE_T
82#include <stdlib.h>
83#define CVEC_SIZE_T size_t
84#endif
85
86#ifndef CVEC_SZ
87#define CVEC_SZ
89#endif
90
91#ifdef __cplusplus
92extern "C" {
93#endif
94
95#ifndef CVEC_NO_INT
96
97
98
100typedef struct cvector_i
101{
102 int* a;
105} cvector_i;
106
108
109int cvec_i(cvector_i* vec, cvec_sz size, cvec_sz capacity);
110int cvec_init_i(cvector_i* vec, int* vals, cvec_sz num);
111
112cvector_i* cvec_i_heap(cvec_sz size, cvec_sz capacity);
113cvector_i* cvec_init_i_heap(int* vals, cvec_sz num);
114int cvec_copyc_i(void* dest, void* src);
115int cvec_copy_i(cvector_i* dest, cvector_i* src);
116
117int cvec_push_i(cvector_i* vec, int a);
118int cvec_pop_i(cvector_i* vec);
119
120int cvec_extend_i(cvector_i* vec, cvec_sz num);
121int cvec_insert_i(cvector_i* vec, cvec_sz i, int a);
122int cvec_insert_array_i(cvector_i* vec, cvec_sz i, int* a, cvec_sz num);
123int cvec_replace_i(cvector_i* vec, cvec_sz i, int a);
124void cvec_erase_i(cvector_i* vec, cvec_sz start, cvec_sz end);
125int cvec_reserve_i(cvector_i* vec, cvec_sz size);
126#define cvec_shrink_to_fit_i(vec) cvec_set_cap_i((vec), (vec)->size)
127int cvec_set_cap_i(cvector_i* vec, cvec_sz size);
128void cvec_set_val_sz_i(cvector_i* vec, int val);
129void cvec_set_val_cap_i(cvector_i* vec, int val);
130
131int* cvec_back_i(cvector_i* vec);
132
133void cvec_clear_i(cvector_i* vec);
134void cvec_free_i_heap(void* vec);
135void cvec_free_i(void* vec);
136
137#endif
138
139#ifndef CVEC_NO_DOUBLE
140
141
142
144typedef struct cvector_d
145{
146 double* a;
149} cvector_d;
150
152
153int cvec_d(cvector_d* vec, cvec_sz size, cvec_sz capacity);
154int cvec_init_d(cvector_d* vec, double* vals, cvec_sz num);
155
156cvector_d* cvec_d_heap(cvec_sz size, cvec_sz capacity);
157cvector_d* cvec_init_d_heap(double* vals, cvec_sz num);
158int cvec_copyc_d(void* dest, void* src);
159int cvec_copy_d(cvector_d* dest, cvector_d* src);
160
161int cvec_push_d(cvector_d* vec, double a);
162double cvec_pop_d(cvector_d* vec);
163
164int cvec_extend_d(cvector_d* vec, cvec_sz num);
165int cvec_insert_d(cvector_d* vec, cvec_sz i, double a);
166int cvec_insert_array_d(cvector_d* vec, cvec_sz i, double* a, cvec_sz num);
167double cvec_replace_d(cvector_d* vec, cvec_sz i, double a);
168void cvec_erase_d(cvector_d* vec, cvec_sz start, cvec_sz end);
169int cvec_reserve_d(cvector_d* vec, cvec_sz size);
170#define cvec_shrink_to_fit_d(vec) cvec_set_cap_d((vec), (vec)->size)
171int cvec_set_cap_d(cvector_d* vec, cvec_sz size);
172void cvec_set_val_sz_d(cvector_d* vec, double val);
173void cvec_set_val_cap_d(cvector_d* vec, double val);
174
175double* cvec_back_d(cvector_d* vec);
176
177void cvec_clear_d(cvector_d* vec);
178void cvec_free_d_heap(void* vec);
179void cvec_free_d(void* vec);
180
181#endif
182
183#ifndef CVEC_NO_STR
184
185
186
194
196
197#ifndef CVEC_STRDUP
198#define CVEC_STRDUP cvec_strdup
199char* cvec_strdup(const char* str);
200#endif
201
202int cvec_str(cvector_str* vec, cvec_sz size, cvec_sz capacity);
203int cvec_init_str(cvector_str* vec, char** vals, cvec_sz num);
204
206cvector_str* cvec_init_str_heap(char** vals, cvec_sz num);
207int cvec_copyc_str(void* dest, void* src);
208int cvec_copy_str(cvector_str* dest, cvector_str* src);
209
210int cvec_push_str(cvector_str* vec, char* a);
211void cvec_pop_str(cvector_str* vec, char* ret);
212
213int cvec_pushm_str(cvector_str* vec, char* a);
214#define cvec_popm_str(vec) (vec)->a[--(vec)->size]
215int cvec_insertm_str(cvector_str* vec, cvec_sz i, char* a);
216int cvec_insert_arraym_str(cvector_str* vec, cvec_sz i, char** a, cvec_sz num);
217#define cvec_replacem_str(vec, i, s, ret) ((ret) = (vec)->a[i], (vec)->a[i] = (s))
218
219int cvec_extend_str(cvector_str* vec, cvec_sz num);
220int cvec_insert_str(cvector_str* vec, cvec_sz i, char* a);
221int cvec_insert_array_str(cvector_str* vec, cvec_sz i, char** a, cvec_sz num);
222void cvec_replace_str(cvector_str* vec, cvec_sz i, char* a, char* ret);
223void cvec_erase_str(cvector_str* vec, cvec_sz start, cvec_sz end);
224void cvec_remove_str(cvector_str* vec, cvec_sz start, cvec_sz end);
225int cvec_reserve_str(cvector_str* vec, cvec_sz size);
226#define cvec_shrink_to_fit_str(vec) cvec_set_cap_str((vec), (vec)->size)
227int cvec_set_cap_str(cvector_str* vec, cvec_sz size);
228void cvec_set_val_sz_str(cvector_str* vec, char* val);
229void cvec_set_val_cap_str(cvector_str* vec, char* val);
230
231char** cvec_back_str(cvector_str* vec);
232
233void cvec_clear_str(cvector_str* vec);
234void cvec_free_str_heap(void* vec);
235void cvec_free_str(void* vec);
236
237#endif
238
239#ifndef CVEC_NO_VOID
240
241
242
243typedef unsigned char cvec_u8;
244
246typedef struct cvector_void
247{
252 void (*elem_free)(void*);
253 int (*elem_init)(void*, void*);
255
257
258#define CVEC_GET_VOID(VEC, TYPE, I) ((TYPE*)&(VEC)->a[(I)*(VEC)->elem_size])
259
260int cvec_void(cvector_void* vec, cvec_sz size, cvec_sz capacity, cvec_sz elem_sz, void(*elem_free)(void*), int(*elem_init)(void*, void*));
261int cvec_init_void(cvector_void* vec, void* vals, cvec_sz num, cvec_sz elem_sz, void(*elem_free)(void*), int(*elem_init)(void*, void*));
262
263cvector_void* cvec_void_heap(cvec_sz size, cvec_sz capacity, cvec_sz elem_sz, void (*elem_free)(void*), int(*elem_init)(void*, void*));
264cvector_void* cvec_init_void_heap(void* vals, cvec_sz num, cvec_sz elem_sz, void (*elem_free)(void*), int(*elem_init)(void*, void*));
265
266int cvec_copyc_void(void* dest, void* src);
268
269int cvec_push_void(cvector_void* vec, void* a);
270void cvec_pop_void(cvector_void* vec, void* ret);
271void* cvec_get_void(cvector_void* vec, cvec_sz i);
272
273int cvec_pushm_void(cvector_void* vec, void* a);
274void cvec_popm_void(cvector_void* vec, void* ret);
275int cvec_insertm_void(cvector_void* vec, cvec_sz i, void* a);
276int cvec_insert_arraym_void(cvector_void* vec, cvec_sz i, void* a, cvec_sz num);
277void cvec_replacem_void(cvector_void* vec, cvec_sz i, void* a, void* ret);
278
280int cvec_insert_void(cvector_void* vec, cvec_sz i, void* a);
281int cvec_insert_array_void(cvector_void* vec, cvec_sz i, void* a, cvec_sz num);
282int cvec_replace_void(cvector_void* vec, cvec_sz i, void* a, void* ret);
283void cvec_erase_void(cvector_void* vec, cvec_sz start, cvec_sz end);
284void cvec_remove_void(cvector_void* vec, cvec_sz start, cvec_sz end);
286#define cvec_shrink_to_fit_void(vec) cvec_set_cap_void((vec), (vec)->size)
288int cvec_set_val_sz_void(cvector_void* vec, void* val);
289int cvec_set_val_cap_void(cvector_void* vec, void* val);
290
291void* cvec_back_void(cvector_void* vec);
292
294void cvec_free_void_heap(void* vec);
295void cvec_free_void(void* vec);
296
297#endif
298
299
300#ifdef __cplusplus
301}
302#endif
303
304
305#define CVEC_NEW_DECLS(TYPE) \
306 typedef struct cvector_##TYPE { \
307 TYPE* a; \
308 cvec_sz size; \
309 cvec_sz capacity; \
310 } cvector_##TYPE; \
311 \
312 extern cvec_sz CVEC_##TYPE##_SZ; \
313 \
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); \
316 \
317 cvector_##TYPE* cvec_##TYPE##_heap(cvec_sz size, cvec_sz capacity); \
318 cvector_##TYPE* cvec_init_##TYPE##_heap(TYPE* vals, cvec_sz num); \
319 \
320 int cvec_copyc_##TYPE(void* dest, void* src); \
321 int cvec_copy_##TYPE(cvector_##TYPE* dest, cvector_##TYPE* src); \
322 \
323 int cvec_push_##TYPE(cvector_##TYPE* vec, TYPE a); \
324 TYPE cvec_pop_##TYPE(cvector_##TYPE* vec); \
325 \
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); \
335 \
336 TYPE* cvec_back_##TYPE(cvector_##TYPE* vec); \
337 \
338 void cvec_clear_##TYPE(cvector_##TYPE* vec); \
339 void cvec_free_##TYPE##_heap(void* vec); \
340 void cvec_free_##TYPE(void* vec);
341
342#define CVEC_NEW_DEFS(TYPE, RESIZE_MACRO) \
343 cvec_sz CVEC_##TYPE##_SZ = 50; \
344 \
345 cvector_##TYPE* cvec_##TYPE##_heap(cvec_sz size, cvec_sz capacity) \
346 { \
347 cvector_##TYPE* vec; \
348 if (!(vec = (cvector_##TYPE*)CVEC_MALLOC(sizeof(cvector_##TYPE)))) { \
349 CVEC_ASSERT(vec != NULL); \
350 return NULL; \
351 } \
352 \
353 vec->size = size; \
354 vec->capacity = (capacity > vec->size || (vec->size && capacity == vec->size)) \
355 ? capacity \
356 : vec->size + CVEC_##TYPE##_SZ; \
357 \
358 if (!(vec->a = (TYPE*)CVEC_MALLOC(vec->capacity * sizeof(TYPE)))) { \
359 CVEC_ASSERT(vec->a != NULL); \
360 CVEC_FREE(vec); \
361 return NULL; \
362 } \
363 \
364 return vec; \
365 } \
366 \
367 cvector_##TYPE* cvec_init_##TYPE##_heap(TYPE* vals, cvec_sz num) \
368 { \
369 cvector_##TYPE* vec; \
370 \
371 if (!(vec = (cvector_##TYPE*)CVEC_MALLOC(sizeof(cvector_##TYPE)))) { \
372 CVEC_ASSERT(vec != NULL); \
373 return NULL; \
374 } \
375 \
376 vec->capacity = num + CVEC_##TYPE##_SZ; \
377 vec->size = num; \
378 if (!(vec->a = (TYPE*)CVEC_MALLOC(vec->capacity * sizeof(TYPE)))) { \
379 CVEC_ASSERT(vec->a != NULL); \
380 CVEC_FREE(vec); \
381 return NULL; \
382 } \
383 \
384 CVEC_MEMMOVE(vec->a, vals, sizeof(TYPE) * num); \
385 \
386 return vec; \
387 } \
388 \
389 int cvec_##TYPE(cvector_##TYPE* vec, cvec_sz size, cvec_sz capacity) \
390 { \
391 vec->size = size; \
392 vec->capacity = (capacity > vec->size || (vec->size && capacity == vec->size)) \
393 ? capacity \
394 : vec->size + CVEC_##TYPE##_SZ; \
395 \
396 if (!(vec->a = (TYPE*)CVEC_MALLOC(vec->capacity * sizeof(TYPE)))) { \
397 CVEC_ASSERT(vec->a != NULL); \
398 vec->size = vec->capacity = 0; \
399 return 0; \
400 } \
401 \
402 return 1; \
403 } \
404 \
405 int cvec_init_##TYPE(cvector_##TYPE* vec, TYPE* vals, cvec_sz num) \
406 { \
407 vec->capacity = num + CVEC_##TYPE##_SZ; \
408 vec->size = num; \
409 if (!(vec->a = (TYPE*)CVEC_MALLOC(vec->capacity * sizeof(TYPE)))) { \
410 CVEC_ASSERT(vec->a != NULL); \
411 vec->size = vec->capacity = 0; \
412 return 0; \
413 } \
414 \
415 CVEC_MEMMOVE(vec->a, vals, sizeof(TYPE) * num); \
416 \
417 return 1; \
418 } \
419 \
420 int cvec_copyc_##TYPE(void* dest, void* src) \
421 { \
422 cvector_##TYPE* vec1 = (cvector_##TYPE*)dest; \
423 cvector_##TYPE* vec2 = (cvector_##TYPE*)src; \
424 \
425 vec1->a = NULL; \
426 vec1->size = 0; \
427 vec1->capacity = 0; \
428 \
429 return cvec_copy_##TYPE(vec1, vec2); \
430 } \
431 \
432 int cvec_copy_##TYPE(cvector_##TYPE* dest, cvector_##TYPE* src) \
433 { \
434 TYPE* tmp = NULL; \
435 if (!(tmp = (TYPE*)CVEC_REALLOC(dest->a, src->capacity*sizeof(TYPE)))) { \
436 CVEC_ASSERT(tmp != NULL); \
437 return 0; \
438 } \
439 dest->a = tmp; \
440 \
441 CVEC_MEMMOVE(dest->a, src->a, src->size*sizeof(TYPE)); \
442 dest->size = src->size; \
443 dest->capacity = src->capacity; \
444 return 1; \
445 } \
446 \
447 int cvec_push_##TYPE(cvector_##TYPE* vec, TYPE a) \
448 { \
449 TYPE* tmp; \
450 cvec_sz tmp_sz; \
451 if (vec->capacity > vec->size) { \
452 vec->a[vec->size++] = a; \
453 } else { \
454 tmp_sz = RESIZE_MACRO(vec->capacity); \
455 if (!(tmp = (TYPE*)CVEC_REALLOC(vec->a, sizeof(TYPE) * tmp_sz))) { \
456 CVEC_ASSERT(tmp != NULL); \
457 return 0; \
458 } \
459 vec->a = tmp; \
460 vec->a[vec->size++] = a; \
461 vec->capacity = tmp_sz; \
462 } \
463 return 1; \
464 } \
465 \
466 TYPE cvec_pop_##TYPE(cvector_##TYPE* vec) { return vec->a[--vec->size]; } \
467 \
468 TYPE* cvec_back_##TYPE(cvector_##TYPE* vec) { return &vec->a[vec->size - 1]; } \
469 \
470 int cvec_extend_##TYPE(cvector_##TYPE* vec, cvec_sz num) \
471 { \
472 TYPE* tmp; \
473 cvec_sz tmp_sz; \
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); \
478 return 0; \
479 } \
480 vec->a = tmp; \
481 vec->capacity = tmp_sz; \
482 } \
483 \
484 vec->size += num; \
485 return 1; \
486 } \
487 \
488 int cvec_insert_##TYPE(cvector_##TYPE* vec, cvec_sz i, TYPE a) \
489 { \
490 TYPE* tmp; \
491 cvec_sz tmp_sz; \
492 if (vec->capacity > vec->size) { \
493 CVEC_MEMMOVE(&vec->a[i + 1], &vec->a[i], (vec->size - i) * sizeof(TYPE)); \
494 vec->a[i] = a; \
495 } else { \
496 tmp_sz = RESIZE_MACRO(vec->capacity); \
497 if (!(tmp = (TYPE*)CVEC_REALLOC(vec->a, sizeof(TYPE) * tmp_sz))) { \
498 CVEC_ASSERT(tmp != NULL); \
499 return 0; \
500 } \
501 vec->a = tmp; \
502 CVEC_MEMMOVE(&vec->a[i + 1], &vec->a[i], (vec->size - i) * sizeof(TYPE)); \
503 vec->a[i] = a; \
504 vec->capacity = tmp_sz; \
505 } \
506 \
507 vec->size++; \
508 return 1; \
509 } \
510 \
511 int cvec_insert_array_##TYPE(cvector_##TYPE* vec, cvec_sz i, TYPE* a, cvec_sz num) \
512 { \
513 TYPE* tmp; \
514 cvec_sz tmp_sz; \
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); \
519 return 0; \
520 } \
521 vec->a = tmp; \
522 vec->capacity = tmp_sz; \
523 } \
524 \
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)); \
527 vec->size += num; \
528 return 1; \
529 } \
530 \
531 TYPE cvec_replace_##TYPE(cvector_##TYPE* vec, cvec_sz i, TYPE a) \
532 { \
533 TYPE tmp = vec->a[i]; \
534 vec->a[i] = a; \
535 return tmp; \
536 } \
537 \
538 void cvec_erase_##TYPE(cvector_##TYPE* vec, cvec_sz start, cvec_sz end) \
539 { \
540 cvec_sz d = end - start + 1; \
541 CVEC_MEMMOVE(&vec->a[start], &vec->a[end + 1], (vec->size - 1 - end) * sizeof(TYPE)); \
542 vec->size -= d; \
543 } \
544 \
545 int cvec_reserve_##TYPE(cvector_##TYPE* vec, cvec_sz size) \
546 { \
547 TYPE* tmp; \
548 if (vec->capacity < size) { \
549 if (!(tmp = (TYPE*)CVEC_REALLOC(vec->a, sizeof(TYPE) * (size + CVEC_##TYPE##_SZ)))) { \
550 CVEC_ASSERT(tmp != NULL); \
551 return 0; \
552 } \
553 vec->a = tmp; \
554 vec->capacity = size + CVEC_##TYPE##_SZ; \
555 } \
556 return 1; \
557 } \
558 \
559 int cvec_set_cap_##TYPE(cvector_##TYPE* vec, cvec_sz size) \
560 { \
561 TYPE* tmp; \
562 if (size < vec->size) { \
563 vec->size = size; \
564 } \
565 \
566 if (!(tmp = (TYPE*)CVEC_REALLOC(vec->a, sizeof(TYPE) * size))) { \
567 CVEC_ASSERT(tmp != NULL); \
568 return 0; \
569 } \
570 vec->a = tmp; \
571 vec->capacity = size; \
572 return 1; \
573 } \
574 \
575 void cvec_set_val_sz_##TYPE(cvector_##TYPE* vec, TYPE val) \
576 { \
577 cvec_sz i; \
578 for (i = 0; i < vec->size; i++) { \
579 vec->a[i] = val; \
580 } \
581 } \
582 \
583 void cvec_set_val_cap_##TYPE(cvector_##TYPE* vec, TYPE val) \
584 { \
585 cvec_sz i; \
586 for (i = 0; i < vec->capacity; i++) { \
587 vec->a[i] = val; \
588 } \
589 } \
590 \
591 void cvec_clear_##TYPE(cvector_##TYPE* vec) { vec->size = 0; } \
592 \
593 void cvec_free_##TYPE##_heap(void* vec) \
594 { \
595 cvector_##TYPE* tmp = (cvector_##TYPE*)vec; \
596 if (!tmp) return; \
597 CVEC_FREE(tmp->a); \
598 CVEC_FREE(tmp); \
599 } \
600 \
601 void cvec_free_##TYPE(void* vec) \
602 { \
603 cvector_##TYPE* tmp = (cvector_##TYPE*)vec; \
604 CVEC_FREE(tmp->a); \
605 tmp->a = NULL; \
606 tmp->size = 0; \
607 tmp->capacity = 0; \
608 }
609
610#define CVEC_NEW_DECLS2(TYPE) \
611 typedef struct cvector_##TYPE { \
612 TYPE* a; \
613 cvec_sz size; \
614 cvec_sz capacity; \
615 void (*elem_free)(void*); \
616 int (*elem_init)(void*, void*); \
617 } cvector_##TYPE; \
618 \
619 extern cvec_sz CVEC_##TYPE##_SZ; \
620 \
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*)); \
625 \
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*)); \
630 \
631 int cvec_copyc_##TYPE(void* dest, void* src); \
632 int cvec_copy_##TYPE(cvector_##TYPE* dest, cvector_##TYPE* src); \
633 \
634 int cvec_push_##TYPE(cvector_##TYPE* vec, TYPE* val); \
635 void cvec_pop_##TYPE(cvector_##TYPE* vec, TYPE* ret); \
636 \
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); \
642 \
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); \
653 \
654 TYPE* cvec_back_##TYPE(cvector_##TYPE* vec); \
655 \
656 void cvec_clear_##TYPE(cvector_##TYPE* vec); \
657 void cvec_free_##TYPE##_heap(void* vec); \
658 void cvec_free_##TYPE(void* vec);
659
660#define CVEC_NEW_DEFS2(TYPE, RESIZE_MACRO) \
661 cvec_sz CVEC_##TYPE##_SZ = 20; \
662 \
663 cvector_##TYPE* cvec_##TYPE##_heap(cvec_sz size, cvec_sz capacity, void (*elem_free)(void*), \
664 int (*elem_init)(void*, void*)) \
665 { \
666 cvector_##TYPE* vec; \
667 if (!(vec = (cvector_##TYPE*)CVEC_MALLOC(sizeof(cvector_##TYPE)))) { \
668 CVEC_ASSERT(vec != NULL); \
669 return NULL; \
670 } \
671 \
672 vec->size = size; \
673 vec->capacity = (capacity > vec->size || (vec->size && capacity == vec->size)) \
674 ? capacity \
675 : vec->size + CVEC_##TYPE##_SZ; \
676 \
677 if (!(vec->a = (TYPE*)CVEC_MALLOC(vec->capacity * sizeof(TYPE)))) { \
678 CVEC_ASSERT(vec->a != NULL); \
679 CVEC_FREE(vec); \
680 return NULL; \
681 } \
682 \
683 vec->elem_free = elem_free; \
684 vec->elem_init = elem_init; \
685 \
686 return vec; \
687 } \
688 \
689 cvector_##TYPE* cvec_init_##TYPE##_heap(TYPE* vals, cvec_sz num, void (*elem_free)(void*), \
690 int (*elem_init)(void*, void*)) \
691 { \
692 cvector_##TYPE* vec; \
693 cvec_sz i; \
694 \
695 if (!(vec = (cvector_##TYPE*)CVEC_MALLOC(sizeof(cvector_##TYPE)))) { \
696 CVEC_ASSERT(vec != NULL); \
697 return NULL; \
698 } \
699 \
700 vec->capacity = num + CVEC_##TYPE##_SZ; \
701 vec->size = num; \
702 if (!(vec->a = (TYPE*)CVEC_MALLOC(vec->capacity * sizeof(TYPE)))) { \
703 CVEC_ASSERT(vec->a != NULL); \
704 CVEC_FREE(vec); \
705 return NULL; \
706 } \
707 \
708 if (elem_init) { \
709 for (i = 0; i < num; ++i) { \
710 if (!elem_init(&vec->a[i], &vals[i])) { \
711 CVEC_ASSERT(0); \
712 CVEC_FREE(vec->a); \
713 CVEC_FREE(vec); \
714 return NULL; \
715 } \
716 } \
717 } else { \
718 CVEC_MEMMOVE(vec->a, vals, sizeof(TYPE) * num); \
719 } \
720 \
721 vec->elem_free = elem_free; \
722 vec->elem_init = elem_init; \
723 \
724 return vec; \
725 } \
726 \
727 int cvec_##TYPE(cvector_##TYPE* vec, cvec_sz size, cvec_sz capacity, void (*elem_free)(void*), \
728 int (*elem_init)(void*, void*)) \
729 { \
730 vec->size = size; \
731 vec->capacity = (capacity > vec->size || (vec->size && capacity == vec->size)) \
732 ? capacity \
733 : vec->size + CVEC_##TYPE##_SZ; \
734 \
735 if (!(vec->a = (TYPE*)CVEC_MALLOC(vec->capacity * sizeof(TYPE)))) { \
736 CVEC_ASSERT(vec->a != NULL); \
737 vec->size = vec->capacity = 0; \
738 return 0; \
739 } \
740 \
741 vec->elem_free = elem_free; \
742 vec->elem_init = elem_init; \
743 \
744 return 1; \
745 } \
746 \
747 int cvec_init_##TYPE(cvector_##TYPE* vec, TYPE* vals, cvec_sz num, void (*elem_free)(void*), \
748 int (*elem_init)(void*, void*)) \
749 { \
750 cvec_sz i; \
751 \
752 vec->capacity = num + CVEC_##TYPE##_SZ; \
753 vec->size = num; \
754 if (!(vec->a = (TYPE*)CVEC_MALLOC(vec->capacity * sizeof(TYPE)))) { \
755 CVEC_ASSERT(vec->a != NULL); \
756 vec->size = vec->capacity = 0; \
757 return 0; \
758 } \
759 \
760 if (elem_init) { \
761 for (i = 0; i < num; ++i) { \
762 if (!elem_init(&vec->a[i], &vals[i])) { \
763 CVEC_ASSERT(0); \
764 return 0; \
765 } \
766 } \
767 } else { \
768 CVEC_MEMMOVE(vec->a, vals, sizeof(TYPE) * num); \
769 } \
770 \
771 vec->elem_free = elem_free; \
772 vec->elem_init = elem_init; \
773 \
774 return 1; \
775 } \
776 \
777 int cvec_copyc_##TYPE(void* dest, void* src) \
778 { \
779 cvector_##TYPE* vec1 = (cvector_##TYPE*)dest; \
780 cvector_##TYPE* vec2 = (cvector_##TYPE*)src; \
781 \
782 vec1->a = NULL; \
783 vec1->size = 0; \
784 vec1->capacity = 0; \
785 \
786 return cvec_copy_##TYPE(vec1, vec2); \
787 } \
788 \
789 int cvec_copy_##TYPE(cvector_##TYPE* dest, cvector_##TYPE* src) \
790 { \
791 int i; \
792 TYPE* tmp = NULL; \
793 if (!(tmp = (TYPE*)CVEC_REALLOC(dest->a, src->capacity*sizeof(TYPE)))) { \
794 CVEC_ASSERT(tmp != NULL); \
795 return 0; \
796 } \
797 dest->a = tmp; \
798 \
799 if (src->elem_init) { \
800 for (i=0; i<src->size; ++i) { \
801 if (!src->elem_init(&dest->a[i], &src->a[i])) { \
802 CVEC_ASSERT(0); \
803 return 0; \
804 } \
805 } \
806 } else { \
807 CVEC_MEMMOVE(dest->a, src->a, src->size*sizeof(TYPE)); \
808 } \
809 \
810 dest->size = src->size; \
811 dest->capacity = src->capacity; \
812 dest->elem_free = src->elem_free; \
813 dest->elem_init = src->elem_init; \
814 return 1; \
815 } \
816 \
817 int cvec_push_##TYPE(cvector_##TYPE* vec, TYPE* a) \
818 { \
819 TYPE* tmp; \
820 cvec_sz tmp_sz; \
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); \
825 return 0; \
826 } \
827 vec->a = tmp; \
828 vec->capacity = tmp_sz; \
829 } \
830 if (vec->elem_init) { \
831 if (!vec->elem_init(&vec->a[vec->size], a)) { \
832 CVEC_ASSERT(0); \
833 return 0; \
834 } \
835 } else { \
836 CVEC_MEMMOVE(&vec->a[vec->size], a, sizeof(TYPE)); \
837 } \
838 \
839 vec->size++; \
840 return 1; \
841 } \
842 \
843 int cvec_pushm_##TYPE(cvector_##TYPE* vec, TYPE* a) \
844 { \
845 TYPE* tmp; \
846 cvec_sz tmp_sz; \
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); \
851 return 0; \
852 } \
853 vec->a = tmp; \
854 vec->capacity = tmp_sz; \
855 } \
856 CVEC_MEMMOVE(&vec->a[vec->size], a, sizeof(TYPE)); \
857 \
858 vec->size++; \
859 return 1; \
860 } \
861 \
862 void cvec_pop_##TYPE(cvector_##TYPE* vec, TYPE* ret) \
863 { \
864 if (ret) { \
865 CVEC_MEMMOVE(ret, &vec->a[--vec->size], sizeof(TYPE)); \
866 } else { \
867 vec->size--; \
868 } \
869 \
870 if (vec->elem_free) { \
871 vec->elem_free(&vec->a[vec->size]); \
872 } \
873 } \
874 \
875 void cvec_popm_##TYPE(cvector_##TYPE* vec, TYPE* ret) \
876 { \
877 vec->size--; \
878 if (ret) { \
879 CVEC_MEMMOVE(ret, &vec->a[vec->size], sizeof(TYPE)); \
880 } \
881 } \
882 \
883 TYPE* cvec_back_##TYPE(cvector_##TYPE* vec) { return &vec->a[vec->size - 1]; } \
884 \
885 int cvec_extend_##TYPE(cvector_##TYPE* vec, cvec_sz num) \
886 { \
887 TYPE* tmp; \
888 cvec_sz tmp_sz; \
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); \
893 return 0; \
894 } \
895 vec->a = tmp; \
896 vec->capacity = tmp_sz; \
897 } \
898 \
899 vec->size += num; \
900 return 1; \
901 } \
902 \
903 int cvec_insert_##TYPE(cvector_##TYPE* vec, cvec_sz i, TYPE* a) \
904 { \
905 TYPE* tmp; \
906 cvec_sz tmp_sz; \
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); \
911 return 0; \
912 } \
913 \
914 vec->a = tmp; \
915 vec->capacity = tmp_sz; \
916 } \
917 CVEC_MEMMOVE(&vec->a[i + 1], &vec->a[i], (vec->size - i) * sizeof(TYPE)); \
918 \
919 if (vec->elem_init) { \
920 if (!vec->elem_init(&vec->a[i], a)) { \
921 CVEC_ASSERT(0); \
922 return 0; \
923 } \
924 } else { \
925 CVEC_MEMMOVE(&vec->a[i], a, sizeof(TYPE)); \
926 } \
927 \
928 vec->size++; \
929 return 1; \
930 } \
931 \
932 int cvec_insertm_##TYPE(cvector_##TYPE* vec, cvec_sz i, TYPE* a) \
933 { \
934 TYPE* tmp; \
935 cvec_sz tmp_sz; \
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); \
940 return 0; \
941 } \
942 \
943 vec->a = tmp; \
944 vec->capacity = tmp_sz; \
945 } \
946 CVEC_MEMMOVE(&vec->a[i + 1], &vec->a[i], (vec->size - i) * sizeof(TYPE)); \
947 \
948 CVEC_MEMMOVE(&vec->a[i], a, sizeof(TYPE)); \
949 \
950 vec->size++; \
951 return 1; \
952 } \
953 \
954 int cvec_insert_array_##TYPE(cvector_##TYPE* vec, cvec_sz i, TYPE* a, cvec_sz num) \
955 { \
956 TYPE* tmp; \
957 cvec_sz tmp_sz, j; \
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); \
962 return 0; \
963 } \
964 vec->a = tmp; \
965 vec->capacity = tmp_sz; \
966 } \
967 \
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])) { \
972 CVEC_ASSERT(0); \
973 return 0; \
974 } \
975 } \
976 } else { \
977 CVEC_MEMMOVE(&vec->a[i], a, num * sizeof(TYPE)); \
978 } \
979 vec->size += num; \
980 return 1; \
981 } \
982 \
983 int cvec_insert_arraym_##TYPE(cvector_##TYPE* vec, cvec_sz i, TYPE* a, cvec_sz num) \
984 { \
985 TYPE* tmp; \
986 cvec_sz tmp_sz; \
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); \
991 return 0; \
992 } \
993 vec->a = tmp; \
994 vec->capacity = tmp_sz; \
995 } \
996 \
997 CVEC_MEMMOVE(&vec->a[i + num], &vec->a[i], (vec->size - i) * sizeof(TYPE)); \
998 \
999 CVEC_MEMMOVE(&vec->a[i], a, num * sizeof(TYPE)); \
1000 vec->size += num; \
1001 return 1; \
1002 } \
1003 \
1004 int cvec_replace_##TYPE(cvector_##TYPE* vec, cvec_sz i, TYPE* a, TYPE* ret) \
1005 { \
1006 if (ret) { \
1007 CVEC_MEMMOVE(ret, &vec->a[i], sizeof(TYPE)); \
1008 } else if (vec->elem_free) { \
1009 vec->elem_free(&vec->a[i]); \
1010 } \
1011 \
1012 if (vec->elem_init) { \
1013 if (!vec->elem_init(&vec->a[i], a)) { \
1014 CVEC_ASSERT(0); \
1015 return 0; \
1016 } \
1017 } else { \
1018 CVEC_MEMMOVE(&vec->a[i], a, sizeof(TYPE)); \
1019 } \
1020 return 1; \
1021 } \
1022 \
1023 void cvec_replacem_##TYPE(cvector_##TYPE* vec, cvec_sz i, TYPE* a, TYPE* ret) \
1024 { \
1025 if (ret) { \
1026 CVEC_MEMMOVE(ret, &vec->a[i], sizeof(TYPE)); \
1027 } \
1028 \
1029 CVEC_MEMMOVE(&vec->a[i], a, sizeof(TYPE)); \
1030 } \
1031 \
1032 void cvec_erase_##TYPE(cvector_##TYPE* vec, cvec_sz start, cvec_sz end) \
1033 { \
1034 cvec_sz i; \
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]); \
1039 } \
1040 } \
1041 CVEC_MEMMOVE(&vec->a[start], &vec->a[end + 1], (vec->size - 1 - end) * sizeof(TYPE)); \
1042 vec->size -= d; \
1043 } \
1044 \
1045 void cvec_remove_##TYPE(cvector_##TYPE* vec, cvec_sz start, cvec_sz end) \
1046 { \
1047 cvec_sz d = end - start + 1; \
1048 CVEC_MEMMOVE(&vec->a[start], &vec->a[end + 1], (vec->size - 1 - end) * sizeof(TYPE)); \
1049 vec->size -= d; \
1050 } \
1051 \
1052 int cvec_reserve_##TYPE(cvector_##TYPE* vec, cvec_sz size) \
1053 { \
1054 TYPE* tmp; \
1055 if (vec->capacity < size) { \
1056 if (!(tmp = (TYPE*)CVEC_REALLOC(vec->a, sizeof(TYPE) * (size + CVEC_##TYPE##_SZ)))) { \
1057 CVEC_ASSERT(tmp != NULL); \
1058 return 0; \
1059 } \
1060 vec->a = tmp; \
1061 vec->capacity = size + CVEC_##TYPE##_SZ; \
1062 } \
1063 return 1; \
1064 } \
1065 \
1066 int cvec_set_cap_##TYPE(cvector_##TYPE* vec, cvec_sz size) \
1067 { \
1068 cvec_sz i; \
1069 TYPE* tmp; \
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]); \
1074 } \
1075 } \
1076 vec->size = size; \
1077 } \
1078 \
1079 vec->capacity = size; \
1080 \
1081 if (!(tmp = (TYPE*)CVEC_REALLOC(vec->a, sizeof(TYPE) * size))) { \
1082 CVEC_ASSERT(tmp != NULL); \
1083 return 0; \
1084 } \
1085 vec->a = tmp; \
1086 return 1; \
1087 } \
1088 \
1089 int cvec_set_val_sz_##TYPE(cvector_##TYPE* vec, TYPE* val) \
1090 { \
1091 cvec_sz i; \
1092 \
1093 if (vec->elem_free) { \
1094 for (i = 0; i < vec->size; i++) { \
1095 vec->elem_free(&vec->a[i]); \
1096 } \
1097 } \
1098 \
1099 if (vec->elem_init) { \
1100 for (i = 0; i < vec->size; i++) { \
1101 if (!vec->elem_init(&vec->a[i], val)) { \
1102 CVEC_ASSERT(0); \
1103 return 0; \
1104 } \
1105 } \
1106 } else { \
1107 for (i = 0; i < vec->size; i++) { \
1108 CVEC_MEMMOVE(&vec->a[i], val, sizeof(TYPE)); \
1109 } \
1110 } \
1111 return 1; \
1112 } \
1113 \
1114 int cvec_set_val_cap_##TYPE(cvector_##TYPE* vec, TYPE* val) \
1115 { \
1116 cvec_sz i; \
1117 if (vec->elem_free) { \
1118 for (i = 0; i < vec->size; i++) { \
1119 vec->elem_free(&vec->a[i]); \
1120 } \
1121 vec->size = vec->capacity; \
1122 } \
1123 \
1124 if (vec->elem_init) { \
1125 for (i = 0; i < vec->capacity; i++) { \
1126 if (!vec->elem_init(&vec->a[i], val)) { \
1127 CVEC_ASSERT(0); \
1128 return 0; \
1129 } \
1130 } \
1131 } else { \
1132 for (i = 0; i < vec->capacity; i++) { \
1133 CVEC_MEMMOVE(&vec->a[i], val, sizeof(TYPE)); \
1134 } \
1135 } \
1136 return 1; \
1137 } \
1138 \
1139 void cvec_clear_##TYPE(cvector_##TYPE* vec) \
1140 { \
1141 cvec_sz i; \
1142 if (vec->elem_free) { \
1143 for (i = 0; i < vec->size; ++i) { \
1144 vec->elem_free(&vec->a[i]); \
1145 } \
1146 } \
1147 vec->size = 0; \
1148 } \
1149 \
1150 void cvec_free_##TYPE##_heap(void* vec) \
1151 { \
1152 cvec_sz i; \
1153 cvector_##TYPE* tmp = (cvector_##TYPE*)vec; \
1154 if (!tmp) return; \
1155 if (tmp->elem_free) { \
1156 for (i = 0; i < tmp->size; i++) { \
1157 tmp->elem_free(&tmp->a[i]); \
1158 } \
1159 } \
1160 CVEC_FREE(tmp->a); \
1161 CVEC_FREE(tmp); \
1162 } \
1163 \
1164 void cvec_free_##TYPE(void* vec) \
1165 { \
1166 cvec_sz i; \
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]); \
1171 } \
1172 } \
1173 \
1174 CVEC_FREE(tmp->a); \
1175 tmp->a = NULL; \
1176 tmp->size = 0; \
1177 tmp->capacity = 0; \
1178 }
1179
1180
1181
1182/* header ends */
1183#endif
1184
1185
1186#ifdef CVECTOR_IMPLEMENTATION
1187
1188#ifndef CVEC_NO_INT
1189
1191
1192#define CVEC_I_ALLOCATOR(x) ((x+1) * 2)
1193
1200cvector_i* cvec_i_heap(cvec_sz size, cvec_sz capacity)
1201{
1202 cvector_i* vec;
1203 if (!(vec = (cvector_i*)CVEC_MALLOC(sizeof(cvector_i)))) {
1204 CVEC_ASSERT(vec != NULL);
1205 return NULL;
1206 }
1207
1208 vec->size = size;
1209 vec->capacity = (capacity > vec->size || (vec->size && capacity == vec->size)) ? capacity : vec->size + CVEC_I_START_SZ;
1210
1211 if (!(vec->a = (int*)CVEC_MALLOC(vec->capacity*sizeof(int)))) {
1212 CVEC_ASSERT(vec->a != NULL);
1213 CVEC_FREE(vec);
1214 return NULL;
1215 }
1216
1217 return vec;
1218}
1219
1223cvector_i* cvec_init_i_heap(int* vals, cvec_sz num)
1224{
1225 cvector_i* vec;
1226
1227 if (!(vec = (cvector_i*)CVEC_MALLOC(sizeof(cvector_i)))) {
1228 CVEC_ASSERT(vec != NULL);
1229 return NULL;
1230 }
1231
1232 vec->capacity = num + CVEC_I_START_SZ;
1233 vec->size = num;
1234 if (!(vec->a = (int*)CVEC_MALLOC(vec->capacity*sizeof(int)))) {
1235 CVEC_ASSERT(vec->a != NULL);
1236 CVEC_FREE(vec);
1237 return NULL;
1238 }
1239
1240 CVEC_MEMMOVE(vec->a, vals, sizeof(int)*num);
1241
1242 return vec;
1243}
1244
1249int cvec_i(cvector_i* vec, cvec_sz size, cvec_sz capacity)
1250{
1251 vec->size = size;
1252 vec->capacity = (capacity > vec->size || (vec->size && capacity == vec->size)) ? capacity : vec->size + CVEC_I_START_SZ;
1253
1254 if (!(vec->a = (int*)CVEC_MALLOC(vec->capacity*sizeof(int)))) {
1255 CVEC_ASSERT(vec->a != NULL);
1256 vec->size = vec->capacity = 0;
1257 return 0;
1258 }
1259
1260 return 1;
1261}
1262
1266int cvec_init_i(cvector_i* vec, int* vals, cvec_sz num)
1267{
1268 vec->capacity = num + CVEC_I_START_SZ;
1269 vec->size = num;
1270 if (!(vec->a = (int*)CVEC_MALLOC(vec->capacity*sizeof(int)))) {
1271 CVEC_ASSERT(vec->a != NULL);
1272 vec->size = vec->capacity = 0;
1273 return 0;
1274 }
1275
1276 CVEC_MEMMOVE(vec->a, vals, sizeof(int)*num);
1277
1278 return 1;
1279}
1280
1291int cvec_copyc_i(void* dest, void* src)
1292{
1293 cvector_i* vec1 = (cvector_i*)dest;
1294 cvector_i* vec2 = (cvector_i*)src;
1295
1296 vec1->a = NULL;
1297 vec1->size = 0;
1298 vec1->capacity = 0;
1299
1300 return cvec_copy_i(vec1, vec2);
1301}
1302
1312int cvec_copy_i(cvector_i* dest, cvector_i* src)
1313{
1314 int* tmp = NULL;
1315 if (!(tmp = (int*)CVEC_REALLOC(dest->a, src->capacity*sizeof(int)))) {
1316 CVEC_ASSERT(tmp != NULL);
1317 return 0;
1318 }
1319 dest->a = tmp;
1320
1321 CVEC_MEMMOVE(dest->a, src->a, src->size*sizeof(int));
1322 dest->size = src->size;
1323 dest->capacity = src->capacity;
1324 return 1;
1325}
1326
1331int cvec_push_i(cvector_i* vec, int a)
1332{
1333 int* tmp;
1334 cvec_sz tmp_sz;
1335 if (vec->capacity == vec->size) {
1336 tmp_sz = CVEC_I_ALLOCATOR(vec->capacity);
1337 if (!(tmp = (int*)CVEC_REALLOC(vec->a, sizeof(int)*tmp_sz))) {
1338 CVEC_ASSERT(tmp != NULL);
1339 return 0;
1340 }
1341 vec->a = tmp;
1342 vec->capacity = tmp_sz;
1343 }
1344
1345 vec->a[vec->size++] = a;
1346 return 1;
1347}
1348
1350int cvec_pop_i(cvector_i* vec)
1351{
1352 return vec->a[--vec->size];
1353}
1354
1356int* cvec_back_i(cvector_i* vec)
1357{
1358 return &vec->a[vec->size-1];
1359}
1360
1363int cvec_extend_i(cvector_i* vec, cvec_sz num)
1364{
1365 int* tmp;
1366 cvec_sz tmp_sz;
1367 if (vec->capacity < vec->size + num) {
1368 tmp_sz = vec->capacity + num + CVEC_I_START_SZ;
1369 if (!(tmp = (int*)CVEC_REALLOC(vec->a, sizeof(int)*tmp_sz))) {
1370 CVEC_ASSERT(tmp != NULL);
1371 return 0;
1372 }
1373 vec->a = tmp;
1374 vec->capacity = tmp_sz;
1375 }
1376
1377 vec->size += num;
1378 return 1;
1379}
1380
1385int cvec_insert_i(cvector_i* vec, cvec_sz i, int a)
1386{
1387 int* tmp;
1388 cvec_sz tmp_sz;
1389 if (vec->capacity == vec->size) {
1390 tmp_sz = CVEC_I_ALLOCATOR(vec->capacity);
1391 if (!(tmp = (int*)CVEC_REALLOC(vec->a, sizeof(int)*tmp_sz))) {
1392 CVEC_ASSERT(tmp != NULL);
1393 return 0;
1394 }
1395 vec->a = tmp;
1396 vec->capacity = tmp_sz;
1397 }
1398
1399 CVEC_MEMMOVE(&vec->a[i+1], &vec->a[i], (vec->size-i)*sizeof(int));
1400 vec->a[i] = a;
1401 vec->size++;
1402 return 1;
1403}
1404
1411int cvec_insert_array_i(cvector_i* vec, cvec_sz i, int* a, cvec_sz num)
1412{
1413 int* tmp;
1414 cvec_sz tmp_sz;
1415 if (vec->capacity < vec->size + num) {
1416 tmp_sz = vec->capacity + num + CVEC_I_START_SZ;
1417 if (!(tmp = (int*)CVEC_REALLOC(vec->a, sizeof(int)*tmp_sz))) {
1418 CVEC_ASSERT(tmp != NULL);
1419 return 0;
1420 }
1421 vec->a = tmp;
1422 vec->capacity = tmp_sz;
1423 }
1424
1425 CVEC_MEMMOVE(&vec->a[i+num], &vec->a[i], (vec->size-i)*sizeof(int));
1426 CVEC_MEMMOVE(&vec->a[i], a, num*sizeof(int));
1427 vec->size += num;
1428 return 1;
1429}
1430
1432int cvec_replace_i(cvector_i* vec, cvec_sz i, int a)
1433{
1434 int tmp = vec->a[i];
1435 vec->a[i] = a;
1436 return tmp;
1437}
1438
1444void cvec_erase_i(cvector_i* vec, cvec_sz start, cvec_sz end)
1445{
1446 cvec_sz d = end - start + 1;
1447 CVEC_MEMMOVE(&vec->a[start], &vec->a[end+1], (vec->size-1-end)*sizeof(int));
1448 vec->size -= d;
1449}
1450
1452int cvec_reserve_i(cvector_i* vec, cvec_sz size)
1453{
1454 int* tmp;
1455 if (vec->capacity < size) {
1456 if (!(tmp = (int*)CVEC_REALLOC(vec->a, sizeof(int)*(size+CVEC_I_START_SZ)))) {
1457 CVEC_ASSERT(tmp != NULL);
1458 return 0;
1459 }
1460 vec->a = tmp;
1461 vec->capacity = size + CVEC_I_START_SZ;
1462 }
1463 return 1;
1464}
1465
1470int cvec_set_cap_i(cvector_i* vec, cvec_sz size)
1471{
1472 int* tmp;
1473 if (size < vec->size) {
1474 vec->size = size;
1475 }
1476
1477 if (!(tmp = (int*)CVEC_REALLOC(vec->a, sizeof(int)*size))) {
1478 CVEC_ASSERT(tmp != NULL);
1479 return 0;
1480 }
1481 vec->a = tmp;
1482 vec->capacity = size;
1483 return 1;
1484}
1485
1487void cvec_set_val_sz_i(cvector_i* vec, int val)
1488{
1489 cvec_sz i;
1490 for (i=0; i<vec->size; i++) {
1491 vec->a[i] = val;
1492 }
1493}
1494
1496void cvec_set_val_cap_i(cvector_i* vec, int val)
1497{
1498 cvec_sz i;
1499 for (i=0; i<vec->capacity; i++) {
1500 vec->a[i] = val;
1501 }
1502}
1503
1505void cvec_clear_i(cvector_i* vec) { vec->size = 0; }
1506
1509void cvec_free_i_heap(void* vec)
1510{
1511 cvector_i* tmp = (cvector_i*)vec;
1512 if (!tmp) return;
1513 CVEC_FREE(tmp->a);
1514 CVEC_FREE(tmp);
1515}
1516
1519void cvec_free_i(void* vec)
1520{
1521 cvector_i* tmp = (cvector_i*)vec;
1522 CVEC_FREE(tmp->a);
1523 tmp->a = NULL;
1524 tmp->size = 0;
1525 tmp->capacity = 0;
1526}
1527
1528#endif
1529
1530#ifndef CVEC_NO_DOUBLE
1531
1533
1534#define CVEC_D_ALLOCATOR(x) ((x+1) * 2)
1535
1542cvector_d* cvec_d_heap(cvec_sz size, cvec_sz capacity)
1543{
1544 cvector_d* vec;
1545
1546 if (!(vec = (cvector_d*)CVEC_MALLOC(sizeof(cvector_d)))) {
1547 CVEC_ASSERT(vec != NULL);
1548 return NULL;
1549 }
1550
1551 vec->size = size;
1552 vec->capacity = (capacity > vec->size || (vec->size && capacity == vec->size)) ? capacity : vec->size + CVEC_D_START_SZ;
1553
1554 if (!(vec->a = (double*)CVEC_MALLOC(vec->capacity*sizeof(double)))) {
1555 CVEC_ASSERT(vec->a != NULL);
1556 CVEC_FREE(vec);
1557 return NULL;
1558 }
1559
1560 return vec;
1561}
1562
1566cvector_d* cvec_init_d_heap(double* vals, cvec_sz num)
1567{
1568 cvector_d* vec;
1569
1570 if (!(vec = (cvector_d*)CVEC_MALLOC(sizeof(cvector_d)))) {
1571 CVEC_ASSERT(vec != NULL);
1572 return NULL;
1573 }
1574
1575 vec->capacity = num + CVEC_D_START_SZ;
1576 vec->size = num;
1577 if (!(vec->a = (double*)CVEC_MALLOC(vec->capacity*sizeof(double)))) {
1578 CVEC_ASSERT(vec->a != NULL);
1579 CVEC_FREE(vec);
1580 return NULL;
1581 }
1582
1583 CVEC_MEMMOVE(vec->a, vals, sizeof(double)*num);
1584
1585 return vec;
1586}
1587
1592int cvec_d(cvector_d* vec, cvec_sz size, cvec_sz capacity)
1593{
1594 vec->size = size;
1595 vec->capacity = (capacity > vec->size || (vec->size && capacity == vec->size)) ? capacity : vec->size + CVEC_D_START_SZ;
1596
1597 if (!(vec->a = (double*)CVEC_MALLOC(vec->capacity*sizeof(double)))) {
1598 CVEC_ASSERT(vec->a != NULL);
1599 vec->size = vec->capacity = 0;
1600 return 0;
1601 }
1602
1603 return 1;
1604}
1605
1609int cvec_init_d(cvector_d* vec, double* vals, cvec_sz num)
1610{
1611 vec->capacity = num + CVEC_D_START_SZ;
1612 vec->size = num;
1613 if (!(vec->a = (double*)CVEC_MALLOC(vec->capacity*sizeof(double)))) {
1614 CVEC_ASSERT(vec->a != NULL);
1615 vec->size = vec->capacity = 0;
1616 return 0;
1617 }
1618
1619 CVEC_MEMMOVE(vec->a, vals, sizeof(double)*num);
1620
1621 return 1;
1622}
1623
1634int cvec_copyc_d(void* dest, void* src)
1635{
1636 cvector_d* vec1 = (cvector_d*)dest;
1637 cvector_d* vec2 = (cvector_d*)src;
1638
1639 vec1->a = NULL;
1640 vec1->size = 0;
1641 vec1->capacity = 0;
1642
1643 return cvec_copy_d(vec1, vec2);
1644}
1645
1655int cvec_copy_d(cvector_d* dest, cvector_d* src)
1656{
1657 double* tmp = NULL;
1658 if (!(tmp = (double*)CVEC_REALLOC(dest->a, src->capacity*sizeof(double)))) {
1659 CVEC_ASSERT(tmp != NULL);
1660 return 0;
1661 }
1662 dest->a = tmp;
1663
1664 CVEC_MEMMOVE(dest->a, src->a, src->size*sizeof(double));
1665 dest->size = src->size;
1666 dest->capacity = src->capacity;
1667 return 1;
1668}
1669
1670
1674int cvec_push_d(cvector_d* vec, double a)
1675{
1676 double* tmp;
1677 cvec_sz tmp_sz;
1678 if (vec->capacity == vec->size) {
1679 tmp_sz = CVEC_D_ALLOCATOR(vec->capacity);
1680 if (!(tmp = (double*)CVEC_REALLOC(vec->a, sizeof(double)*tmp_sz))) {
1681 CVEC_ASSERT(tmp != NULL);
1682 return 0;
1683 }
1684 vec->a = tmp;
1685 vec->capacity = tmp_sz;
1686 }
1687 vec->a[vec->size++] = a;
1688 return 1;
1689}
1690
1692double cvec_pop_d(cvector_d* vec)
1693{
1694 return vec->a[--vec->size];
1695}
1696
1698double* cvec_back_d(cvector_d* vec)
1699{
1700 return &vec->a[vec->size-1];
1701}
1702
1705int cvec_extend_d(cvector_d* vec, cvec_sz num)
1706{
1707 double* tmp;
1708 cvec_sz tmp_sz;
1709 if (vec->capacity < vec->size + num) {
1710 tmp_sz = vec->capacity + num + CVEC_D_START_SZ;
1711 if (!(tmp = (double*)CVEC_REALLOC(vec->a, sizeof(double)*tmp_sz))) {
1712 CVEC_ASSERT(tmp != NULL);
1713 return 0;
1714 }
1715 vec->a = tmp;
1716 vec->capacity = tmp_sz;
1717 }
1718
1719 vec->size += num;
1720 return 1;
1721}
1722
1727int cvec_insert_d(cvector_d* vec, cvec_sz i, double a)
1728{
1729 double* tmp;
1730 cvec_sz tmp_sz;
1731 if (vec->capacity == vec->size) {
1732 tmp_sz = CVEC_D_ALLOCATOR(vec->capacity);
1733 if (!(tmp = (double*)CVEC_REALLOC(vec->a, sizeof(double)*tmp_sz))) {
1734 CVEC_ASSERT(tmp != NULL);
1735 return 0;
1736 }
1737 vec->a = tmp;
1738 vec->capacity = tmp_sz;
1739 }
1740
1741 CVEC_MEMMOVE(&vec->a[i+1], &vec->a[i], (vec->size-i)*sizeof(double));
1742 vec->a[i] = a;
1743 vec->size++;
1744 return 1;
1745}
1746
1753int cvec_insert_array_d(cvector_d* vec, cvec_sz i, double* a, cvec_sz num)
1754{
1755 double* tmp;
1756 cvec_sz tmp_sz;
1757 if (vec->capacity < vec->size + num) {
1758 tmp_sz = vec->capacity + num + CVEC_D_START_SZ;
1759 if (!(tmp = (double*)CVEC_REALLOC(vec->a, sizeof(double)*tmp_sz))) {
1760 CVEC_ASSERT(tmp != NULL);
1761 return 0;
1762 }
1763 vec->a = tmp;
1764 vec->capacity = tmp_sz;
1765 }
1766
1767 CVEC_MEMMOVE(&vec->a[i+num], &vec->a[i], (vec->size-i)*sizeof(double));
1768 CVEC_MEMMOVE(&vec->a[i], a, num*sizeof(double));
1769 vec->size += num;
1770 return 1;
1771}
1772
1774double cvec_replace_d(cvector_d* vec, cvec_sz i, double a)
1775{
1776 double tmp = vec->a[i];
1777 vec->a[i] = a;
1778 return tmp;
1779}
1780
1786void cvec_erase_d(cvector_d* vec, cvec_sz start, cvec_sz end)
1787{
1788 cvec_sz d = end - start + 1;
1789 CVEC_MEMMOVE(&vec->a[start], &vec->a[end+1], (vec->size-1-end)*sizeof(double));
1790 vec->size -= d;
1791}
1792
1794int cvec_reserve_d(cvector_d* vec, cvec_sz size)
1795{
1796 double* tmp;
1797 if (vec->capacity < size) {
1798 if (!(tmp = (double*)CVEC_REALLOC(vec->a, sizeof(double)*(size+CVEC_D_START_SZ)))) {
1799 CVEC_ASSERT(tmp != NULL);
1800 return 0;
1801 }
1802 vec->a = tmp;
1803 vec->capacity = size + CVEC_D_START_SZ;
1804 }
1805 return 1;
1806}
1807
1812int cvec_set_cap_d(cvector_d* vec, cvec_sz size)
1813{
1814 double* tmp;
1815 if (size < vec->size)
1816 vec->size = size;
1817
1818 if (!(tmp = (double*)CVEC_REALLOC(vec->a, sizeof(double)*size))) {
1819 CVEC_ASSERT(tmp != NULL);
1820 return 0;
1821 }
1822 vec->a = tmp;
1823 vec->capacity = size;
1824 return 1;
1825}
1826
1828void cvec_set_val_sz_d(cvector_d* vec, double val)
1829{
1830 cvec_sz i;
1831 for(i=0; i<vec->size; i++) {
1832 vec->a[i] = val;
1833 }
1834}
1835
1837void cvec_set_val_cap_d(cvector_d* vec, double val)
1838{
1839 cvec_sz i;
1840 for(i=0; i<vec->capacity; i++) {
1841 vec->a[i] = val;
1842 }
1843}
1844
1846void cvec_clear_d(cvector_d* vec) { vec->size = 0; }
1847
1850void cvec_free_d_heap(void* vec)
1851{
1852 cvector_d* tmp = (cvector_d*)vec;
1853 if (!tmp) return;
1854 CVEC_FREE(tmp->a);
1855 CVEC_FREE(tmp);
1856}
1857
1860void cvec_free_d(void* vec)
1861{
1862 cvector_d* tmp = (cvector_d*)vec;
1863 CVEC_FREE(tmp->a);
1864 tmp->a = NULL;
1865 tmp->size = 0;
1866 tmp->capacity = 0;
1867}
1868#endif
1869
1870#ifndef CVEC_NO_STR
1871
1873
1874#define CVEC_STR_ALLOCATOR(x) ((x+1) * 2)
1875
1876#if CVEC_STRDUP == cvec_strdup
1878char* cvec_strdup(const char* str)
1879{
1880 cvec_sz len;
1881 char* temp;
1882 if (!str)
1883 return NULL;
1884
1885 len = strlen(str);
1886 temp = (char*)CVEC_MALLOC(len+1);
1887 if (!temp) {
1888 CVEC_ASSERT(temp != NULL);
1889 return NULL;
1890 }
1891 temp[len] = 0;
1892
1893 return (char*)CVEC_MEMMOVE(temp, str, len); /* CVEC_MEMMOVE returns to */
1894}
1895#endif
1896
1908{
1909 cvector_str* vec;
1910 if (!(vec = (cvector_str*)CVEC_MALLOC(sizeof(cvector_str)))) {
1911 CVEC_ASSERT(vec != NULL);
1912 return NULL;
1913 }
1914
1915 vec->size = size;
1916 vec->capacity = (capacity > vec->size || (vec->size && capacity == vec->size)) ? capacity : vec->size + CVEC_STR_START_SZ;
1917
1918 if (!(vec->a = (char**)CVEC_MALLOC(vec->capacity * sizeof(char*)))) {
1919 CVEC_ASSERT(vec->a != NULL);
1920 CVEC_FREE(vec);
1921 return NULL;
1922 }
1923 /* clearing to 0 here because if the user gave a non-zero initial size, popping/
1924 * erasing will crash unless they're NULL. Really the user should never do that.
1925 * They should use cvec_init or otherwise immediately assign to the size elements they
1926 * started with. */
1927 memset(vec->a, 0, vec->capacity*sizeof(char*));
1928
1929 return vec;
1930}
1931
1934cvector_str* cvec_init_str_heap(char** vals, cvec_sz num)
1935{
1936 cvector_str* vec;
1937 cvec_sz i;
1938
1939 if (!(vec = (cvector_str*)CVEC_MALLOC(sizeof(cvector_str)))) {
1940 CVEC_ASSERT(vec != NULL);
1941 return NULL;
1942 }
1943
1944 vec->capacity = num + CVEC_STR_START_SZ;
1945 vec->size = num;
1946 if (!(vec->a = (char**)CVEC_MALLOC(vec->capacity*sizeof(char*)))) {
1947 CVEC_ASSERT(vec->a != NULL);
1948 CVEC_FREE(vec);
1949 return NULL;
1950 }
1951
1952 for(i=0; i<num; i++) {
1953 vec->a[i] = CVEC_STRDUP(vals[i]);
1954 }
1955
1956 return vec;
1957}
1958
1963int cvec_str(cvector_str* vec, cvec_sz size, cvec_sz capacity)
1964{
1965 vec->size = size;
1966 vec->capacity = (capacity > vec->size || (vec->size && capacity == vec->size)) ? capacity : vec->size + CVEC_STR_START_SZ;
1967
1968 if (!(vec->a = (char**)CVEC_MALLOC(vec->capacity * sizeof(char*)))) {
1969 CVEC_ASSERT(vec->a != NULL);
1970 vec->size = vec->capacity = 0;
1971 return 0;
1972 }
1973 /* clearing to 0 here because if the user gave a non-zero initial size, popping/
1974 * erasing will crash unless they're NULL */
1975 memset(vec->a, 0, vec->capacity*sizeof(char*));
1976
1977 return 1;
1978}
1979
1983int cvec_init_str(cvector_str* vec, char** vals, cvec_sz num)
1984{
1985 cvec_sz i;
1986
1987 vec->capacity = num + CVEC_STR_START_SZ;
1988 vec->size = num;
1989 if (!(vec->a = (char**)CVEC_MALLOC(vec->capacity*sizeof(char*)))) {
1990 CVEC_ASSERT(vec->a != NULL);
1991 vec->size = vec->capacity = 0;
1992 return 0;
1993 }
1994
1995 for(i=0; i<num; i++) {
1996 vec->a[i] = CVEC_STRDUP(vals[i]);
1997 }
1998
1999 return 1;
2000}
2001
2012int cvec_copyc_str(void* dest, void* src)
2013{
2014 cvector_str* vec1 = (cvector_str*)dest;
2015 cvector_str* vec2 = (cvector_str*)src;
2016
2017 vec1->a = NULL;
2018 vec1->size = 0;
2019 vec1->capacity = 0;
2020
2021 return cvec_copy_str(vec1, vec2);
2022}
2023
2033int cvec_copy_str(cvector_str* dest, cvector_str* src)
2034{
2035 int i;
2036 char** tmp = NULL;
2037 if (!(tmp = (char**)CVEC_REALLOC(dest->a, src->capacity*sizeof(char*)))) {
2038 CVEC_ASSERT(tmp != NULL);
2039 return 0;
2040 }
2041 dest->a = tmp;
2042
2043 for (i=0; i<src->size; ++i) {
2044 dest->a[i] = CVEC_STRDUP(src->a[i]);
2045 }
2046 dest->size = src->size;
2047 dest->capacity = src->capacity;
2048 return 1;
2049}
2050
2055int cvec_push_str(cvector_str* vec, char* a)
2056{
2057 char** tmp;
2058 cvec_sz tmp_sz;
2059 if (vec->capacity == vec->size) {
2060 tmp_sz = CVEC_STR_ALLOCATOR(vec->capacity);
2061 if (!(tmp = (char**)CVEC_REALLOC(vec->a, sizeof(char*)*tmp_sz))) {
2062 CVEC_ASSERT(tmp != NULL);
2063 return 0;
2064 }
2065 vec->a = tmp;
2066 vec->capacity = tmp_sz;
2067 }
2068
2069 vec->a[vec->size++] = CVEC_STRDUP(a);
2070 return 1;
2071}
2072
2074int cvec_pushm_str(cvector_str* vec, char* a)
2075{
2076 char** tmp;
2077 cvec_sz tmp_sz;
2078 if (vec->capacity == vec->size) {
2079 tmp_sz = CVEC_STR_ALLOCATOR(vec->capacity);
2080 if (!(tmp = (char**)CVEC_REALLOC(vec->a, sizeof(char*)*tmp_sz))) {
2081 CVEC_ASSERT(tmp != NULL);
2082 return 0;
2083 }
2084 vec->a = tmp;
2085 vec->capacity = tmp_sz;
2086 }
2087
2088 vec->a[vec->size++] = a;
2089 return 1;
2090}
2091
2096void cvec_pop_str(cvector_str* vec, char* ret)
2097{
2098 vec->size--;
2099 if (ret)
2100 strcpy(ret, vec->a[vec->size]);
2101 CVEC_FREE(vec->a[vec->size]);
2102}
2103
2105char** cvec_back_str(cvector_str* vec)
2106{
2107 return &vec->a[vec->size-1];
2108}
2109
2113int cvec_extend_str(cvector_str* vec, cvec_sz num)
2114{
2115 char** tmp;
2116 cvec_sz tmp_sz;
2117 if (vec->capacity < vec->size + num) {
2118 tmp_sz = vec->capacity + num + CVEC_STR_START_SZ;
2119 if (!(tmp = (char**)CVEC_REALLOC(vec->a, sizeof(char*)*tmp_sz))) {
2120 CVEC_ASSERT(tmp != NULL);
2121 return 0;
2122 }
2123 vec->a = tmp;
2124 vec->capacity = tmp_sz;
2125 }
2126
2127 memset(&vec->a[vec->size], 0, num*sizeof(char*));
2128 vec->size += num;
2129 return 1;
2130}
2131
2136int cvec_insert_str(cvector_str* vec, cvec_sz i, char* a)
2137{
2138 char** tmp;
2139 cvec_sz tmp_sz;
2140 if (vec->capacity == vec->size) {
2141 tmp_sz = CVEC_STR_ALLOCATOR(vec->capacity);
2142 if (!(tmp = (char**)CVEC_REALLOC(vec->a, sizeof(char*)*tmp_sz))) {
2143 CVEC_ASSERT(tmp != NULL);
2144 return 0;
2145 }
2146 vec->a = tmp;
2147 vec->capacity = tmp_sz;
2148 }
2149
2150 CVEC_MEMMOVE(&vec->a[i+1], &vec->a[i], (vec->size-i)*sizeof(char*));
2151 vec->a[i] = CVEC_STRDUP(a);
2152 vec->size++;
2153 return 1;
2154}
2155
2159int cvec_insertm_str(cvector_str* vec, cvec_sz i, char* a)
2160{
2161 char** tmp;
2162 cvec_sz tmp_sz;
2163 if (vec->capacity == vec->size) {
2164 tmp_sz = CVEC_STR_ALLOCATOR(vec->capacity);
2165 if (!(tmp = (char**)CVEC_REALLOC(vec->a, sizeof(char*)*tmp_sz))) {
2166 CVEC_ASSERT(tmp != NULL);
2167 return 0;
2168 }
2169 vec->a = tmp;
2170 vec->capacity = tmp_sz;
2171 }
2172
2173 CVEC_MEMMOVE(&vec->a[i+1], &vec->a[i], (vec->size-i)*sizeof(char*));
2174 vec->a[i] = a;
2175 vec->size++;
2176 return 1;
2177}
2178
2184int cvec_insert_array_str(cvector_str* vec, cvec_sz i, char** a, cvec_sz num)
2185{
2186 char** tmp;
2187 cvec_sz tmp_sz, j;
2188 if (vec->capacity < vec->size + num) {
2189 tmp_sz = vec->capacity + num + CVEC_STR_START_SZ;
2190 if (!(tmp = (char**)CVEC_REALLOC(vec->a, sizeof(char*)*tmp_sz))) {
2191 CVEC_ASSERT(tmp != NULL);
2192 return 0;
2193 }
2194 vec->a = tmp;
2195 vec->capacity = tmp_sz;
2196 }
2197
2198 CVEC_MEMMOVE(&vec->a[i+num], &vec->a[i], (vec->size-i)*sizeof(char*));
2199 for (j=0; j<num; ++j) {
2200 vec->a[j+i] = CVEC_STRDUP(a[j]);
2201 }
2202
2203 vec->size += num;
2204 return 1;
2205}
2206
2210int cvec_insert_arraym_str(cvector_str* vec, cvec_sz i, char** a, cvec_sz num)
2211{
2212 char** tmp;
2213 cvec_sz tmp_sz;
2214 if (vec->capacity < vec->size + num) {
2215 tmp_sz = vec->capacity + num + CVEC_STR_START_SZ;
2216 if (!(tmp = (char**)CVEC_REALLOC(vec->a, sizeof(char*)*tmp_sz))) {
2217 CVEC_ASSERT(tmp != NULL);
2218 return 0;
2219 }
2220 vec->a = tmp;
2221 vec->capacity = tmp_sz;
2222 }
2223
2224 CVEC_MEMMOVE(&vec->a[i+num], &vec->a[i], (vec->size-i)*sizeof(char*));
2225
2226 CVEC_MEMMOVE(&vec->a[i], a, num*sizeof(char*));
2227 vec->size += num;
2228 return 1;
2229}
2230
2235void cvec_replace_str(cvector_str* vec, cvec_sz i, char* a, char* ret)
2236{
2237 if (ret)
2238 strcpy(ret, vec->a[i]);
2239 CVEC_FREE(vec->a[i]);
2240 vec->a[i] = CVEC_STRDUP(a);
2241}
2242
2248void cvec_erase_str(cvector_str* vec, cvec_sz start, cvec_sz end)
2249{
2250 cvec_sz i;
2251 cvec_sz d = end - start + 1;
2252 for (i=start; i<=end; i++) {
2253 CVEC_FREE(vec->a[i]);
2254 }
2255
2256 CVEC_MEMMOVE(&vec->a[start], &vec->a[end+1], (vec->size-1-end)*sizeof(char*));
2257 vec->size -= d;
2258}
2259
2261void cvec_remove_str(cvector_str* vec, cvec_sz start, cvec_sz end)
2262{
2263 cvec_sz d = end - start + 1;
2264 CVEC_MEMMOVE(&vec->a[start], &vec->a[end+1], (vec->size-1-end)*sizeof(char*));
2265 vec->size -= d;
2266}
2267
2269int cvec_reserve_str(cvector_str* vec, cvec_sz size)
2270{
2271 char** tmp;
2272 if (vec->capacity < size) {
2273 if (!(tmp = (char**)CVEC_REALLOC(vec->a, sizeof(char*)*(size+CVEC_STR_START_SZ)))) {
2274 CVEC_ASSERT(tmp != NULL);
2275 return 0;
2276 }
2277 vec->a = tmp;
2278 vec->capacity = size + CVEC_STR_START_SZ;
2279 }
2280 return 1;
2281}
2282
2287int cvec_set_cap_str(cvector_str* vec, cvec_sz size)
2288{
2289 cvec_sz i;
2290 char** tmp;
2291 if (size < vec->size) {
2292 for(i=vec->size-1; i>size-1; i--) {
2293 CVEC_FREE(vec->a[i]);
2294 }
2295
2296 vec->size = size;
2297 }
2298
2299 if (!(tmp = (char**)CVEC_REALLOC(vec->a, sizeof(char*)*size))) {
2300 CVEC_ASSERT(tmp != NULL);
2301 return 0;
2302 }
2303 vec->a = tmp;
2304 vec->capacity = size;
2305 return 1;
2306}
2307
2309void cvec_set_val_sz_str(cvector_str* vec, char* val)
2310{
2311 cvec_sz i;
2312 for(i=0; i<vec->size; i++) {
2313 CVEC_FREE(vec->a[i]);
2314
2315 /* not worth checking to me see commit msg aa0c5cf */
2316 vec->a[i] = CVEC_STRDUP(val);
2317 }
2318}
2319
2324void cvec_set_val_cap_str(cvector_str* vec, char* val)
2325{
2326 cvec_sz i;
2327 for (i=0; i<vec->capacity; i++) {
2328 if (i<vec->size) {
2329 CVEC_FREE(vec->a[i]);
2330 }
2331
2332 vec->a[i] = CVEC_STRDUP(val);
2333 }
2334 vec->size = vec->capacity;
2335}
2336
2338void cvec_clear_str(cvector_str* vec)
2339{
2340 int i;
2341 for (i=0; i<vec->size; i++) {
2342 CVEC_FREE(vec->a[i]);
2343 }
2344
2345 vec->size = 0;
2346}
2347
2350void cvec_free_str_heap(void* vec)
2351{
2352 cvec_sz i;
2353 cvector_str* tmp = (cvector_str*)vec;
2354 if (!tmp) return;
2355 for (i=0; i<tmp->size; i++) {
2356 CVEC_FREE(tmp->a[i]);
2357 }
2358
2359 CVEC_FREE(tmp->a);
2360 CVEC_FREE(tmp);
2361}
2362
2365void cvec_free_str(void* vec)
2366{
2367 cvec_sz i;
2368 cvector_str* tmp = (cvector_str*)vec;
2369 for (i=0; i<tmp->size; i++) {
2370 CVEC_FREE(tmp->a[i]);
2371 }
2372
2373 CVEC_FREE(tmp->a);
2374 tmp->a = NULL;
2375 tmp->size = 0;
2376 tmp->capacity = 0;
2377}
2378#endif
2379
2380#ifndef CVEC_NO_VOID
2381
2383
2384#define CVEC_VOID_ALLOCATOR(x) ((x+1) * 2)
2385
2414cvector_void* cvec_void_heap(cvec_sz size, cvec_sz capacity, cvec_sz elem_sz, void(*elem_free)(void*), int(*elem_init)(void*, void*))
2415{
2416 cvector_void* vec;
2417 if (!(vec = (cvector_void*)CVEC_MALLOC(sizeof(cvector_void)))) {
2418 CVEC_ASSERT(vec != NULL);
2419 return NULL;
2420 }
2421
2422 vec->size = size;
2423 vec->capacity = (capacity > vec->size || (vec->size && capacity == vec->size)) ? capacity : vec->size + CVEC_VOID_START_SZ;
2424
2425 vec->elem_size = elem_sz;
2426
2427 if (!(vec->a = (cvec_u8*)CVEC_MALLOC(vec->capacity*elem_sz))) {
2428 CVEC_ASSERT(vec->a != NULL);
2429 CVEC_FREE(vec);
2430 return NULL;
2431 }
2432 /* not clearing to 0 here as in cvector_str because elem_free cannot be calling CVEC_FREE directly
2433 * since it takes the address of the element not the element itself */
2434
2435 vec->elem_free = elem_free;
2436 vec->elem_init = elem_init;
2437
2438 return vec;
2439}
2440
2445cvector_void* cvec_init_void_heap(void* vals, cvec_sz num, cvec_sz elem_sz, void(*elem_free)(void*), int(*elem_init)(void*, void*))
2446{
2447 cvector_void* vec;
2448 cvec_sz i;
2449
2450 if (!(vec = (cvector_void*)CVEC_MALLOC(sizeof(cvector_void)))) {
2451 CVEC_ASSERT(vec != NULL);
2452 return NULL;
2453 }
2454
2455 vec->elem_size = elem_sz;
2456
2457 vec->capacity = num + CVEC_VOID_START_SZ;
2458 vec->size = num;
2459 if (!(vec->a = (cvec_u8*)CVEC_MALLOC(vec->capacity*elem_sz))) {
2460 CVEC_ASSERT(vec->a != NULL);
2461 CVEC_FREE(vec);
2462 return NULL;
2463 }
2464
2465 if (elem_init) {
2466 for (i=0; i<num; ++i) {
2467 if (!elem_init(&vec->a[i*elem_sz], &((cvec_u8*)vals)[i*elem_sz])) {
2468 CVEC_ASSERT(0);
2469 CVEC_FREE(vec->a);
2470 CVEC_FREE(vec);
2471 return NULL;
2472 }
2473 }
2474 } else {
2475 CVEC_MEMMOVE(vec->a, vals, elem_sz*num);
2476 }
2477
2478 vec->elem_free = elem_free;
2479 vec->elem_init = elem_init;
2480
2481 return vec;
2482}
2483
2487int cvec_void(cvector_void* vec, cvec_sz size, cvec_sz capacity, cvec_sz elem_sz, void(*elem_free)(void*), int(*elem_init)(void*, void*))
2488{
2489 vec->size = size;
2490 vec->capacity = (capacity > vec->size || (vec->size && capacity == vec->size)) ? capacity : vec->size + CVEC_VOID_START_SZ;
2491
2492 vec->elem_size = elem_sz;
2493
2494 if (!(vec->a = (cvec_u8*)CVEC_MALLOC(vec->capacity*elem_sz))) {
2495 CVEC_ASSERT(vec->a != NULL);
2496 vec->size = vec->capacity = 0;
2497 return 0;
2498 }
2499
2500 vec->elem_free = elem_free;
2501 vec->elem_init = elem_init;
2502
2503 return 1;
2504}
2505
2509int cvec_init_void(cvector_void* vec, void* vals, cvec_sz num, cvec_sz elem_sz, void(*elem_free)(void*), int(*elem_init)(void*, void*))
2510{
2511 cvec_sz i;
2512
2513 vec->elem_size = elem_sz;
2514
2515 vec->capacity = num + CVEC_VOID_START_SZ;
2516 vec->size = num;
2517 if (!(vec->a = (cvec_u8*)CVEC_MALLOC(vec->capacity*elem_sz))) {
2518 CVEC_ASSERT(vec->a != NULL);
2519 vec->size = vec->capacity = 0;
2520 return 0;
2521 }
2522
2523 if (elem_init) {
2524 for (i=0; i<num; ++i) {
2525 if (!elem_init(&vec->a[i*elem_sz], &((cvec_u8*)vals)[i*elem_sz])) {
2526 CVEC_ASSERT(0);
2527 return 0;
2528 }
2529 }
2530 } else {
2531 CVEC_MEMMOVE(vec->a, vals, elem_sz*num);
2532 }
2533
2534 vec->elem_free = elem_free;
2535 vec->elem_init = elem_init;
2536
2537 return 1;
2538}
2539
2550int cvec_copyc_void(void* dest, void* src)
2551{
2552 cvector_void* vec1 = (cvector_void*)dest;
2553 cvector_void* vec2 = (cvector_void*)src;
2554
2555 vec1->a = NULL;
2556 vec1->size = 0;
2557 vec1->capacity = 0;
2558
2559 return cvec_copy_void(vec1, vec2);
2560}
2561
2572{
2573 int i;
2574 cvec_u8* tmp = NULL;
2575 if (!(tmp = (cvec_u8*)CVEC_REALLOC(dest->a, src->capacity*src->elem_size))) {
2576 CVEC_ASSERT(tmp != NULL);
2577 return 0;
2578 }
2579 dest->a = tmp;
2580
2581 if (src->elem_init) {
2582 for (i=0; i<src->size; ++i) {
2583 if (!src->elem_init(&dest->a[i*src->elem_size], &src->a[i*src->elem_size])) {
2584 CVEC_ASSERT(0);
2585 return 0;
2586 }
2587 }
2588 } else {
2589 /* could use memcpy here since we know we just allocated dest->a */
2590 CVEC_MEMMOVE(dest->a, src->a, src->size*src->elem_size);
2591 }
2592
2593 dest->size = src->size;
2594 dest->capacity = src->capacity;
2595 dest->elem_size = src->elem_size;
2596 dest->elem_free = src->elem_free;
2597 dest->elem_init = src->elem_init;
2598 return 1;
2599}
2600
2607int cvec_push_void(cvector_void* vec, void* a)
2608{
2609 cvec_u8* tmp;
2610 cvec_sz tmp_sz;
2611 if (vec->capacity == vec->size) {
2612 tmp_sz = CVEC_VOID_ALLOCATOR(vec->capacity);
2613 if (!(tmp = (cvec_u8*)CVEC_REALLOC(vec->a, vec->elem_size*tmp_sz))) {
2614 CVEC_ASSERT(tmp != NULL);
2615 return 0;
2616 }
2617 vec->a = tmp;
2618 vec->capacity = tmp_sz;
2619 }
2620 if (vec->elem_init) {
2621 if (!vec->elem_init(&vec->a[vec->size*vec->elem_size], a)) {
2622 CVEC_ASSERT(0);
2623 return 0;
2624 }
2625 } else {
2626 CVEC_MEMMOVE(&vec->a[vec->size*vec->elem_size], a, vec->elem_size);
2627 }
2628
2629 vec->size++;
2630 return 1;
2631}
2632
2634int cvec_pushm_void(cvector_void* vec, void* a)
2635{
2636 cvec_u8* tmp;
2637 cvec_sz tmp_sz;
2638 if (vec->capacity == vec->size) {
2639 tmp_sz = CVEC_VOID_ALLOCATOR(vec->capacity);
2640 if (!(tmp = (cvec_u8*)CVEC_REALLOC(vec->a, vec->elem_size*tmp_sz))) {
2641 CVEC_ASSERT(tmp != NULL);
2642 return 0;
2643 }
2644 vec->a = tmp;
2645 vec->capacity = tmp_sz;
2646 }
2647 CVEC_MEMMOVE(&vec->a[vec->size*vec->elem_size], a, vec->elem_size);
2648
2649 vec->size++;
2650 return 1;
2651}
2652
2653
2659void cvec_pop_void(cvector_void* vec, void* ret)
2660{
2661 vec->size--;
2662 if (ret) {
2663 CVEC_MEMMOVE(ret, &vec->a[vec->size*vec->elem_size], vec->elem_size);
2664 }
2665 if (vec->elem_free) {
2666 vec->elem_free(&vec->a[vec->size*vec->elem_size]);
2667 }
2668}
2669
2671void cvec_popm_void(cvector_void* vec, void* ret)
2672{
2673 vec->size--;
2674 if (ret) {
2675 CVEC_MEMMOVE(ret, &vec->a[vec->size*vec->elem_size], vec->elem_size);
2676 }
2677}
2678
2680void* cvec_back_void(cvector_void* vec)
2681{
2682 return &vec->a[(vec->size-1)*vec->elem_size];
2683}
2684
2688{
2689 cvec_u8* tmp;
2690 cvec_sz tmp_sz;
2691 if (vec->capacity < vec->size + num) {
2692 tmp_sz = vec->capacity + num + CVEC_VOID_START_SZ;
2693 if (!(tmp = (cvec_u8*)CVEC_REALLOC(vec->a, vec->elem_size*tmp_sz))) {
2694 CVEC_ASSERT(tmp != NULL);
2695 return 0;
2696 }
2697 vec->a = tmp;
2698 vec->capacity = tmp_sz;
2699 }
2700
2701 vec->size += num;
2702 return 1;
2703}
2704
2710void* cvec_get_void(cvector_void* vec, cvec_sz i)
2711{
2712 return &vec->a[i*vec->elem_size];
2713}
2714
2719int cvec_insert_void(cvector_void* vec, cvec_sz i, void* a)
2720{
2721 cvec_u8* tmp;
2722 cvec_sz tmp_sz;
2723 if (vec->capacity == vec->size) {
2724 tmp_sz = CVEC_VOID_ALLOCATOR(vec->capacity);
2725 if (!(tmp = (cvec_u8*)CVEC_REALLOC(vec->a, vec->elem_size*tmp_sz))) {
2726 CVEC_ASSERT(tmp != NULL);
2727 return 0;
2728 }
2729
2730 vec->a = tmp;
2731 vec->capacity = tmp_sz;
2732 }
2733 CVEC_MEMMOVE(&vec->a[(i+1)*vec->elem_size], &vec->a[i*vec->elem_size], (vec->size-i)*vec->elem_size);
2734
2735 if (vec->elem_init) {
2736 if (!vec->elem_init(&vec->a[i*vec->elem_size], a)) {
2737 CVEC_ASSERT(0);
2738 return 0;
2739 }
2740 } else {
2741 CVEC_MEMMOVE(&vec->a[i*vec->elem_size], a, vec->elem_size);
2742 }
2743
2744 vec->size++;
2745 return 1;
2746}
2747
2749int cvec_insertm_void(cvector_void* vec, cvec_sz i, void* a)
2750{
2751 cvec_u8* tmp;
2752 cvec_sz tmp_sz;
2753 if (vec->capacity == vec->size) {
2754 tmp_sz = CVEC_VOID_ALLOCATOR(vec->capacity);
2755 if (!(tmp = (cvec_u8*)CVEC_REALLOC(vec->a, vec->elem_size*tmp_sz))) {
2756 CVEC_ASSERT(tmp != NULL);
2757 return 0;
2758 }
2759
2760 vec->a = tmp;
2761 vec->capacity = tmp_sz;
2762 }
2763 CVEC_MEMMOVE(&vec->a[(i+1)*vec->elem_size], &vec->a[i*vec->elem_size], (vec->size-i)*vec->elem_size);
2764
2765 CVEC_MEMMOVE(&vec->a[i*vec->elem_size], a, vec->elem_size);
2766
2767 vec->size++;
2768 return 1;
2769}
2770
2778int cvec_insert_array_void(cvector_void* vec, cvec_sz i, void* a, cvec_sz num)
2779{
2780 cvec_u8* tmp;
2781 cvec_sz tmp_sz, j;
2782 if (vec->capacity < vec->size + num) {
2783 tmp_sz = vec->capacity + num + CVEC_VOID_START_SZ;
2784 if (!(tmp = (cvec_u8*)CVEC_REALLOC(vec->a, vec->elem_size*tmp_sz))) {
2785 CVEC_ASSERT(tmp != NULL);
2786 return 0;
2787 }
2788 vec->a = tmp;
2789 vec->capacity = tmp_sz;
2790 }
2791
2792 CVEC_MEMMOVE(&vec->a[(i+num)*vec->elem_size], &vec->a[i*vec->elem_size], (vec->size-i)*vec->elem_size);
2793 if (vec->elem_init) {
2794 for (j=0; j<num; ++j) {
2795 if (!vec->elem_init(&vec->a[(j+i)*vec->elem_size], &((cvec_u8*)a)[j*vec->elem_size])) {
2796 CVEC_ASSERT(0);
2797 return 0;
2798 }
2799 }
2800 } else {
2801 CVEC_MEMMOVE(&vec->a[i*vec->elem_size], a, num*vec->elem_size);
2802 }
2803 vec->size += num;
2804 return 1;
2805}
2806
2808int cvec_insert_arraym_void(cvector_void* vec, cvec_sz i, void* a, cvec_sz num)
2809{
2810 cvec_u8* tmp;
2811 cvec_sz tmp_sz;
2812 if (vec->capacity < vec->size + num) {
2813 tmp_sz = vec->capacity + num + CVEC_VOID_START_SZ;
2814 if (!(tmp = (cvec_u8*)CVEC_REALLOC(vec->a, vec->elem_size*tmp_sz))) {
2815 CVEC_ASSERT(tmp != NULL);
2816 return 0;
2817 }
2818 vec->a = tmp;
2819 vec->capacity = tmp_sz;
2820 }
2821
2822 CVEC_MEMMOVE(&vec->a[(i+num)*vec->elem_size], &vec->a[i*vec->elem_size], (vec->size-i)*vec->elem_size);
2823
2824 CVEC_MEMMOVE(&vec->a[i*vec->elem_size], a, num*vec->elem_size);
2825 vec->size += num;
2826 return 1;
2827}
2828
2832int cvec_replace_void(cvector_void* vec, cvec_sz i, void* a, void* ret)
2833{
2834 if (ret) {
2835 CVEC_MEMMOVE(ret, &vec->a[i*vec->elem_size], vec->elem_size);
2836 } else if (vec->elem_free) {
2837 vec->elem_free(&vec->a[i*vec->elem_size]);
2838 }
2839
2840 if (vec->elem_init) {
2841 if (!vec->elem_init(&vec->a[i*vec->elem_size], a)) {
2842 CVEC_ASSERT(0);
2843 return 0;
2844 }
2845 } else {
2846 CVEC_MEMMOVE(&vec->a[i*vec->elem_size], a, vec->elem_size);
2847 }
2848 return 1;
2849}
2850
2856void cvec_replacem_void(cvector_void* vec, cvec_sz i, void* a, void* ret)
2857{
2858 if (ret) {
2859 CVEC_MEMMOVE(ret, &vec->a[i*vec->elem_size], vec->elem_size);
2860 }
2861
2862 CVEC_MEMMOVE(&vec->a[i*vec->elem_size], a, vec->elem_size);
2863}
2864
2870void cvec_erase_void(cvector_void* vec, cvec_sz start, cvec_sz end)
2871{
2872 cvec_sz i;
2873 cvec_sz d = end - start + 1;
2874 if (vec->elem_free) {
2875 for (i=start; i<=end; i++) {
2876 vec->elem_free(&vec->a[i*vec->elem_size]);
2877 }
2878 }
2879 CVEC_MEMMOVE(&vec->a[start*vec->elem_size], &vec->a[(end+1)*vec->elem_size], (vec->size-1-end)*vec->elem_size);
2880 vec->size -= d;
2881}
2882
2884void cvec_remove_void(cvector_void* vec, cvec_sz start, cvec_sz end)
2885{
2886 cvec_sz d = end - start + 1;
2887 CVEC_MEMMOVE(&vec->a[start*vec->elem_size], &vec->a[(end+1)*vec->elem_size], (vec->size-1-end)*vec->elem_size);
2888 vec->size -= d;
2889}
2890
2893{
2894 cvec_u8* tmp;
2895 if (vec->capacity < size) {
2896 if (!(tmp = (cvec_u8*)CVEC_REALLOC(vec->a, vec->elem_size*(size+CVEC_VOID_START_SZ)))) {
2897 CVEC_ASSERT(tmp != NULL);
2898 return 0;
2899 }
2900 vec->a = tmp;
2901 vec->capacity = size + CVEC_VOID_START_SZ;
2902 }
2903 return 1;
2904}
2905
2911{
2912 cvec_sz i;
2913 cvec_u8* tmp;
2914 if (size < vec->size) {
2915 if (vec->elem_free) {
2916 for (i=vec->size-1; i>=size; i--) {
2917 vec->elem_free(&vec->a[i*vec->elem_size]);
2918 }
2919 }
2920 vec->size = size;
2921 }
2922
2923 vec->capacity = size;
2924
2925 if (!(tmp = (cvec_u8*)CVEC_REALLOC(vec->a, vec->elem_size*size))) {
2926 CVEC_ASSERT(tmp != NULL);
2927 return 0;
2928 }
2929 vec-> a = tmp;
2930 return 1;
2931}
2932
2934int cvec_set_val_sz_void(cvector_void* vec, void* val)
2935{
2936 cvec_sz i;
2937
2938 if (vec->elem_free) {
2939 for(i=0; i<vec->size; i++) {
2940 vec->elem_free(&vec->a[i*vec->elem_size]);
2941 }
2942 }
2943
2944 if (vec->elem_init) {
2945 for (i=0; i<vec->size; i++) {
2946 if (!vec->elem_init(&vec->a[i*vec->elem_size], val)) {
2947 CVEC_ASSERT(0);
2948 return 0;
2949 }
2950 }
2951 } else {
2952 for (i=0; i<vec->size; i++) {
2953 CVEC_MEMMOVE(&vec->a[i*vec->elem_size], val, vec->elem_size);
2954 }
2955 }
2956 return 1;
2957}
2958
2964int cvec_set_val_cap_void(cvector_void* vec, void* val)
2965{
2966 cvec_sz i;
2967 if (vec->elem_free) {
2968 for (i=0; i<vec->size; i++) {
2969 vec->elem_free(&vec->a[i*vec->elem_size]);
2970 }
2971 vec->size = vec->capacity;
2972 }
2973
2974 if (vec->elem_init) {
2975 for (i=0; i<vec->capacity; i++) {
2976 if (!vec->elem_init(&vec->a[i*vec->elem_size], val)) {
2977 CVEC_ASSERT(0);
2978 return 0;
2979 }
2980 }
2981 } else {
2982 for (i=0; i<vec->capacity; i++) {
2983 CVEC_MEMMOVE(&vec->a[i*vec->elem_size], val, vec->elem_size);
2984 }
2985 }
2986 return 1;
2987}
2988
2992{
2993 cvec_sz i;
2994 if (vec->elem_free) {
2995 for (i=0; i<vec->size; ++i) {
2996 vec->elem_free(&vec->a[i*vec->elem_size]);
2997 }
2998 }
2999 vec->size = 0;
3000}
3001
3005void cvec_free_void_heap(void* vec)
3006{
3007 cvec_sz i;
3008 cvector_void* tmp = (cvector_void*)vec;
3009 if (!tmp) return;
3010 if (tmp->elem_free) {
3011 for (i=0; i<tmp->size; i++) {
3012 tmp->elem_free(&tmp->a[i*tmp->elem_size]);
3013 }
3014 }
3015 CVEC_FREE(tmp->a);
3016 CVEC_FREE(tmp);
3017}
3018
3021void cvec_free_void(void* vec)
3022{
3023 cvec_sz i;
3024 cvector_void* tmp = (cvector_void*)vec;
3025 if (tmp->elem_free) {
3026 for (i=0; i<tmp->size; i++) {
3027 tmp->elem_free(&tmp->a[i*tmp->elem_size]);
3028 }
3029 }
3030
3031 CVEC_FREE(tmp->a);
3032 tmp->a = NULL;
3033 tmp->size = 0;
3034 tmp->capacity = 0;
3035}
3036
3216#endif
3217
3218
3219#endif
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.
#define CVEC_FREE(p)
Definition cvector.h:68
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.
Definition cvector_d.c:251
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).
Definition cvector_d.c:225
int cvec_insert_i(cvector_i *vec, cvec_sz i, int a)
Insert a at index i (0 based).
Definition cvector_i.c:225
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.
Definition cvector_i.c:349
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.
unsigned char cvec_u8
Definition cvector.h:243
void cvec_free_i(void *vec)
Frees the internal array and zeros out the members to maintain a consistent state.
Definition cvector_i.c:359
void cvec_free_d(void *vec)
Frees the internal array and zeros out the members to maintain a consistent state.
Definition cvector_d.c:358
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)
Definition cvector.h:67
int cvec_pop_i(cvector_i *vec)
Remove and return the last element (size decreased 1).
Definition cvector_i.c:190
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.
Definition cvector_i.c:131
cvector_str * cvec_init_str_heap(char **vals, cvec_sz num)
Create (on the heap) and initialize cvector_str with num elements of vals.
Definition cvector_str.c:92
void cvec_erase_d(cvector_d *vec, cvec_sz start, cvec_sz end)
Erases elements from start to end inclusive.
Definition cvector_d.c:284
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.
Definition cvector_i.c:272
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.
Definition cvector_d.c:40
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.
Definition cvector_i.c:251
void cvec_set_val_cap_d(cvector_d *vec, double val)
Fills entire allocated array (capacity) with val.
Definition cvector_d.c:335
cvec_sz CVEC_I_START_SZ
Definition cvector_i.c:30
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.
Definition cvector_d.c:153
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.
Definition cvector_i.c:152
int cvec_set_cap_i(cvector_i *vec, cvec_sz size)
Set capacity to size.
Definition cvector_i.c:310
cvector_i * cvec_init_i_heap(int *vals, cvec_sz num)
Create (on the heap) and initialize cvector_i with num elements of vals.
Definition cvector_i.c:63
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).
Definition cvector_d.c:292
#define CVEC_MEMMOVE(dst, src, sz)
Definition cvector.h:73
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.
Definition cvector_d.c:203
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).
Definition cvector_i.c:292
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.
Definition cvector_d.c:132
int cvec_insertm_void(cvector_void *vec, cvec_sz i, void *a)
Same as insert but no elem_init even if defined.
#define CVEC_MALLOC(sz)
Definition cvector.h:66
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.
Definition cvector_d.c:272
#define CVEC_ASSERT(x)
Definition cvector.h:78
cvector_i * cvec_i_heap(cvec_sz size, cvec_sz capacity)
Creates a new cvector_i on the heap.
Definition cvector_i.c:40
int cvec_push_i(cvector_i *vec, int a)
Append a to end of vector (size increased 1).
Definition cvector_i.c:171
void cvec_erase_i(cvector_i *vec, cvec_sz start, cvec_sz end)
Erases elements from start to end inclusive.
Definition cvector_i.c:284
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.
Definition cvector_d.c:326
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...
Definition cvector_i.c:106
char * cvec_strdup(const char *str)
Useful utility function since strdup isn't in standard C.
Definition cvector_str.c:36
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.
Definition cvector_str.c:65
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 ...
Definition cvector_i.c:89
int cvec_set_cap_void(cvector_void *vec, cvec_sz size)
Set capacity to size.
CVEC_SIZE_T cvec_sz
Definition cvector.h:88
cvector_d * cvec_init_d_heap(double *vals, cvec_sz num)
Create (on the heap) and initialize cvector_d with num elements of vals.
Definition cvector_d.c:64
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 ...
Definition cvector_d.c:90
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.
Definition cvector_d.c:310
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).
Definition cvector_d.c:172
void cvec_clear_i(cvector_i *vec)
Sets size to 0 (does not clear contents).
Definition cvector_i.c:345
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).
#define CVEC_STRDUP
Definition cvector.h:198
int cvec_extend_i(cvector_i *vec, cvec_sz num)
Increase the size of the array num items.
Definition cvector_i.c:203
void cvec_set_val_cap_i(cvector_i *vec, int val)
Fills entire allocated array (capacity) with val.
Definition cvector_i.c:336
double * cvec_back_d(cvector_d *vec)
Return pointer to last element.
Definition cvector_d.c:196
#define CVEC_SIZE_T
Definition cvector.h:83
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).
Definition cvector_d.c:344
void cvec_set_val_sz_i(cvector_i *vec, int val)
Set all size elements to val.
Definition cvector_i.c:327
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.
Definition cvector_d.c:348
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...
Definition cvector_d.c:107
double cvec_pop_d(cvector_d *vec)
Remove and return the last element (size decreased 1).
Definition cvector_d.c:190
int * cvec_back_i(cvector_i *vec)
Return pointer to last element.
Definition cvector_i.c:196
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
Definition cvector_str.c:30
cvec_sz CVEC_D_START_SZ
Definition cvector_d.c:30
#define CVEC_D_ALLOCATOR(x)
Definition cvector_d.c:32
CVEC_SIZE_T cvec_sz
Definition cvector_d.h:11
#define CVEC_I_ALLOCATOR(x)
Definition cvector_i.c:32
CVEC_SIZE_T cvec_sz
Definition cvector_i.h:11
#define CVEC_STR_ALLOCATOR(x)
Definition cvector_str.c:32
CVEC_SIZE_T cvec_sz
Definition cvector_str.h:11
#define CVEC_VOID_ALLOCATOR(x)
unsigned char cvec_u8
CVEC_SIZE_T cvec_sz
Data structure for double vector.
Definition cvector.h:145
cvec_sz size
Current size (amount you use when manipulating array directly).
Definition cvector.h:147
cvec_sz capacity
Allocated size of array; always >= size.
Definition cvector.h:148
double * a
Array.
Definition cvector.h:146
Data structure for int vector.
Definition cvector.h:101
cvec_sz size
Current size (amount you use when manipulating array directly).
Definition cvector.h:103
int * a
Array.
Definition cvector.h:102
cvec_sz capacity
Allocated size of array; always >= size.
Definition cvector.h:104
Data structure for string vector.
Definition cvector.h:189
cvec_sz capacity
Allocated size of array; always >= size.
Definition cvector.h:192
cvec_sz size
Current size (amount you use when manipulating array directly).
Definition cvector.h:191
char ** a
Array.
Definition cvector.h:190
Data structure for generic type (cast to void) vectors.
Definition cvector.h:247
cvec_sz size
Current size (amount you should use when manipulating array directly).
Definition cvector.h:249
cvec_sz elem_size
Size in bytes of type stored (sizeof(T) where T is type).
Definition cvector.h:251
cvec_sz capacity
Allocated size of array; always >= size.
Definition cvector.h:250
void(* elem_free)(void *)
Definition cvector.h:252
cvec_u8 * a
Array.
Definition cvector.h:248
int(* elem_init)(void *, void *)
Definition cvector.h:253