CVector  4.1.0
A C++ style vector library in strict ANSI C (C89)
cvector.h
Go to the documentation of this file.
1 /*
2 
3 CVector 4.1.0 MIT Licensed vector (dynamic array) library in strict C89
4 http://www.robertwinkler.com/projects/cvector.html
5 http://www.robertwinkler.com/projects/cvector/
6 
7 Besides the docs and all the Doxygen comments, see cvector_tests.c for
8 examples of how to use it or look at any of these other projects for
9 more practical examples:
10 
11 https://github.com/rswinkle/C_Interpreter
12 https://github.com/rswinkle/CPIM2
13 https://github.com/rswinkle/spelling_game
14 https://github.com/rswinkle/c_bigint
15 http://portablegl.com/
16 
17 The MIT License (MIT)
18 
19 Copyright (c) 2011-2023 Robert Winkler
20 
21 Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated
22 documentation files (the "Software"), to deal in the Software without restriction, including without limitation
23 the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and
24 to permit persons to whom the Software is furnished to do so, subject to the following conditions:
25 
26 The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
27 
28 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
29 TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
30 THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
31 CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
32 IN THE SOFTWARE.
33 */
34 
35 
36 /* header starts */
37 
38 #ifndef CVECTOR_H
39 #define CVECTOR_H
40 
41 #include <stdlib.h>
42 #include <string.h>
43 #include <assert.h>
44 
45 #if defined(CVEC_ONLY_INT) || defined(CVEC_ONLY_DOUBLE) || defined(CVEC_ONLY_STR) || defined(CVEC_ONLY_VOID)
46  #ifndef CVEC_ONLY_INT
47  #define CVEC_NO_INT
48  #endif
49  #ifndef CVEC_ONLY_DOUBLE
50  #define CVEC_NO_DOUBLE
51  #endif
52  #ifndef CVEC_ONLY_STR
53  #define CVEC_NO_STR
54  #endif
55  #ifndef CVEC_ONLY_VOID
56  #define CVEC_NO_VOID
57  #endif
58 #endif
59 
60 #if defined(CVEC_MALLOC) && defined(CVEC_FREE) && defined(CVEC_REALLOC)
61 /* ok */
62 #elif !defined(CVEC_MALLOC) && !defined(CVEC_FREE) && !defined(CVEC_REALLOC)
63 /* ok */
64 #else
65 #error "Must define all or none of CVEC_MALLOC, CVEC_FREE, and CVEC_REALLOC."
66 #endif
67 
68 #ifndef CVEC_MALLOC
69 #define CVEC_MALLOC(sz) malloc(sz)
70 #define CVEC_REALLOC(p, sz) realloc(p, sz)
71 #define CVEC_FREE(p) free(p)
72 #endif
73 
74 #ifndef CVEC_MEMMOVE
75 #include <string.h>
76 #define CVEC_MEMMOVE(dst, src, sz) memmove(dst, src, sz)
77 #endif
78 
79 #ifndef CVEC_ASSERT
80 #include <assert.h>
81 #define CVEC_ASSERT(x) assert(x)
82 #endif
83 
84 #ifndef CVEC_SIZE_T
85 #define CVEC_SIZE_T size_t
86 #endif
87 
89 
90 #ifdef __cplusplus
91 extern "C" {
92 #endif
93 
94 #ifndef CVEC_NO_INT
95 
96 
97 
99 typedef struct cvector_i
100 {
101  int* a;
104 } cvector_i;
105 
106 extern cvec_sz CVEC_I_START_SZ;
107 
108 int cvec_i(cvector_i* vec, cvec_sz size, cvec_sz capacity);
109 int cvec_init_i(cvector_i* vec, int* vals, cvec_sz num);
110 
111 cvector_i* cvec_i_heap(cvec_sz size, cvec_sz capacity);
112 cvector_i* cvec_init_i_heap(int* vals, cvec_sz num);
113 int cvec_copyc_i(void* dest, void* src);
114 int cvec_copy_i(cvector_i* dest, cvector_i* src);
115 
116 int cvec_push_i(cvector_i* vec, int a);
117 int cvec_pop_i(cvector_i* vec);
118 
119 int cvec_extend_i(cvector_i* vec, cvec_sz num);
120 int cvec_insert_i(cvector_i* vec, cvec_sz i, int a);
121 int cvec_insert_array_i(cvector_i* vec, cvec_sz i, int* a, cvec_sz num);
122 int cvec_replace_i(cvector_i* vec, cvec_sz i, int a);
123 void cvec_erase_i(cvector_i* vec, cvec_sz start, cvec_sz end);
124 int cvec_reserve_i(cvector_i* vec, cvec_sz size);
125 int cvec_set_cap_i(cvector_i* vec, cvec_sz size);
126 void cvec_set_val_sz_i(cvector_i* vec, int val);
127 void cvec_set_val_cap_i(cvector_i* vec, int val);
128 
129 int* cvec_back_i(cvector_i* vec);
130 
131 void cvec_clear_i(cvector_i* vec);
132 void cvec_free_i_heap(void* vec);
133 void cvec_free_i(void* vec);
134 
135 #endif
136 
137 #ifndef CVEC_NO_DOUBLE
138 
139 
140 
142 typedef struct cvector_d
143 {
144  double* a;
147 } cvector_d;
148 
149 extern cvec_sz CVEC_D_START_SZ;
150 
151 int cvec_d(cvector_d* vec, cvec_sz size, cvec_sz capacity);
152 int cvec_init_d(cvector_d* vec, double* vals, cvec_sz num);
153 
154 cvector_d* cvec_d_heap(cvec_sz size, cvec_sz capacity);
155 cvector_d* cvec_init_d_heap(double* vals, cvec_sz num);
156 int cvec_copyc_d(void* dest, void* src);
157 int cvec_copy_d(cvector_d* dest, cvector_d* src);
158 
159 int cvec_push_d(cvector_d* vec, double a);
160 double cvec_pop_d(cvector_d* vec);
161 
162 int cvec_extend_d(cvector_d* vec, cvec_sz num);
163 int cvec_insert_d(cvector_d* vec, cvec_sz i, double a);
164 int cvec_insert_array_d(cvector_d* vec, cvec_sz i, double* a, cvec_sz num);
165 double cvec_replace_d(cvector_d* vec, cvec_sz i, double a);
166 void cvec_erase_d(cvector_d* vec, cvec_sz start, cvec_sz end);
167 int cvec_reserve_d(cvector_d* vec, cvec_sz size);
168 int cvec_set_cap_d(cvector_d* vec, cvec_sz size);
169 void cvec_set_val_sz_d(cvector_d* vec, double val);
170 void cvec_set_val_cap_d(cvector_d* vec, double val);
171 
172 double* cvec_back_d(cvector_d* vec);
173 
174 void cvec_clear_d(cvector_d* vec);
175 void cvec_free_d_heap(void* vec);
176 void cvec_free_d(void* vec);
177 
178 #endif
179 
180 #ifndef CVEC_NO_STR
181 
182 
183 
185 typedef struct cvector_str
186 {
187  char** a;
190 } cvector_str;
191 
193 
194 #ifndef CVEC_STRDUP
195 #define CVEC_STRDUP cvec_strdup
196 char* cvec_strdup(const char* str);
197 #endif
198 
199 int cvec_str(cvector_str* vec, cvec_sz size, cvec_sz capacity);
200 int cvec_init_str(cvector_str* vec, char** vals, cvec_sz num);
201 
202 cvector_str* cvec_str_heap(cvec_sz size, cvec_sz capacity);
203 cvector_str* cvec_init_str_heap(char** vals, cvec_sz num);
204 int cvec_copyc_str(void* dest, void* src);
205 int cvec_copy_str(cvector_str* dest, cvector_str* src);
206 
207 int cvec_push_str(cvector_str* vec, char* a);
208 void cvec_pop_str(cvector_str* vec, char* ret);
209 
210 int cvec_pushm_str(cvector_str* vec, char* a);
211 #define cvec_popm_str(vec) (vec).a[--(vec).size]
212 int cvec_insertm_str(cvector_str* vec, cvec_sz i, char* a);
213 int cvec_insert_arraym_str(cvector_str* vec, cvec_sz i, char** a, cvec_sz num);
214 #define cvec_replacem_str(vec, i, s, ret) ((ret) = (vec).a[i], (vec).a[i] = (s))
215 
216 int cvec_extend_str(cvector_str* vec, cvec_sz num);
217 int cvec_insert_str(cvector_str* vec, cvec_sz i, char* a);
218 int cvec_insert_array_str(cvector_str* vec, cvec_sz i, char** a, cvec_sz num);
219 void cvec_replace_str(cvector_str* vec, cvec_sz i, char* a, char* ret);
220 void cvec_erase_str(cvector_str* vec, cvec_sz start, cvec_sz end);
221 void cvec_remove_str(cvector_str* vec, cvec_sz start, cvec_sz end);
222 int cvec_reserve_str(cvector_str* vec, cvec_sz size);
223 int cvec_set_cap_str(cvector_str* vec, cvec_sz size);
224 void cvec_set_val_sz_str(cvector_str* vec, char* val);
225 void cvec_set_val_cap_str(cvector_str* vec, char* val);
226 
227 char** cvec_back_str(cvector_str* vec);
228 
229 void cvec_clear_str(cvector_str* vec);
230 void cvec_free_str_heap(void* vec);
231 void cvec_free_str(void* vec);
232 
233 #endif
234 
235 #ifndef CVEC_NO_VOID
236 
237 
238 
239 typedef unsigned char cvec_u8;
240 
242 typedef struct cvector_void
243 {
248  void (*elem_free)(void*);
249  int (*elem_init)(void*, void*);
250 } cvector_void;
251 
253 
254 #define CVEC_GET_VOID(VEC, TYPE, I) ((TYPE*)&(VEC)->a[(I)*(VEC)->elem_size])
255 
256 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*));
257 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*));
258 
259 cvector_void* cvec_void_heap(cvec_sz size, cvec_sz capacity, cvec_sz elem_sz, void (*elem_free)(void*), int(*elem_init)(void*, void*));
260 cvector_void* cvec_init_void_heap(void* vals, cvec_sz num, cvec_sz elem_sz, void (*elem_free)(void*), int(*elem_init)(void*, void*));
261 
262 int cvec_copyc_void(void* dest, void* src);
263 int cvec_copy_void(cvector_void* dest, cvector_void* src);
264 
265 int cvec_push_void(cvector_void* vec, void* a);
266 void cvec_pop_void(cvector_void* vec, void* ret);
267 void* cvec_get_void(cvector_void* vec, cvec_sz i);
268 
269 int cvec_pushm_void(cvector_void* vec, void* a);
270 void cvec_popm_void(cvector_void* vec, void* ret);
271 int cvec_insertm_void(cvector_void* vec, cvec_sz i, void* a);
272 int cvec_insert_arraym_void(cvector_void* vec, cvec_sz i, void* a, cvec_sz num);
273 void cvec_replacem_void(cvector_void* vec, cvec_sz i, void* a, void* ret);
274 
275 int cvec_extend_void(cvector_void* vec, cvec_sz num);
276 int cvec_insert_void(cvector_void* vec, cvec_sz i, void* a);
277 int cvec_insert_array_void(cvector_void* vec, cvec_sz i, void* a, cvec_sz num);
278 int cvec_replace_void(cvector_void* vec, cvec_sz i, void* a, void* ret);
279 void cvec_erase_void(cvector_void* vec, cvec_sz start, cvec_sz end);
280 void cvec_remove_void(cvector_void* vec, cvec_sz start, cvec_sz end);
281 int cvec_reserve_void(cvector_void* vec, cvec_sz size);
282 int cvec_set_cap_void(cvector_void* vec, cvec_sz size);
283 int cvec_set_val_sz_void(cvector_void* vec, void* val);
284 int cvec_set_val_cap_void(cvector_void* vec, void* val);
285 
286 void* cvec_back_void(cvector_void* vec);
287 
288 void cvec_clear_void(cvector_void* vec);
289 void cvec_free_void_heap(void* vec);
290 void cvec_free_void(void* vec);
291 
292 #endif
293 
294 
295 #ifdef __cplusplus
296 }
297 #endif
298 
299 
300 #define CVEC_NEW_DECLS(TYPE) \
301  typedef struct cvector_##TYPE { \
302  TYPE* a; \
303  cvec_sz size; \
304  cvec_sz capacity; \
305  } cvector_##TYPE; \
306  \
307  extern cvec_sz CVEC_##TYPE##_SZ; \
308  \
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); \
311  \
312  cvector_##TYPE* cvec_##TYPE##_heap(cvec_sz size, cvec_sz capacity); \
313  cvector_##TYPE* cvec_init_##TYPE##_heap(TYPE* vals, cvec_sz num); \
314  \
315  int cvec_copyc_##TYPE(void* dest, void* src); \
316  int cvec_copy_##TYPE(cvector_##TYPE* dest, cvector_##TYPE* src); \
317  \
318  int cvec_push_##TYPE(cvector_##TYPE* vec, TYPE a); \
319  TYPE cvec_pop_##TYPE(cvector_##TYPE* vec); \
320  \
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); \
330  \
331  TYPE* cvec_back_##TYPE(cvector_##TYPE* vec); \
332  \
333  void cvec_clear_##TYPE(cvector_##TYPE* vec); \
334  void cvec_free_##TYPE##_heap(void* vec); \
335  void cvec_free_##TYPE(void* vec);
336 
337 #define CVEC_NEW_DEFS(TYPE, RESIZE_MACRO) \
338  cvec_sz CVEC_##TYPE##_SZ = 50; \
339  \
340  cvector_##TYPE* cvec_##TYPE##_heap(cvec_sz size, cvec_sz capacity) \
341  { \
342  cvector_##TYPE* vec; \
343  if (!(vec = (cvector_##TYPE*)CVEC_MALLOC(sizeof(cvector_##TYPE)))) { \
344  CVEC_ASSERT(vec != NULL); \
345  return NULL; \
346  } \
347  \
348  vec->size = size; \
349  vec->capacity = (capacity > vec->size || (vec->size && capacity == vec->size)) \
350  ? capacity \
351  : vec->size + CVEC_##TYPE##_SZ; \
352  \
353  if (!(vec->a = (TYPE*)CVEC_MALLOC(vec->capacity * sizeof(TYPE)))) { \
354  CVEC_ASSERT(vec->a != NULL); \
355  CVEC_FREE(vec); \
356  return NULL; \
357  } \
358  \
359  return vec; \
360  } \
361  \
362  cvector_##TYPE* cvec_init_##TYPE##_heap(TYPE* vals, cvec_sz num) \
363  { \
364  cvector_##TYPE* vec; \
365  \
366  if (!(vec = (cvector_##TYPE*)CVEC_MALLOC(sizeof(cvector_##TYPE)))) { \
367  CVEC_ASSERT(vec != NULL); \
368  return NULL; \
369  } \
370  \
371  vec->capacity = num + CVEC_##TYPE##_SZ; \
372  vec->size = num; \
373  if (!(vec->a = (TYPE*)CVEC_MALLOC(vec->capacity * sizeof(TYPE)))) { \
374  CVEC_ASSERT(vec->a != NULL); \
375  CVEC_FREE(vec); \
376  return NULL; \
377  } \
378  \
379  CVEC_MEMMOVE(vec->a, vals, sizeof(TYPE) * num); \
380  \
381  return vec; \
382  } \
383  \
384  int cvec_##TYPE(cvector_##TYPE* vec, cvec_sz size, cvec_sz capacity) \
385  { \
386  vec->size = size; \
387  vec->capacity = (capacity > vec->size || (vec->size && capacity == vec->size)) \
388  ? capacity \
389  : vec->size + CVEC_##TYPE##_SZ; \
390  \
391  if (!(vec->a = (TYPE*)CVEC_MALLOC(vec->capacity * sizeof(TYPE)))) { \
392  CVEC_ASSERT(vec->a != NULL); \
393  vec->size = vec->capacity = 0; \
394  return 0; \
395  } \
396  \
397  return 1; \
398  } \
399  \
400  int cvec_init_##TYPE(cvector_##TYPE* vec, TYPE* vals, cvec_sz num) \
401  { \
402  vec->capacity = num + CVEC_##TYPE##_SZ; \
403  vec->size = num; \
404  if (!(vec->a = (TYPE*)CVEC_MALLOC(vec->capacity * sizeof(TYPE)))) { \
405  CVEC_ASSERT(vec->a != NULL); \
406  vec->size = vec->capacity = 0; \
407  return 0; \
408  } \
409  \
410  CVEC_MEMMOVE(vec->a, vals, sizeof(TYPE) * num); \
411  \
412  return 1; \
413  } \
414  \
415  int cvec_copyc_##TYPE(void* dest, void* src) \
416  { \
417  cvector_##TYPE* vec1 = (cvector_##TYPE*)dest; \
418  cvector_##TYPE* vec2 = (cvector_##TYPE*)src; \
419  \
420  vec1->a = NULL; \
421  vec1->size = 0; \
422  vec1->capacity = 0; \
423  \
424  return cvec_copy_##TYPE(vec1, vec2); \
425  } \
426  \
427  int cvec_copy_##TYPE(cvector_##TYPE* dest, cvector_##TYPE* src) \
428  { \
429  TYPE* tmp = NULL; \
430  if (!(tmp = (TYPE*)CVEC_REALLOC(dest->a, src->capacity*sizeof(TYPE)))) { \
431  CVEC_ASSERT(tmp != NULL); \
432  return 0; \
433  } \
434  dest->a = tmp; \
435  \
436  CVEC_MEMMOVE(dest->a, src->a, src->size*sizeof(TYPE)); \
437  dest->size = src->size; \
438  dest->capacity = src->capacity; \
439  return 1; \
440  } \
441  \
442  int cvec_push_##TYPE(cvector_##TYPE* vec, TYPE a) \
443  { \
444  TYPE* tmp; \
445  cvec_sz tmp_sz; \
446  if (vec->capacity > vec->size) { \
447  vec->a[vec->size++] = a; \
448  } else { \
449  tmp_sz = RESIZE_MACRO(vec->capacity); \
450  if (!(tmp = (TYPE*)CVEC_REALLOC(vec->a, sizeof(TYPE) * tmp_sz))) { \
451  CVEC_ASSERT(tmp != NULL); \
452  return 0; \
453  } \
454  vec->a = tmp; \
455  vec->a[vec->size++] = a; \
456  vec->capacity = tmp_sz; \
457  } \
458  return 1; \
459  } \
460  \
461  TYPE cvec_pop_##TYPE(cvector_##TYPE* vec) { return vec->a[--vec->size]; } \
462  \
463  TYPE* cvec_back_##TYPE(cvector_##TYPE* vec) { return &vec->a[vec->size - 1]; } \
464  \
465  int cvec_extend_##TYPE(cvector_##TYPE* vec, cvec_sz num) \
466  { \
467  TYPE* tmp; \
468  cvec_sz tmp_sz; \
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); \
473  return 0; \
474  } \
475  vec->a = tmp; \
476  vec->capacity = tmp_sz; \
477  } \
478  \
479  vec->size += num; \
480  return 1; \
481  } \
482  \
483  int cvec_insert_##TYPE(cvector_##TYPE* vec, cvec_sz i, TYPE a) \
484  { \
485  TYPE* tmp; \
486  cvec_sz tmp_sz; \
487  if (vec->capacity > vec->size) { \
488  CVEC_MEMMOVE(&vec->a[i + 1], &vec->a[i], (vec->size - i) * sizeof(TYPE)); \
489  vec->a[i] = a; \
490  } else { \
491  tmp_sz = RESIZE_MACRO(vec->capacity); \
492  if (!(tmp = (TYPE*)CVEC_REALLOC(vec->a, sizeof(TYPE) * tmp_sz))) { \
493  CVEC_ASSERT(tmp != NULL); \
494  return 0; \
495  } \
496  vec->a = tmp; \
497  CVEC_MEMMOVE(&vec->a[i + 1], &vec->a[i], (vec->size - i) * sizeof(TYPE)); \
498  vec->a[i] = a; \
499  vec->capacity = tmp_sz; \
500  } \
501  \
502  vec->size++; \
503  return 1; \
504  } \
505  \
506  int cvec_insert_array_##TYPE(cvector_##TYPE* vec, cvec_sz i, TYPE* a, cvec_sz num) \
507  { \
508  TYPE* tmp; \
509  cvec_sz tmp_sz; \
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); \
514  return 0; \
515  } \
516  vec->a = tmp; \
517  vec->capacity = tmp_sz; \
518  } \
519  \
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)); \
522  vec->size += num; \
523  return 1; \
524  } \
525  \
526  TYPE cvec_replace_##TYPE(cvector_##TYPE* vec, cvec_sz i, TYPE a) \
527  { \
528  TYPE tmp = vec->a[i]; \
529  vec->a[i] = a; \
530  return tmp; \
531  } \
532  \
533  void cvec_erase_##TYPE(cvector_##TYPE* vec, cvec_sz start, cvec_sz end) \
534  { \
535  cvec_sz d = end - start + 1; \
536  CVEC_MEMMOVE(&vec->a[start], &vec->a[end + 1], (vec->size - 1 - end) * sizeof(TYPE)); \
537  vec->size -= d; \
538  } \
539  \
540  int cvec_reserve_##TYPE(cvector_##TYPE* vec, cvec_sz size) \
541  { \
542  TYPE* tmp; \
543  if (vec->capacity < size) { \
544  if (!(tmp = (TYPE*)CVEC_REALLOC(vec->a, sizeof(TYPE) * (size + CVEC_##TYPE##_SZ)))) { \
545  CVEC_ASSERT(tmp != NULL); \
546  return 0; \
547  } \
548  vec->a = tmp; \
549  vec->capacity = size + CVEC_##TYPE##_SZ; \
550  } \
551  return 1; \
552  } \
553  \
554  int cvec_set_cap_##TYPE(cvector_##TYPE* vec, cvec_sz size) \
555  { \
556  TYPE* tmp; \
557  if (size < vec->size) { \
558  vec->size = size; \
559  } \
560  \
561  if (!(tmp = (TYPE*)CVEC_REALLOC(vec->a, sizeof(TYPE) * size))) { \
562  CVEC_ASSERT(tmp != NULL); \
563  return 0; \
564  } \
565  vec->a = tmp; \
566  vec->capacity = size; \
567  return 1; \
568  } \
569  \
570  void cvec_set_val_sz_##TYPE(cvector_##TYPE* vec, TYPE val) \
571  { \
572  cvec_sz i; \
573  for (i = 0; i < vec->size; i++) { \
574  vec->a[i] = val; \
575  } \
576  } \
577  \
578  void cvec_set_val_cap_##TYPE(cvector_##TYPE* vec, TYPE val) \
579  { \
580  cvec_sz i; \
581  for (i = 0; i < vec->capacity; i++) { \
582  vec->a[i] = val; \
583  } \
584  } \
585  \
586  void cvec_clear_##TYPE(cvector_##TYPE* vec) { vec->size = 0; } \
587  \
588  void cvec_free_##TYPE##_heap(void* vec) \
589  { \
590  cvector_##TYPE* tmp = (cvector_##TYPE*)vec; \
591  if (!tmp) return; \
592  CVEC_FREE(tmp->a); \
593  CVEC_FREE(tmp); \
594  } \
595  \
596  void cvec_free_##TYPE(void* vec) \
597  { \
598  cvector_##TYPE* tmp = (cvector_##TYPE*)vec; \
599  CVEC_FREE(tmp->a); \
600  tmp->size = 0; \
601  tmp->capacity = 0; \
602  }
603 
604 #define CVEC_NEW_DECLS2(TYPE) \
605  typedef struct cvector_##TYPE { \
606  TYPE* a; \
607  cvec_sz size; \
608  cvec_sz capacity; \
609  void (*elem_free)(void*); \
610  int (*elem_init)(void*, void*); \
611  } cvector_##TYPE; \
612  \
613  extern cvec_sz CVEC_##TYPE##_SZ; \
614  \
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*)); \
619  \
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*)); \
624  \
625  int cvec_copyc_##TYPE(void* dest, void* src); \
626  int cvec_copy_##TYPE(cvector_##TYPE* dest, cvector_##TYPE* src); \
627  \
628  int cvec_push_##TYPE(cvector_##TYPE* vec, TYPE* val); \
629  void cvec_pop_##TYPE(cvector_##TYPE* vec, TYPE* ret); \
630  \
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); \
636  \
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); \
647  \
648  TYPE* cvec_back_##TYPE(cvector_##TYPE* vec); \
649  \
650  void cvec_clear_##TYPE(cvector_##TYPE* vec); \
651  void cvec_free_##TYPE##_heap(void* vec); \
652  void cvec_free_##TYPE(void* vec);
653 
654 #define CVEC_NEW_DEFS2(TYPE, RESIZE_MACRO) \
655  cvec_sz CVEC_##TYPE##_SZ = 20; \
656  \
657  cvector_##TYPE* cvec_##TYPE##_heap(cvec_sz size, cvec_sz capacity, void (*elem_free)(void*), \
658  int (*elem_init)(void*, void*)) \
659  { \
660  cvector_##TYPE* vec; \
661  if (!(vec = (cvector_##TYPE*)CVEC_MALLOC(sizeof(cvector_##TYPE)))) { \
662  CVEC_ASSERT(vec != NULL); \
663  return NULL; \
664  } \
665  \
666  vec->size = size; \
667  vec->capacity = (capacity > vec->size || (vec->size && capacity == vec->size)) \
668  ? capacity \
669  : vec->size + CVEC_##TYPE##_SZ; \
670  \
671  if (!(vec->a = (TYPE*)CVEC_MALLOC(vec->capacity * sizeof(TYPE)))) { \
672  CVEC_ASSERT(vec->a != NULL); \
673  CVEC_FREE(vec); \
674  return NULL; \
675  } \
676  \
677  vec->elem_free = elem_free; \
678  vec->elem_init = elem_init; \
679  \
680  return vec; \
681  } \
682  \
683  cvector_##TYPE* cvec_init_##TYPE##_heap(TYPE* vals, cvec_sz num, void (*elem_free)(void*), \
684  int (*elem_init)(void*, void*)) \
685  { \
686  cvector_##TYPE* vec; \
687  cvec_sz i; \
688  \
689  if (!(vec = (cvector_##TYPE*)CVEC_MALLOC(sizeof(cvector_##TYPE)))) { \
690  CVEC_ASSERT(vec != NULL); \
691  return NULL; \
692  } \
693  \
694  vec->capacity = num + CVEC_##TYPE##_SZ; \
695  vec->size = num; \
696  if (!(vec->a = (TYPE*)CVEC_MALLOC(vec->capacity * sizeof(TYPE)))) { \
697  CVEC_ASSERT(vec->a != NULL); \
698  CVEC_FREE(vec); \
699  return NULL; \
700  } \
701  \
702  if (elem_init) { \
703  for (i = 0; i < num; ++i) { \
704  if (!elem_init(&vec->a[i], &vals[i])) { \
705  CVEC_ASSERT(0); \
706  CVEC_FREE(vec->a); \
707  CVEC_FREE(vec); \
708  return NULL; \
709  } \
710  } \
711  } else { \
712  CVEC_MEMMOVE(vec->a, vals, sizeof(TYPE) * num); \
713  } \
714  \
715  vec->elem_free = elem_free; \
716  vec->elem_init = elem_init; \
717  \
718  return vec; \
719  } \
720  \
721  int cvec_##TYPE(cvector_##TYPE* vec, cvec_sz size, cvec_sz capacity, void (*elem_free)(void*), \
722  int (*elem_init)(void*, void*)) \
723  { \
724  vec->size = size; \
725  vec->capacity = (capacity > vec->size || (vec->size && capacity == vec->size)) \
726  ? capacity \
727  : vec->size + CVEC_##TYPE##_SZ; \
728  \
729  if (!(vec->a = (TYPE*)CVEC_MALLOC(vec->capacity * sizeof(TYPE)))) { \
730  CVEC_ASSERT(vec->a != NULL); \
731  vec->size = vec->capacity = 0; \
732  return 0; \
733  } \
734  \
735  vec->elem_free = elem_free; \
736  vec->elem_init = elem_init; \
737  \
738  return 1; \
739  } \
740  \
741  int cvec_init_##TYPE(cvector_##TYPE* vec, TYPE* vals, cvec_sz num, void (*elem_free)(void*), \
742  int (*elem_init)(void*, void*)) \
743  { \
744  cvec_sz i; \
745  \
746  vec->capacity = num + CVEC_##TYPE##_SZ; \
747  vec->size = num; \
748  if (!(vec->a = (TYPE*)CVEC_MALLOC(vec->capacity * sizeof(TYPE)))) { \
749  CVEC_ASSERT(vec->a != NULL); \
750  vec->size = vec->capacity = 0; \
751  return 0; \
752  } \
753  \
754  if (elem_init) { \
755  for (i = 0; i < num; ++i) { \
756  if (!elem_init(&vec->a[i], &vals[i])) { \
757  CVEC_ASSERT(0); \
758  return 0; \
759  } \
760  } \
761  } else { \
762  CVEC_MEMMOVE(vec->a, vals, sizeof(TYPE) * num); \
763  } \
764  \
765  vec->elem_free = elem_free; \
766  vec->elem_init = elem_init; \
767  \
768  return 1; \
769  } \
770  \
771  int cvec_copyc_##TYPE(void* dest, void* src) \
772  { \
773  cvector_##TYPE* vec1 = (cvector_##TYPE*)dest; \
774  cvector_##TYPE* vec2 = (cvector_##TYPE*)src; \
775  \
776  vec1->a = NULL; \
777  vec1->size = 0; \
778  vec1->capacity = 0; \
779  \
780  return cvec_copy_##TYPE(vec1, vec2); \
781  } \
782  \
783  int cvec_copy_##TYPE(cvector_##TYPE* dest, cvector_##TYPE* src) \
784  { \
785  int i; \
786  TYPE* tmp = NULL; \
787  if (!(tmp = (TYPE*)CVEC_REALLOC(dest->a, src->capacity*sizeof(TYPE)))) { \
788  CVEC_ASSERT(tmp != NULL); \
789  return 0; \
790  } \
791  dest->a = tmp; \
792  \
793  if (src->elem_init) { \
794  for (i=0; i<src->size; ++i) { \
795  if (!src->elem_init(&dest->a[i], &src->a[i])) { \
796  CVEC_ASSERT(0); \
797  return 0; \
798  } \
799  } \
800  } else { \
801  CVEC_MEMMOVE(dest->a, src->a, src->size*sizeof(TYPE)); \
802  } \
803  \
804  dest->size = src->size; \
805  dest->capacity = src->capacity; \
806  dest->elem_free = src->elem_free; \
807  dest->elem_init = src->elem_init; \
808  return 1; \
809  } \
810  \
811  int cvec_push_##TYPE(cvector_##TYPE* vec, TYPE* a) \
812  { \
813  TYPE* tmp; \
814  cvec_sz tmp_sz; \
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); \
819  return 0; \
820  } \
821  vec->a = tmp; \
822  vec->capacity = tmp_sz; \
823  } \
824  if (vec->elem_init) { \
825  if (!vec->elem_init(&vec->a[vec->size], a)) { \
826  CVEC_ASSERT(0); \
827  return 0; \
828  } \
829  } else { \
830  CVEC_MEMMOVE(&vec->a[vec->size], a, sizeof(TYPE)); \
831  } \
832  \
833  vec->size++; \
834  return 1; \
835  } \
836  \
837  int cvec_pushm_##TYPE(cvector_##TYPE* vec, TYPE* a) \
838  { \
839  TYPE* tmp; \
840  cvec_sz tmp_sz; \
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); \
845  return 0; \
846  } \
847  vec->a = tmp; \
848  vec->capacity = tmp_sz; \
849  } \
850  CVEC_MEMMOVE(&vec->a[vec->size], a, sizeof(TYPE)); \
851  \
852  vec->size++; \
853  return 1; \
854  } \
855  \
856  void cvec_pop_##TYPE(cvector_##TYPE* vec, TYPE* ret) \
857  { \
858  if (ret) { \
859  CVEC_MEMMOVE(ret, &vec->a[--vec->size], sizeof(TYPE)); \
860  } else { \
861  vec->size--; \
862  } \
863  \
864  if (vec->elem_free) { \
865  vec->elem_free(&vec->a[vec->size]); \
866  } \
867  } \
868  \
869  void cvec_popm_##TYPE(cvector_##TYPE* vec, TYPE* ret) \
870  { \
871  vec->size--; \
872  if (ret) { \
873  CVEC_MEMMOVE(ret, &vec->a[vec->size], sizeof(TYPE)); \
874  } \
875  } \
876  \
877  TYPE* cvec_back_##TYPE(cvector_##TYPE* vec) { return &vec->a[vec->size - 1]; } \
878  \
879  int cvec_extend_##TYPE(cvector_##TYPE* vec, cvec_sz num) \
880  { \
881  TYPE* tmp; \
882  cvec_sz tmp_sz; \
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); \
887  return 0; \
888  } \
889  vec->a = tmp; \
890  vec->capacity = tmp_sz; \
891  } \
892  \
893  vec->size += num; \
894  return 1; \
895  } \
896  \
897  int cvec_insert_##TYPE(cvector_##TYPE* vec, cvec_sz i, TYPE* a) \
898  { \
899  TYPE* tmp; \
900  cvec_sz tmp_sz; \
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); \
905  return 0; \
906  } \
907  \
908  vec->a = tmp; \
909  vec->capacity = tmp_sz; \
910  } \
911  CVEC_MEMMOVE(&vec->a[i + 1], &vec->a[i], (vec->size - i) * sizeof(TYPE)); \
912  \
913  if (vec->elem_init) { \
914  if (!vec->elem_init(&vec->a[i], a)) { \
915  CVEC_ASSERT(0); \
916  return 0; \
917  } \
918  } else { \
919  CVEC_MEMMOVE(&vec->a[i], a, sizeof(TYPE)); \
920  } \
921  \
922  vec->size++; \
923  return 1; \
924  } \
925  \
926  int cvec_insertm_##TYPE(cvector_##TYPE* vec, cvec_sz i, TYPE* a) \
927  { \
928  TYPE* tmp; \
929  cvec_sz tmp_sz; \
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); \
934  return 0; \
935  } \
936  \
937  vec->a = tmp; \
938  vec->capacity = tmp_sz; \
939  } \
940  CVEC_MEMMOVE(&vec->a[i + 1], &vec->a[i], (vec->size - i) * sizeof(TYPE)); \
941  \
942  CVEC_MEMMOVE(&vec->a[i], a, sizeof(TYPE)); \
943  \
944  vec->size++; \
945  return 1; \
946  } \
947  \
948  int cvec_insert_array_##TYPE(cvector_##TYPE* vec, cvec_sz i, TYPE* a, cvec_sz num) \
949  { \
950  TYPE* tmp; \
951  cvec_sz tmp_sz, j; \
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); \
956  return 0; \
957  } \
958  vec->a = tmp; \
959  vec->capacity = tmp_sz; \
960  } \
961  \
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])) { \
966  CVEC_ASSERT(0); \
967  return 0; \
968  } \
969  } \
970  } else { \
971  CVEC_MEMMOVE(&vec->a[i], a, num * sizeof(TYPE)); \
972  } \
973  vec->size += num; \
974  return 1; \
975  } \
976  \
977  int cvec_insert_arraym_##TYPE(cvector_##TYPE* vec, cvec_sz i, TYPE* a, cvec_sz num) \
978  { \
979  TYPE* tmp; \
980  cvec_sz tmp_sz; \
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); \
985  return 0; \
986  } \
987  vec->a = tmp; \
988  vec->capacity = tmp_sz; \
989  } \
990  \
991  CVEC_MEMMOVE(&vec->a[i + num], &vec->a[i], (vec->size - i) * sizeof(TYPE)); \
992  \
993  CVEC_MEMMOVE(&vec->a[i], a, num * sizeof(TYPE)); \
994  vec->size += num; \
995  return 1; \
996  } \
997  \
998  int cvec_replace_##TYPE(cvector_##TYPE* vec, cvec_sz i, TYPE* a, TYPE* ret) \
999  { \
1000  if (ret) { \
1001  CVEC_MEMMOVE(ret, &vec->a[i], sizeof(TYPE)); \
1002  } else if (vec->elem_free) { \
1003  vec->elem_free(&vec->a[i]); \
1004  } \
1005  \
1006  if (vec->elem_init) { \
1007  if (!vec->elem_init(&vec->a[i], a)) { \
1008  CVEC_ASSERT(0); \
1009  return 0; \
1010  } \
1011  } else { \
1012  CVEC_MEMMOVE(&vec->a[i], a, sizeof(TYPE)); \
1013  } \
1014  return 1; \
1015  } \
1016  \
1017  void cvec_replacem_##TYPE(cvector_##TYPE* vec, cvec_sz i, TYPE* a, TYPE* ret) \
1018  { \
1019  if (ret) { \
1020  CVEC_MEMMOVE(ret, &vec->a[i], sizeof(TYPE)); \
1021  } \
1022  \
1023  CVEC_MEMMOVE(&vec->a[i], a, sizeof(TYPE)); \
1024  } \
1025  \
1026  void cvec_erase_##TYPE(cvector_##TYPE* vec, cvec_sz start, cvec_sz end) \
1027  { \
1028  cvec_sz i; \
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]); \
1033  } \
1034  } \
1035  CVEC_MEMMOVE(&vec->a[start], &vec->a[end + 1], (vec->size - 1 - end) * sizeof(TYPE)); \
1036  vec->size -= d; \
1037  } \
1038  \
1039  void cvec_remove_##TYPE(cvector_##TYPE* vec, cvec_sz start, cvec_sz end) \
1040  { \
1041  cvec_sz d = end - start + 1; \
1042  CVEC_MEMMOVE(&vec->a[start], &vec->a[end + 1], (vec->size - 1 - end) * sizeof(TYPE)); \
1043  vec->size -= d; \
1044  } \
1045  \
1046  int cvec_reserve_##TYPE(cvector_##TYPE* vec, cvec_sz size) \
1047  { \
1048  TYPE* tmp; \
1049  if (vec->capacity < size) { \
1050  if (!(tmp = (TYPE*)CVEC_REALLOC(vec->a, sizeof(TYPE) * (size + CVEC_##TYPE##_SZ)))) { \
1051  CVEC_ASSERT(tmp != NULL); \
1052  return 0; \
1053  } \
1054  vec->a = tmp; \
1055  vec->capacity = size + CVEC_##TYPE##_SZ; \
1056  } \
1057  return 1; \
1058  } \
1059  \
1060  int cvec_set_cap_##TYPE(cvector_##TYPE* vec, cvec_sz size) \
1061  { \
1062  cvec_sz i; \
1063  TYPE* tmp; \
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]); \
1068  } \
1069  } \
1070  vec->size = size; \
1071  } \
1072  \
1073  vec->capacity = size; \
1074  \
1075  if (!(tmp = (TYPE*)CVEC_REALLOC(vec->a, sizeof(TYPE) * size))) { \
1076  CVEC_ASSERT(tmp != NULL); \
1077  return 0; \
1078  } \
1079  vec->a = tmp; \
1080  return 1; \
1081  } \
1082  \
1083  int cvec_set_val_sz_##TYPE(cvector_##TYPE* vec, TYPE* val) \
1084  { \
1085  cvec_sz i; \
1086  \
1087  if (vec->elem_free) { \
1088  for (i = 0; i < vec->size; i++) { \
1089  vec->elem_free(&vec->a[i]); \
1090  } \
1091  } \
1092  \
1093  if (vec->elem_init) { \
1094  for (i = 0; i < vec->size; i++) { \
1095  if (!vec->elem_init(&vec->a[i], val)) { \
1096  CVEC_ASSERT(0); \
1097  return 0; \
1098  } \
1099  } \
1100  } else { \
1101  for (i = 0; i < vec->size; i++) { \
1102  CVEC_MEMMOVE(&vec->a[i], val, sizeof(TYPE)); \
1103  } \
1104  } \
1105  return 1; \
1106  } \
1107  \
1108  int cvec_set_val_cap_##TYPE(cvector_##TYPE* vec, TYPE* val) \
1109  { \
1110  cvec_sz i; \
1111  if (vec->elem_free) { \
1112  for (i = 0; i < vec->size; i++) { \
1113  vec->elem_free(&vec->a[i]); \
1114  } \
1115  vec->size = vec->capacity; \
1116  } \
1117  \
1118  if (vec->elem_init) { \
1119  for (i = 0; i < vec->capacity; i++) { \
1120  if (!vec->elem_init(&vec->a[i], val)) { \
1121  CVEC_ASSERT(0); \
1122  return 0; \
1123  } \
1124  } \
1125  } else { \
1126  for (i = 0; i < vec->capacity; i++) { \
1127  CVEC_MEMMOVE(&vec->a[i], val, sizeof(TYPE)); \
1128  } \
1129  } \
1130  return 1; \
1131  } \
1132  \
1133  void cvec_clear_##TYPE(cvector_##TYPE* vec) \
1134  { \
1135  cvec_sz i; \
1136  if (vec->elem_free) { \
1137  for (i = 0; i < vec->size; ++i) { \
1138  vec->elem_free(&vec->a[i]); \
1139  } \
1140  } \
1141  vec->size = 0; \
1142  } \
1143  \
1144  void cvec_free_##TYPE##_heap(void* vec) \
1145  { \
1146  cvec_sz i; \
1147  cvector_##TYPE* tmp = (cvector_##TYPE*)vec; \
1148  if (!tmp) return; \
1149  if (tmp->elem_free) { \
1150  for (i = 0; i < tmp->size; i++) { \
1151  tmp->elem_free(&tmp->a[i]); \
1152  } \
1153  } \
1154  CVEC_FREE(tmp->a); \
1155  CVEC_FREE(tmp); \
1156  } \
1157  \
1158  void cvec_free_##TYPE(void* vec) \
1159  { \
1160  cvec_sz i; \
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]); \
1165  } \
1166  } \
1167  \
1168  CVEC_FREE(tmp->a); \
1169  \
1170  tmp->size = 0; \
1171  tmp->capacity = 0; \
1172  }
1173 
1174 
1175 
1176 /* header ends */
1177 #endif
1178 
1179 
1180 #ifdef CVECTOR_IMPLEMENTATION
1181 
1182 #ifndef CVEC_NO_INT
1183 
1185 
1186 #define CVEC_I_ALLOCATOR(x) ((x+1) * 2)
1187 
1194 cvector_i* cvec_i_heap(cvec_sz size, cvec_sz capacity)
1195 {
1196  cvector_i* vec;
1197  if (!(vec = (cvector_i*)CVEC_MALLOC(sizeof(cvector_i)))) {
1198  CVEC_ASSERT(vec != NULL);
1199  return NULL;
1200  }
1201 
1202  vec->size = size;
1203  vec->capacity = (capacity > vec->size || (vec->size && capacity == vec->size)) ? capacity : vec->size + CVEC_I_START_SZ;
1204 
1205  if (!(vec->a = (int*)CVEC_MALLOC(vec->capacity*sizeof(int)))) {
1206  CVEC_ASSERT(vec->a != NULL);
1207  CVEC_FREE(vec);
1208  return NULL;
1209  }
1210 
1211  return vec;
1212 }
1213 
1217 cvector_i* cvec_init_i_heap(int* vals, cvec_sz num)
1218 {
1219  cvector_i* vec;
1220 
1221  if (!(vec = (cvector_i*)CVEC_MALLOC(sizeof(cvector_i)))) {
1222  CVEC_ASSERT(vec != NULL);
1223  return NULL;
1224  }
1225 
1226  vec->capacity = num + CVEC_I_START_SZ;
1227  vec->size = num;
1228  if (!(vec->a = (int*)CVEC_MALLOC(vec->capacity*sizeof(int)))) {
1229  CVEC_ASSERT(vec->a != NULL);
1230  CVEC_FREE(vec);
1231  return NULL;
1232  }
1233 
1234  CVEC_MEMMOVE(vec->a, vals, sizeof(int)*num);
1235 
1236  return vec;
1237 }
1238 
1243 int cvec_i(cvector_i* vec, cvec_sz size, cvec_sz capacity)
1244 {
1245  vec->size = size;
1246  vec->capacity = (capacity > vec->size || (vec->size && capacity == vec->size)) ? capacity : vec->size + CVEC_I_START_SZ;
1247 
1248  if (!(vec->a = (int*)CVEC_MALLOC(vec->capacity*sizeof(int)))) {
1249  CVEC_ASSERT(vec->a != NULL);
1250  vec->size = vec->capacity = 0;
1251  return 0;
1252  }
1253 
1254  return 1;
1255 }
1256 
1260 int cvec_init_i(cvector_i* vec, int* vals, cvec_sz num)
1261 {
1262  vec->capacity = num + CVEC_I_START_SZ;
1263  vec->size = num;
1264  if (!(vec->a = (int*)CVEC_MALLOC(vec->capacity*sizeof(int)))) {
1265  CVEC_ASSERT(vec->a != NULL);
1266  vec->size = vec->capacity = 0;
1267  return 0;
1268  }
1269 
1270  CVEC_MEMMOVE(vec->a, vals, sizeof(int)*num);
1271 
1272  return 1;
1273 }
1274 
1285 int cvec_copyc_i(void* dest, void* src)
1286 {
1287  cvector_i* vec1 = (cvector_i*)dest;
1288  cvector_i* vec2 = (cvector_i*)src;
1289 
1290  vec1->a = NULL;
1291  vec1->size = 0;
1292  vec1->capacity = 0;
1293 
1294  return cvec_copy_i(vec1, vec2);
1295 }
1296 
1306 int cvec_copy_i(cvector_i* dest, cvector_i* src)
1307 {
1308  int* tmp = NULL;
1309  if (!(tmp = (int*)CVEC_REALLOC(dest->a, src->capacity*sizeof(int)))) {
1310  CVEC_ASSERT(tmp != NULL);
1311  return 0;
1312  }
1313  dest->a = tmp;
1314 
1315  CVEC_MEMMOVE(dest->a, src->a, src->size*sizeof(int));
1316  dest->size = src->size;
1317  dest->capacity = src->capacity;
1318  return 1;
1319 }
1320 
1325 int cvec_push_i(cvector_i* vec, int a)
1326 {
1327  int* tmp;
1328  cvec_sz tmp_sz;
1329  if (vec->capacity == vec->size) {
1330  tmp_sz = CVEC_I_ALLOCATOR(vec->capacity);
1331  if (!(tmp = (int*)CVEC_REALLOC(vec->a, sizeof(int)*tmp_sz))) {
1332  CVEC_ASSERT(tmp != NULL);
1333  return 0;
1334  }
1335  vec->a = tmp;
1336  vec->capacity = tmp_sz;
1337  }
1338 
1339  vec->a[vec->size++] = a;
1340  return 1;
1341 }
1342 
1344 int cvec_pop_i(cvector_i* vec)
1345 {
1346  return vec->a[--vec->size];
1347 }
1348 
1350 int* cvec_back_i(cvector_i* vec)
1351 {
1352  return &vec->a[vec->size-1];
1353 }
1354 
1357 int cvec_extend_i(cvector_i* vec, cvec_sz num)
1358 {
1359  int* tmp;
1360  cvec_sz tmp_sz;
1361  if (vec->capacity < vec->size + num) {
1362  tmp_sz = vec->capacity + num + CVEC_I_START_SZ;
1363  if (!(tmp = (int*)CVEC_REALLOC(vec->a, sizeof(int)*tmp_sz))) {
1364  CVEC_ASSERT(tmp != NULL);
1365  return 0;
1366  }
1367  vec->a = tmp;
1368  vec->capacity = tmp_sz;
1369  }
1370 
1371  vec->size += num;
1372  return 1;
1373 }
1374 
1379 int cvec_insert_i(cvector_i* vec, cvec_sz i, int a)
1380 {
1381  int* tmp;
1382  cvec_sz tmp_sz;
1383  if (vec->capacity == vec->size) {
1384  tmp_sz = CVEC_I_ALLOCATOR(vec->capacity);
1385  if (!(tmp = (int*)CVEC_REALLOC(vec->a, sizeof(int)*tmp_sz))) {
1386  CVEC_ASSERT(tmp != NULL);
1387  return 0;
1388  }
1389  vec->a = tmp;
1390  vec->capacity = tmp_sz;
1391  }
1392 
1393  CVEC_MEMMOVE(&vec->a[i+1], &vec->a[i], (vec->size-i)*sizeof(int));
1394  vec->a[i] = a;
1395  vec->size++;
1396  return 1;
1397 }
1398 
1405 int cvec_insert_array_i(cvector_i* vec, cvec_sz i, int* a, cvec_sz num)
1406 {
1407  int* tmp;
1408  cvec_sz tmp_sz;
1409  if (vec->capacity < vec->size + num) {
1410  tmp_sz = vec->capacity + num + CVEC_I_START_SZ;
1411  if (!(tmp = (int*)CVEC_REALLOC(vec->a, sizeof(int)*tmp_sz))) {
1412  CVEC_ASSERT(tmp != NULL);
1413  return 0;
1414  }
1415  vec->a = tmp;
1416  vec->capacity = tmp_sz;
1417  }
1418 
1419  CVEC_MEMMOVE(&vec->a[i+num], &vec->a[i], (vec->size-i)*sizeof(int));
1420  CVEC_MEMMOVE(&vec->a[i], a, num*sizeof(int));
1421  vec->size += num;
1422  return 1;
1423 }
1424 
1426 int cvec_replace_i(cvector_i* vec, cvec_sz i, int a)
1427 {
1428  int tmp = vec->a[i];
1429  vec->a[i] = a;
1430  return tmp;
1431 }
1432 
1438 void cvec_erase_i(cvector_i* vec, cvec_sz start, cvec_sz end)
1439 {
1440  cvec_sz d = end - start + 1;
1441  CVEC_MEMMOVE(&vec->a[start], &vec->a[end+1], (vec->size-1-end)*sizeof(int));
1442  vec->size -= d;
1443 }
1444 
1446 int cvec_reserve_i(cvector_i* vec, cvec_sz size)
1447 {
1448  int* tmp;
1449  if (vec->capacity < size) {
1450  if (!(tmp = (int*)CVEC_REALLOC(vec->a, sizeof(int)*(size+CVEC_I_START_SZ)))) {
1451  CVEC_ASSERT(tmp != NULL);
1452  return 0;
1453  }
1454  vec->a = tmp;
1455  vec->capacity = size + CVEC_I_START_SZ;
1456  }
1457  return 1;
1458 }
1459 
1464 int cvec_set_cap_i(cvector_i* vec, cvec_sz size)
1465 {
1466  int* tmp;
1467  if (size < vec->size) {
1468  vec->size = size;
1469  }
1470 
1471  if (!(tmp = (int*)CVEC_REALLOC(vec->a, sizeof(int)*size))) {
1472  CVEC_ASSERT(tmp != NULL);
1473  return 0;
1474  }
1475  vec->a = tmp;
1476  vec->capacity = size;
1477  return 1;
1478 }
1479 
1481 void cvec_set_val_sz_i(cvector_i* vec, int val)
1482 {
1483  cvec_sz i;
1484  for (i=0; i<vec->size; i++) {
1485  vec->a[i] = val;
1486  }
1487 }
1488 
1490 void cvec_set_val_cap_i(cvector_i* vec, int val)
1491 {
1492  cvec_sz i;
1493  for (i=0; i<vec->capacity; i++) {
1494  vec->a[i] = val;
1495  }
1496 }
1497 
1499 void cvec_clear_i(cvector_i* vec) { vec->size = 0; }
1500 
1503 void cvec_free_i_heap(void* vec)
1504 {
1505  cvector_i* tmp = (cvector_i*)vec;
1506  if (!tmp) return;
1507  CVEC_FREE(tmp->a);
1508  CVEC_FREE(tmp);
1509 }
1510 
1512 void cvec_free_i(void* vec)
1513 {
1514  cvector_i* tmp = (cvector_i*)vec;
1515  CVEC_FREE(tmp->a);
1516  tmp->size = 0;
1517  tmp->capacity = 0;
1518 }
1519 
1520 #endif
1521 
1522 #ifndef CVEC_NO_DOUBLE
1523 
1525 
1526 #define CVEC_D_ALLOCATOR(x) ((x+1) * 2)
1527 
1534 cvector_d* cvec_d_heap(cvec_sz size, cvec_sz capacity)
1535 {
1536  cvector_d* vec;
1537 
1538  if (!(vec = (cvector_d*)CVEC_MALLOC(sizeof(cvector_d)))) {
1539  CVEC_ASSERT(vec != NULL);
1540  return NULL;
1541  }
1542 
1543  vec->size = size;
1544  vec->capacity = (capacity > vec->size || (vec->size && capacity == vec->size)) ? capacity : vec->size + CVEC_D_START_SZ;
1545 
1546  if (!(vec->a = (double*)CVEC_MALLOC(vec->capacity*sizeof(double)))) {
1547  CVEC_ASSERT(vec->a != NULL);
1548  CVEC_FREE(vec);
1549  return NULL;
1550  }
1551 
1552  return vec;
1553 }
1554 
1558 cvector_d* cvec_init_d_heap(double* vals, cvec_sz num)
1559 {
1560  cvector_d* vec;
1561 
1562  if (!(vec = (cvector_d*)CVEC_MALLOC(sizeof(cvector_d)))) {
1563  CVEC_ASSERT(vec != NULL);
1564  return NULL;
1565  }
1566 
1567  vec->capacity = num + CVEC_D_START_SZ;
1568  vec->size = num;
1569  if (!(vec->a = (double*)CVEC_MALLOC(vec->capacity*sizeof(double)))) {
1570  CVEC_ASSERT(vec->a != NULL);
1571  CVEC_FREE(vec);
1572  return NULL;
1573  }
1574 
1575  CVEC_MEMMOVE(vec->a, vals, sizeof(double)*num);
1576 
1577  return vec;
1578 }
1579 
1584 int cvec_d(cvector_d* vec, cvec_sz size, cvec_sz capacity)
1585 {
1586  vec->size = size;
1587  vec->capacity = (capacity > vec->size || (vec->size && capacity == vec->size)) ? capacity : vec->size + CVEC_D_START_SZ;
1588 
1589  if (!(vec->a = (double*)CVEC_MALLOC(vec->capacity*sizeof(double)))) {
1590  CVEC_ASSERT(vec->a != NULL);
1591  vec->size = vec->capacity = 0;
1592  return 0;
1593  }
1594 
1595  return 1;
1596 }
1597 
1601 int cvec_init_d(cvector_d* vec, double* vals, cvec_sz num)
1602 {
1603  vec->capacity = num + CVEC_D_START_SZ;
1604  vec->size = num;
1605  if (!(vec->a = (double*)CVEC_MALLOC(vec->capacity*sizeof(double)))) {
1606  CVEC_ASSERT(vec->a != NULL);
1607  vec->size = vec->capacity = 0;
1608  return 0;
1609  }
1610 
1611  CVEC_MEMMOVE(vec->a, vals, sizeof(double)*num);
1612 
1613  return 1;
1614 }
1615 
1626 int cvec_copyc_d(void* dest, void* src)
1627 {
1628  cvector_d* vec1 = (cvector_d*)dest;
1629  cvector_d* vec2 = (cvector_d*)src;
1630 
1631  vec1->a = NULL;
1632  vec1->size = 0;
1633  vec1->capacity = 0;
1634 
1635  return cvec_copy_d(vec1, vec2);
1636 }
1637 
1647 int cvec_copy_d(cvector_d* dest, cvector_d* src)
1648 {
1649  double* tmp = NULL;
1650  if (!(tmp = (double*)CVEC_REALLOC(dest->a, src->capacity*sizeof(double)))) {
1651  CVEC_ASSERT(tmp != NULL);
1652  return 0;
1653  }
1654  dest->a = tmp;
1655 
1656  CVEC_MEMMOVE(dest->a, src->a, src->size*sizeof(double));
1657  dest->size = src->size;
1658  dest->capacity = src->capacity;
1659  return 1;
1660 }
1661 
1662 
1666 int cvec_push_d(cvector_d* vec, double a)
1667 {
1668  double* tmp;
1669  cvec_sz tmp_sz;
1670  if (vec->capacity == vec->size) {
1671  tmp_sz = CVEC_D_ALLOCATOR(vec->capacity);
1672  if (!(tmp = (double*)CVEC_REALLOC(vec->a, sizeof(double)*tmp_sz))) {
1673  CVEC_ASSERT(tmp != NULL);
1674  return 0;
1675  }
1676  vec->a = tmp;
1677  vec->capacity = tmp_sz;
1678  }
1679  vec->a[vec->size++] = a;
1680  return 1;
1681 }
1682 
1684 double cvec_pop_d(cvector_d* vec)
1685 {
1686  return vec->a[--vec->size];
1687 }
1688 
1690 double* cvec_back_d(cvector_d* vec)
1691 {
1692  return &vec->a[vec->size-1];
1693 }
1694 
1697 int cvec_extend_d(cvector_d* vec, cvec_sz num)
1698 {
1699  double* tmp;
1700  cvec_sz tmp_sz;
1701  if (vec->capacity < vec->size + num) {
1702  tmp_sz = vec->capacity + num + CVEC_D_START_SZ;
1703  if (!(tmp = (double*)CVEC_REALLOC(vec->a, sizeof(double)*tmp_sz))) {
1704  CVEC_ASSERT(tmp != NULL);
1705  return 0;
1706  }
1707  vec->a = tmp;
1708  vec->capacity = tmp_sz;
1709  }
1710 
1711  vec->size += num;
1712  return 1;
1713 }
1714 
1719 int cvec_insert_d(cvector_d* vec, cvec_sz i, double a)
1720 {
1721  double* tmp;
1722  cvec_sz tmp_sz;
1723  if (vec->capacity == vec->size) {
1724  tmp_sz = CVEC_D_ALLOCATOR(vec->capacity);
1725  if (!(tmp = (double*)CVEC_REALLOC(vec->a, sizeof(double)*tmp_sz))) {
1726  CVEC_ASSERT(tmp != NULL);
1727  return 0;
1728  }
1729  vec->a = tmp;
1730  vec->capacity = tmp_sz;
1731  }
1732 
1733  CVEC_MEMMOVE(&vec->a[i+1], &vec->a[i], (vec->size-i)*sizeof(double));
1734  vec->a[i] = a;
1735  vec->size++;
1736  return 1;
1737 }
1738 
1745 int cvec_insert_array_d(cvector_d* vec, cvec_sz i, double* a, cvec_sz num)
1746 {
1747  double* tmp;
1748  cvec_sz tmp_sz;
1749  if (vec->capacity < vec->size + num) {
1750  tmp_sz = vec->capacity + num + CVEC_D_START_SZ;
1751  if (!(tmp = (double*)CVEC_REALLOC(vec->a, sizeof(double)*tmp_sz))) {
1752  CVEC_ASSERT(tmp != NULL);
1753  return 0;
1754  }
1755  vec->a = tmp;
1756  vec->capacity = tmp_sz;
1757  }
1758 
1759  CVEC_MEMMOVE(&vec->a[i+num], &vec->a[i], (vec->size-i)*sizeof(double));
1760  CVEC_MEMMOVE(&vec->a[i], a, num*sizeof(double));
1761  vec->size += num;
1762  return 1;
1763 }
1764 
1766 double cvec_replace_d(cvector_d* vec, cvec_sz i, double a)
1767 {
1768  double tmp = vec->a[i];
1769  vec->a[i] = a;
1770  return tmp;
1771 }
1772 
1778 void cvec_erase_d(cvector_d* vec, cvec_sz start, cvec_sz end)
1779 {
1780  cvec_sz d = end - start + 1;
1781  CVEC_MEMMOVE(&vec->a[start], &vec->a[end+1], (vec->size-1-end)*sizeof(double));
1782  vec->size -= d;
1783 }
1784 
1786 int cvec_reserve_d(cvector_d* vec, cvec_sz size)
1787 {
1788  double* tmp;
1789  if (vec->capacity < size) {
1790  if (!(tmp = (double*)CVEC_REALLOC(vec->a, sizeof(double)*(size+CVEC_D_START_SZ)))) {
1791  CVEC_ASSERT(tmp != NULL);
1792  return 0;
1793  }
1794  vec->a = tmp;
1795  vec->capacity = size + CVEC_D_START_SZ;
1796  }
1797  return 1;
1798 }
1799 
1804 int cvec_set_cap_d(cvector_d* vec, cvec_sz size)
1805 {
1806  double* tmp;
1807  if (size < vec->size)
1808  vec->size = size;
1809 
1810  if (!(tmp = (double*)CVEC_REALLOC(vec->a, sizeof(double)*size))) {
1811  CVEC_ASSERT(tmp != NULL);
1812  return 0;
1813  }
1814  vec->a = tmp;
1815  vec->capacity = size;
1816  return 1;
1817 }
1818 
1820 void cvec_set_val_sz_d(cvector_d* vec, double val)
1821 {
1822  cvec_sz i;
1823  for(i=0; i<vec->size; i++) {
1824  vec->a[i] = val;
1825  }
1826 }
1827 
1829 void cvec_set_val_cap_d(cvector_d* vec, double val)
1830 {
1831  cvec_sz i;
1832  for(i=0; i<vec->capacity; i++) {
1833  vec->a[i] = val;
1834  }
1835 }
1836 
1838 void cvec_clear_d(cvector_d* vec) { vec->size = 0; }
1839 
1842 void cvec_free_d_heap(void* vec)
1843 {
1844  cvector_d* tmp = (cvector_d*)vec;
1845  if (!tmp) return;
1846  CVEC_FREE(tmp->a);
1847  CVEC_FREE(tmp);
1848 }
1849 
1851 void cvec_free_d(void* vec)
1852 {
1853  cvector_d* tmp = (cvector_d*)vec;
1854  CVEC_FREE(tmp->a); tmp->size = 0;
1855  tmp->capacity = 0;
1856 }
1857 #endif
1858 
1859 #ifndef CVEC_NO_STR
1860 
1862 
1863 #define CVEC_STR_ALLOCATOR(x) ((x+1) * 2)
1864 
1865 #if CVEC_STRDUP == cvec_strdup
1867 char* cvec_strdup(const char* str)
1868 {
1869  cvec_sz len;
1870  char* temp;
1871  if (!str)
1872  return NULL;
1873 
1874  len = strlen(str);
1875  temp = (char*)CVEC_MALLOC(len+1);
1876  if (!temp) {
1877  CVEC_ASSERT(temp != NULL);
1878  return NULL;
1879  }
1880  temp[len] = 0;
1881 
1882  return (char*)CVEC_MEMMOVE(temp, str, len); /* CVEC_MEMMOVE returns to */
1883 }
1884 #endif
1885 
1896 cvector_str* cvec_str_heap(cvec_sz size, cvec_sz capacity)
1897 {
1898  cvector_str* vec;
1899  if (!(vec = (cvector_str*)CVEC_MALLOC(sizeof(cvector_str)))) {
1900  CVEC_ASSERT(vec != NULL);
1901  return NULL;
1902  }
1903 
1904  vec->size = size;
1905  vec->capacity = (capacity > vec->size || (vec->size && capacity == vec->size)) ? capacity : vec->size + CVEC_STR_START_SZ;
1906 
1907  if (!(vec->a = (char**)CVEC_MALLOC(vec->capacity * sizeof(char*)))) {
1908  CVEC_ASSERT(vec->a != NULL);
1909  CVEC_FREE(vec);
1910  return NULL;
1911  }
1912  /* clearing to 0 here because if the user gave a non-zero initial size, popping/
1913  * erasing will crash unless they're NULL. Really the user should never do that.
1914  * They should use cvec_init or otherwise immediately assign to the size elements they
1915  * started with. */
1916  memset(vec->a, 0, vec->capacity*sizeof(char*));
1917 
1918  return vec;
1919 }
1920 
1923 cvector_str* cvec_init_str_heap(char** vals, cvec_sz num)
1924 {
1925  cvector_str* vec;
1926  cvec_sz i;
1927 
1928  if (!(vec = (cvector_str*)CVEC_MALLOC(sizeof(cvector_str)))) {
1929  CVEC_ASSERT(vec != NULL);
1930  return NULL;
1931  }
1932 
1933  vec->capacity = num + CVEC_STR_START_SZ;
1934  vec->size = num;
1935  if (!(vec->a = (char**)CVEC_MALLOC(vec->capacity*sizeof(char*)))) {
1936  CVEC_ASSERT(vec->a != NULL);
1937  CVEC_FREE(vec);
1938  return NULL;
1939  }
1940 
1941  for(i=0; i<num; i++) {
1942  vec->a[i] = CVEC_STRDUP(vals[i]);
1943  }
1944 
1945  return vec;
1946 }
1947 
1952 int cvec_str(cvector_str* vec, cvec_sz size, cvec_sz capacity)
1953 {
1954  vec->size = size;
1955  vec->capacity = (capacity > vec->size || (vec->size && capacity == vec->size)) ? capacity : vec->size + CVEC_STR_START_SZ;
1956 
1957  if (!(vec->a = (char**)CVEC_MALLOC(vec->capacity * sizeof(char*)))) {
1958  CVEC_ASSERT(vec->a != NULL);
1959  vec->size = vec->capacity = 0;
1960  return 0;
1961  }
1962  /* clearing to 0 here because if the user gave a non-zero initial size, popping/
1963  * erasing will crash unless they're NULL */
1964  memset(vec->a, 0, vec->capacity*sizeof(char*));
1965 
1966  return 1;
1967 }
1968 
1972 int cvec_init_str(cvector_str* vec, char** vals, cvec_sz num)
1973 {
1974  cvec_sz i;
1975 
1976  vec->capacity = num + CVEC_STR_START_SZ;
1977  vec->size = num;
1978  if (!(vec->a = (char**)CVEC_MALLOC(vec->capacity*sizeof(char*)))) {
1979  CVEC_ASSERT(vec->a != NULL);
1980  vec->size = vec->capacity = 0;
1981  return 0;
1982  }
1983 
1984  for(i=0; i<num; i++) {
1985  vec->a[i] = CVEC_STRDUP(vals[i]);
1986  }
1987 
1988  return 1;
1989 }
1990 
2001 int cvec_copyc_str(void* dest, void* src)
2002 {
2003  cvector_str* vec1 = (cvector_str*)dest;
2004  cvector_str* vec2 = (cvector_str*)src;
2005 
2006  vec1->a = NULL;
2007  vec1->size = 0;
2008  vec1->capacity = 0;
2009 
2010  return cvec_copy_str(vec1, vec2);
2011 }
2012 
2022 int cvec_copy_str(cvector_str* dest, cvector_str* src)
2023 {
2024  int i;
2025  char** tmp = NULL;
2026  if (!(tmp = (char**)CVEC_REALLOC(dest->a, src->capacity*sizeof(char*)))) {
2027  CVEC_ASSERT(tmp != NULL);
2028  return 0;
2029  }
2030  dest->a = tmp;
2031 
2032  for (i=0; i<src->size; ++i) {
2033  dest->a[i] = CVEC_STRDUP(src->a[i]);
2034  }
2035  dest->size = src->size;
2036  dest->capacity = src->capacity;
2037  return 1;
2038 }
2039 
2044 int cvec_push_str(cvector_str* vec, char* a)
2045 {
2046  char** tmp;
2047  cvec_sz tmp_sz;
2048  if (vec->capacity == vec->size) {
2049  tmp_sz = CVEC_STR_ALLOCATOR(vec->capacity);
2050  if (!(tmp = (char**)CVEC_REALLOC(vec->a, sizeof(char*)*tmp_sz))) {
2051  CVEC_ASSERT(tmp != NULL);
2052  return 0;
2053  }
2054  vec->a = tmp;
2055  vec->capacity = tmp_sz;
2056  }
2057 
2058  vec->a[vec->size++] = CVEC_STRDUP(a);
2059  return 1;
2060 }
2061 
2063 int cvec_pushm_str(cvector_str* vec, char* a)
2064 {
2065  char** tmp;
2066  cvec_sz tmp_sz;
2067  if (vec->capacity == vec->size) {
2068  tmp_sz = CVEC_STR_ALLOCATOR(vec->capacity);
2069  if (!(tmp = (char**)CVEC_REALLOC(vec->a, sizeof(char*)*tmp_sz))) {
2070  CVEC_ASSERT(tmp != NULL);
2071  return 0;
2072  }
2073  vec->a = tmp;
2074  vec->capacity = tmp_sz;
2075  }
2076 
2077  vec->a[vec->size++] = a;
2078  return 1;
2079 }
2080 
2085 void cvec_pop_str(cvector_str* vec, char* ret)
2086 {
2087  vec->size--;
2088  if (ret)
2089  strcpy(ret, vec->a[vec->size]);
2090  CVEC_FREE(vec->a[vec->size]);
2091 }
2092 
2094 char** cvec_back_str(cvector_str* vec)
2095 {
2096  return &vec->a[vec->size-1];
2097 }
2098 
2102 int cvec_extend_str(cvector_str* vec, cvec_sz num)
2103 {
2104  char** tmp;
2105  cvec_sz tmp_sz;
2106  if (vec->capacity < vec->size + num) {
2107  tmp_sz = vec->capacity + num + CVEC_STR_START_SZ;
2108  if (!(tmp = (char**)CVEC_REALLOC(vec->a, sizeof(char*)*tmp_sz))) {
2109  CVEC_ASSERT(tmp != NULL);
2110  return 0;
2111  }
2112  vec->a = tmp;
2113  vec->capacity = tmp_sz;
2114  }
2115 
2116  memset(&vec->a[vec->size], 0, num*sizeof(char*));
2117  vec->size += num;
2118  return 1;
2119 }
2120 
2125 int cvec_insert_str(cvector_str* vec, cvec_sz i, char* a)
2126 {
2127  char** tmp;
2128  cvec_sz tmp_sz;
2129  if (vec->capacity == vec->size) {
2130  tmp_sz = CVEC_STR_ALLOCATOR(vec->capacity);
2131  if (!(tmp = (char**)CVEC_REALLOC(vec->a, sizeof(char*)*tmp_sz))) {
2132  CVEC_ASSERT(tmp != NULL);
2133  return 0;
2134  }
2135  vec->a = tmp;
2136  vec->capacity = tmp_sz;
2137  }
2138 
2139  CVEC_MEMMOVE(&vec->a[i+1], &vec->a[i], (vec->size-i)*sizeof(char*));
2140  vec->a[i] = CVEC_STRDUP(a);
2141  vec->size++;
2142  return 1;
2143 }
2144 
2148 int cvec_insertm_str(cvector_str* vec, cvec_sz i, char* a)
2149 {
2150  char** tmp;
2151  cvec_sz tmp_sz;
2152  if (vec->capacity == vec->size) {
2153  tmp_sz = CVEC_STR_ALLOCATOR(vec->capacity);
2154  if (!(tmp = (char**)CVEC_REALLOC(vec->a, sizeof(char*)*tmp_sz))) {
2155  CVEC_ASSERT(tmp != NULL);
2156  return 0;
2157  }
2158  vec->a = tmp;
2159  vec->capacity = tmp_sz;
2160  }
2161 
2162  CVEC_MEMMOVE(&vec->a[i+1], &vec->a[i], (vec->size-i)*sizeof(char*));
2163  vec->a[i] = a;
2164  vec->size++;
2165  return 1;
2166 }
2167 
2173 int cvec_insert_array_str(cvector_str* vec, cvec_sz i, char** a, cvec_sz num)
2174 {
2175  char** tmp;
2176  cvec_sz tmp_sz, j;
2177  if (vec->capacity < vec->size + num) {
2178  tmp_sz = vec->capacity + num + CVEC_STR_START_SZ;
2179  if (!(tmp = (char**)CVEC_REALLOC(vec->a, sizeof(char*)*tmp_sz))) {
2180  CVEC_ASSERT(tmp != NULL);
2181  return 0;
2182  }
2183  vec->a = tmp;
2184  vec->capacity = tmp_sz;
2185  }
2186 
2187  CVEC_MEMMOVE(&vec->a[i+num], &vec->a[i], (vec->size-i)*sizeof(char*));
2188  for (j=0; j<num; ++j) {
2189  vec->a[j+i] = CVEC_STRDUP(a[j]);
2190  }
2191 
2192  vec->size += num;
2193  return 1;
2194 }
2195 
2199 int cvec_insert_arraym_str(cvector_str* vec, cvec_sz i, char** a, cvec_sz num)
2200 {
2201  char** tmp;
2202  cvec_sz tmp_sz;
2203  if (vec->capacity < vec->size + num) {
2204  tmp_sz = vec->capacity + num + CVEC_STR_START_SZ;
2205  if (!(tmp = (char**)CVEC_REALLOC(vec->a, sizeof(char*)*tmp_sz))) {
2206  CVEC_ASSERT(tmp != NULL);
2207  return 0;
2208  }
2209  vec->a = tmp;
2210  vec->capacity = tmp_sz;
2211  }
2212 
2213  CVEC_MEMMOVE(&vec->a[i+num], &vec->a[i], (vec->size-i)*sizeof(char*));
2214 
2215  CVEC_MEMMOVE(&vec->a[i], a, num*sizeof(char*));
2216  vec->size += num;
2217  return 1;
2218 }
2219 
2224 void cvec_replace_str(cvector_str* vec, cvec_sz i, char* a, char* ret)
2225 {
2226  if (ret)
2227  strcpy(ret, vec->a[i]);
2228  CVEC_FREE(vec->a[i]);
2229  vec->a[i] = CVEC_STRDUP(a);
2230 }
2231 
2237 void cvec_erase_str(cvector_str* vec, cvec_sz start, cvec_sz end)
2238 {
2239  cvec_sz i;
2240  cvec_sz d = end - start + 1;
2241  for (i=start; i<=end; i++) {
2242  CVEC_FREE(vec->a[i]);
2243  }
2244 
2245  CVEC_MEMMOVE(&vec->a[start], &vec->a[end+1], (vec->size-1-end)*sizeof(char*));
2246  vec->size -= d;
2247 }
2248 
2250 void cvec_remove_str(cvector_str* vec, cvec_sz start, cvec_sz end)
2251 {
2252  cvec_sz d = end - start + 1;
2253  CVEC_MEMMOVE(&vec->a[start], &vec->a[end+1], (vec->size-1-end)*sizeof(char*));
2254  vec->size -= d;
2255 }
2256 
2258 int cvec_reserve_str(cvector_str* vec, cvec_sz size)
2259 {
2260  char** tmp;
2261  if (vec->capacity < size) {
2262  if (!(tmp = (char**)CVEC_REALLOC(vec->a, sizeof(char*)*(size+CVEC_STR_START_SZ)))) {
2263  CVEC_ASSERT(tmp != NULL);
2264  return 0;
2265  }
2266  vec->a = tmp;
2267  vec->capacity = size + CVEC_STR_START_SZ;
2268  }
2269  return 1;
2270 }
2271 
2276 int cvec_set_cap_str(cvector_str* vec, cvec_sz size)
2277 {
2278  cvec_sz i;
2279  char** tmp;
2280  if (size < vec->size) {
2281  for(i=vec->size-1; i>size-1; i--) {
2282  CVEC_FREE(vec->a[i]);
2283  }
2284 
2285  vec->size = size;
2286  }
2287 
2288  if (!(tmp = (char**)CVEC_REALLOC(vec->a, sizeof(char*)*size))) {
2289  CVEC_ASSERT(tmp != NULL);
2290  return 0;
2291  }
2292  vec->a = tmp;
2293  vec->capacity = size;
2294  return 1;
2295 }
2296 
2298 void cvec_set_val_sz_str(cvector_str* vec, char* val)
2299 {
2300  cvec_sz i;
2301  for(i=0; i<vec->size; i++) {
2302  CVEC_FREE(vec->a[i]);
2303 
2304  /* not worth checking to me see commit msg aa0c5cf */
2305  vec->a[i] = CVEC_STRDUP(val);
2306  }
2307 }
2308 
2313 void cvec_set_val_cap_str(cvector_str* vec, char* val)
2314 {
2315  cvec_sz i;
2316  for (i=0; i<vec->capacity; i++) {
2317  if (i<vec->size) {
2318  CVEC_FREE(vec->a[i]);
2319  }
2320 
2321  vec->a[i] = CVEC_STRDUP(val);
2322  }
2323  vec->size = vec->capacity;
2324 }
2325 
2327 void cvec_clear_str(cvector_str* vec)
2328 {
2329  int i;
2330  for (i=0; i<vec->size; i++) {
2331  CVEC_FREE(vec->a[i]);
2332  }
2333 
2334  vec->size = 0;
2335 }
2336 
2339 void cvec_free_str_heap(void* vec)
2340 {
2341  cvec_sz i;
2342  cvector_str* tmp = (cvector_str*)vec;
2343  if (!tmp) return;
2344  for (i=0; i<tmp->size; i++) {
2345  CVEC_FREE(tmp->a[i]);
2346  }
2347 
2348  CVEC_FREE(tmp->a);
2349  CVEC_FREE(tmp);
2350 }
2351 
2353 void cvec_free_str(void* vec)
2354 {
2355  cvec_sz i;
2356  cvector_str* tmp = (cvector_str*)vec;
2357  for (i=0; i<tmp->size; i++) {
2358  CVEC_FREE(tmp->a[i]);
2359  }
2360 
2361  CVEC_FREE(tmp->a);
2362  tmp->size = 0;
2363  tmp->capacity = 0;
2364 }
2365 #endif
2366 
2367 #ifndef CVEC_NO_VOID
2368 
2370 
2371 #define CVEC_VOID_ALLOCATOR(x) ((x+1) * 2)
2372 
2401 cvector_void* cvec_void_heap(cvec_sz size, cvec_sz capacity, cvec_sz elem_sz, void(*elem_free)(void*), int(*elem_init)(void*, void*))
2402 {
2403  cvector_void* vec;
2404  if (!(vec = (cvector_void*)CVEC_MALLOC(sizeof(cvector_void)))) {
2405  CVEC_ASSERT(vec != NULL);
2406  return NULL;
2407  }
2408 
2409  vec->size = size;
2410  vec->capacity = (capacity > vec->size || (vec->size && capacity == vec->size)) ? capacity : vec->size + CVEC_VOID_START_SZ;
2411 
2412  vec->elem_size = elem_sz;
2413 
2414  if (!(vec->a = (cvec_u8*)CVEC_MALLOC(vec->capacity*elem_sz))) {
2415  CVEC_ASSERT(vec->a != NULL);
2416  CVEC_FREE(vec);
2417  return NULL;
2418  }
2419  /* not clearing to 0 here as in cvector_str because elem_free cannot be calling CVEC_FREE directly
2420  * since it takes the address of the element not the element itself */
2421 
2422  vec->elem_free = elem_free;
2423  vec->elem_init = elem_init;
2424 
2425  return vec;
2426 }
2427 
2432 cvector_void* cvec_init_void_heap(void* vals, cvec_sz num, cvec_sz elem_sz, void(*elem_free)(void*), int(*elem_init)(void*, void*))
2433 {
2434  cvector_void* vec;
2435  cvec_sz i;
2436 
2437  if (!(vec = (cvector_void*)CVEC_MALLOC(sizeof(cvector_void)))) {
2438  CVEC_ASSERT(vec != NULL);
2439  return NULL;
2440  }
2441 
2442  vec->elem_size = elem_sz;
2443 
2444  vec->capacity = num + CVEC_VOID_START_SZ;
2445  vec->size = num;
2446  if (!(vec->a = (cvec_u8*)CVEC_MALLOC(vec->capacity*elem_sz))) {
2447  CVEC_ASSERT(vec->a != NULL);
2448  CVEC_FREE(vec);
2449  return NULL;
2450  }
2451 
2452  if (elem_init) {
2453  for (i=0; i<num; ++i) {
2454  if (!elem_init(&vec->a[i*elem_sz], &((cvec_u8*)vals)[i*elem_sz])) {
2455  CVEC_ASSERT(0);
2456  CVEC_FREE(vec->a);
2457  CVEC_FREE(vec);
2458  return NULL;
2459  }
2460  }
2461  } else {
2462  CVEC_MEMMOVE(vec->a, vals, elem_sz*num);
2463  }
2464 
2465  vec->elem_free = elem_free;
2466  vec->elem_init = elem_init;
2467 
2468  return vec;
2469 }
2470 
2474 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*))
2475 {
2476  vec->size = size;
2477  vec->capacity = (capacity > vec->size || (vec->size && capacity == vec->size)) ? capacity : vec->size + CVEC_VOID_START_SZ;
2478 
2479  vec->elem_size = elem_sz;
2480 
2481  if (!(vec->a = (cvec_u8*)CVEC_MALLOC(vec->capacity*elem_sz))) {
2482  CVEC_ASSERT(vec->a != NULL);
2483  vec->size = vec->capacity = 0;
2484  return 0;
2485  }
2486 
2487  vec->elem_free = elem_free;
2488  vec->elem_init = elem_init;
2489 
2490  return 1;
2491 }
2492 
2496 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*))
2497 {
2498  cvec_sz i;
2499 
2500  vec->elem_size = elem_sz;
2501 
2502  vec->capacity = num + CVEC_VOID_START_SZ;
2503  vec->size = num;
2504  if (!(vec->a = (cvec_u8*)CVEC_MALLOC(vec->capacity*elem_sz))) {
2505  CVEC_ASSERT(vec->a != NULL);
2506  vec->size = vec->capacity = 0;
2507  return 0;
2508  }
2509 
2510  if (elem_init) {
2511  for (i=0; i<num; ++i) {
2512  if (!elem_init(&vec->a[i*elem_sz], &((cvec_u8*)vals)[i*elem_sz])) {
2513  CVEC_ASSERT(0);
2514  return 0;
2515  }
2516  }
2517  } else {
2518  CVEC_MEMMOVE(vec->a, vals, elem_sz*num);
2519  }
2520 
2521  vec->elem_free = elem_free;
2522  vec->elem_init = elem_init;
2523 
2524  return 1;
2525 }
2526 
2537 int cvec_copyc_void(void* dest, void* src)
2538 {
2539  cvector_void* vec1 = (cvector_void*)dest;
2540  cvector_void* vec2 = (cvector_void*)src;
2541 
2542  vec1->a = NULL;
2543  vec1->size = 0;
2544  vec1->capacity = 0;
2545 
2546  return cvec_copy_void(vec1, vec2);
2547 }
2548 
2558 int cvec_copy_void(cvector_void* dest, cvector_void* src)
2559 {
2560  int i;
2561  cvec_u8* tmp = NULL;
2562  if (!(tmp = (cvec_u8*)CVEC_REALLOC(dest->a, src->capacity*src->elem_size))) {
2563  CVEC_ASSERT(tmp != NULL);
2564  return 0;
2565  }
2566  dest->a = tmp;
2567 
2568  if (src->elem_init) {
2569  for (i=0; i<src->size; ++i) {
2570  if (!src->elem_init(&dest->a[i*src->elem_size], &src->a[i*src->elem_size])) {
2571  CVEC_ASSERT(0);
2572  return 0;
2573  }
2574  }
2575  } else {
2576  /* could use memcpy here since we know we just allocated dest->a */
2577  CVEC_MEMMOVE(dest->a, src->a, src->size*src->elem_size);
2578  }
2579 
2580  dest->size = src->size;
2581  dest->capacity = src->capacity;
2582  dest->elem_size = src->elem_size;
2583  dest->elem_free = src->elem_free;
2584  dest->elem_init = src->elem_init;
2585  return 1;
2586 }
2587 
2594 int cvec_push_void(cvector_void* vec, void* a)
2595 {
2596  cvec_u8* tmp;
2597  cvec_sz tmp_sz;
2598  if (vec->capacity == vec->size) {
2599  tmp_sz = CVEC_VOID_ALLOCATOR(vec->capacity);
2600  if (!(tmp = (cvec_u8*)CVEC_REALLOC(vec->a, vec->elem_size*tmp_sz))) {
2601  CVEC_ASSERT(tmp != NULL);
2602  return 0;
2603  }
2604  vec->a = tmp;
2605  vec->capacity = tmp_sz;
2606  }
2607  if (vec->elem_init) {
2608  if (!vec->elem_init(&vec->a[vec->size*vec->elem_size], a)) {
2609  CVEC_ASSERT(0);
2610  return 0;
2611  }
2612  } else {
2613  CVEC_MEMMOVE(&vec->a[vec->size*vec->elem_size], a, vec->elem_size);
2614  }
2615 
2616  vec->size++;
2617  return 1;
2618 }
2619 
2621 int cvec_pushm_void(cvector_void* vec, void* a)
2622 {
2623  cvec_u8* tmp;
2624  cvec_sz tmp_sz;
2625  if (vec->capacity == vec->size) {
2626  tmp_sz = CVEC_VOID_ALLOCATOR(vec->capacity);
2627  if (!(tmp = (cvec_u8*)CVEC_REALLOC(vec->a, vec->elem_size*tmp_sz))) {
2628  CVEC_ASSERT(tmp != NULL);
2629  return 0;
2630  }
2631  vec->a = tmp;
2632  vec->capacity = tmp_sz;
2633  }
2634  CVEC_MEMMOVE(&vec->a[vec->size*vec->elem_size], a, vec->elem_size);
2635 
2636  vec->size++;
2637  return 1;
2638 }
2639 
2640 
2646 void cvec_pop_void(cvector_void* vec, void* ret)
2647 {
2648  vec->size--;
2649  if (ret) {
2650  CVEC_MEMMOVE(ret, &vec->a[vec->size*vec->elem_size], vec->elem_size);
2651  }
2652  if (vec->elem_free) {
2653  vec->elem_free(&vec->a[vec->size*vec->elem_size]);
2654  }
2655 }
2656 
2658 void cvec_popm_void(cvector_void* vec, void* ret)
2659 {
2660  vec->size--;
2661  if (ret) {
2662  CVEC_MEMMOVE(ret, &vec->a[vec->size*vec->elem_size], vec->elem_size);
2663  }
2664 }
2665 
2667 void* cvec_back_void(cvector_void* vec)
2668 {
2669  return &vec->a[(vec->size-1)*vec->elem_size];
2670 }
2671 
2674 int cvec_extend_void(cvector_void* vec, cvec_sz num)
2675 {
2676  cvec_u8* tmp;
2677  cvec_sz tmp_sz;
2678  if (vec->capacity < vec->size + num) {
2679  tmp_sz = vec->capacity + num + CVEC_VOID_START_SZ;
2680  if (!(tmp = (cvec_u8*)CVEC_REALLOC(vec->a, vec->elem_size*tmp_sz))) {
2681  CVEC_ASSERT(tmp != NULL);
2682  return 0;
2683  }
2684  vec->a = tmp;
2685  vec->capacity = tmp_sz;
2686  }
2687 
2688  vec->size += num;
2689  return 1;
2690 }
2691 
2697 void* cvec_get_void(cvector_void* vec, cvec_sz i)
2698 {
2699  return &vec->a[i*vec->elem_size];
2700 }
2701 
2706 int cvec_insert_void(cvector_void* vec, cvec_sz i, void* a)
2707 {
2708  cvec_u8* tmp;
2709  cvec_sz tmp_sz;
2710  if (vec->capacity == vec->size) {
2711  tmp_sz = CVEC_VOID_ALLOCATOR(vec->capacity);
2712  if (!(tmp = (cvec_u8*)CVEC_REALLOC(vec->a, vec->elem_size*tmp_sz))) {
2713  CVEC_ASSERT(tmp != NULL);
2714  return 0;
2715  }
2716 
2717  vec->a = tmp;
2718  vec->capacity = tmp_sz;
2719  }
2720  CVEC_MEMMOVE(&vec->a[(i+1)*vec->elem_size], &vec->a[i*vec->elem_size], (vec->size-i)*vec->elem_size);
2721 
2722  if (vec->elem_init) {
2723  if (!vec->elem_init(&vec->a[i*vec->elem_size], a)) {
2724  CVEC_ASSERT(0);
2725  return 0;
2726  }
2727  } else {
2728  CVEC_MEMMOVE(&vec->a[i*vec->elem_size], a, vec->elem_size);
2729  }
2730 
2731  vec->size++;
2732  return 1;
2733 }
2734 
2736 int cvec_insertm_void(cvector_void* vec, cvec_sz i, void* a)
2737 {
2738  cvec_u8* tmp;
2739  cvec_sz tmp_sz;
2740  if (vec->capacity == vec->size) {
2741  tmp_sz = CVEC_VOID_ALLOCATOR(vec->capacity);
2742  if (!(tmp = (cvec_u8*)CVEC_REALLOC(vec->a, vec->elem_size*tmp_sz))) {
2743  CVEC_ASSERT(tmp != NULL);
2744  return 0;
2745  }
2746 
2747  vec->a = tmp;
2748  vec->capacity = tmp_sz;
2749  }
2750  CVEC_MEMMOVE(&vec->a[(i+1)*vec->elem_size], &vec->a[i*vec->elem_size], (vec->size-i)*vec->elem_size);
2751 
2752  CVEC_MEMMOVE(&vec->a[i*vec->elem_size], a, vec->elem_size);
2753 
2754  vec->size++;
2755  return 1;
2756 }
2757 
2765 int cvec_insert_array_void(cvector_void* vec, cvec_sz i, void* a, cvec_sz num)
2766 {
2767  cvec_u8* tmp;
2768  cvec_sz tmp_sz, j;
2769  if (vec->capacity < vec->size + num) {
2770  tmp_sz = vec->capacity + num + CVEC_VOID_START_SZ;
2771  if (!(tmp = (cvec_u8*)CVEC_REALLOC(vec->a, vec->elem_size*tmp_sz))) {
2772  CVEC_ASSERT(tmp != NULL);
2773  return 0;
2774  }
2775  vec->a = tmp;
2776  vec->capacity = tmp_sz;
2777  }
2778 
2779  CVEC_MEMMOVE(&vec->a[(i+num)*vec->elem_size], &vec->a[i*vec->elem_size], (vec->size-i)*vec->elem_size);
2780  if (vec->elem_init) {
2781  for (j=0; j<num; ++j) {
2782  if (!vec->elem_init(&vec->a[(j+i)*vec->elem_size], &((cvec_u8*)a)[j*vec->elem_size])) {
2783  CVEC_ASSERT(0);
2784  return 0;
2785  }
2786  }
2787  } else {
2788  CVEC_MEMMOVE(&vec->a[i*vec->elem_size], a, num*vec->elem_size);
2789  }
2790  vec->size += num;
2791  return 1;
2792 }
2793 
2795 int cvec_insert_arraym_void(cvector_void* vec, cvec_sz i, void* a, cvec_sz num)
2796 {
2797  cvec_u8* tmp;
2798  cvec_sz tmp_sz;
2799  if (vec->capacity < vec->size + num) {
2800  tmp_sz = vec->capacity + num + CVEC_VOID_START_SZ;
2801  if (!(tmp = (cvec_u8*)CVEC_REALLOC(vec->a, vec->elem_size*tmp_sz))) {
2802  CVEC_ASSERT(tmp != NULL);
2803  return 0;
2804  }
2805  vec->a = tmp;
2806  vec->capacity = tmp_sz;
2807  }
2808 
2809  CVEC_MEMMOVE(&vec->a[(i+num)*vec->elem_size], &vec->a[i*vec->elem_size], (vec->size-i)*vec->elem_size);
2810 
2811  CVEC_MEMMOVE(&vec->a[i*vec->elem_size], a, num*vec->elem_size);
2812  vec->size += num;
2813  return 1;
2814 }
2815 
2819 int cvec_replace_void(cvector_void* vec, cvec_sz i, void* a, void* ret)
2820 {
2821  if (ret) {
2822  CVEC_MEMMOVE(ret, &vec->a[i*vec->elem_size], vec->elem_size);
2823  } else if (vec->elem_free) {
2824  vec->elem_free(&vec->a[i*vec->elem_size]);
2825  }
2826 
2827  if (vec->elem_init) {
2828  if (!vec->elem_init(&vec->a[i*vec->elem_size], a)) {
2829  CVEC_ASSERT(0);
2830  return 0;
2831  }
2832  } else {
2833  CVEC_MEMMOVE(&vec->a[i*vec->elem_size], a, vec->elem_size);
2834  }
2835  return 1;
2836 }
2837 
2843 void cvec_replacem_void(cvector_void* vec, cvec_sz i, void* a, void* ret)
2844 {
2845  if (ret) {
2846  CVEC_MEMMOVE(ret, &vec->a[i*vec->elem_size], vec->elem_size);
2847  }
2848 
2849  CVEC_MEMMOVE(&vec->a[i*vec->elem_size], a, vec->elem_size);
2850 }
2851 
2857 void cvec_erase_void(cvector_void* vec, cvec_sz start, cvec_sz end)
2858 {
2859  cvec_sz i;
2860  cvec_sz d = end - start + 1;
2861  if (vec->elem_free) {
2862  for (i=start; i<=end; i++) {
2863  vec->elem_free(&vec->a[i*vec->elem_size]);
2864  }
2865  }
2866  CVEC_MEMMOVE(&vec->a[start*vec->elem_size], &vec->a[(end+1)*vec->elem_size], (vec->size-1-end)*vec->elem_size);
2867  vec->size -= d;
2868 }
2869 
2871 void cvec_remove_void(cvector_void* vec, cvec_sz start, cvec_sz end)
2872 {
2873  cvec_sz d = end - start + 1;
2874  CVEC_MEMMOVE(&vec->a[start*vec->elem_size], &vec->a[(end+1)*vec->elem_size], (vec->size-1-end)*vec->elem_size);
2875  vec->size -= d;
2876 }
2877 
2879 int cvec_reserve_void(cvector_void* vec, cvec_sz size)
2880 {
2881  cvec_u8* tmp;
2882  if (vec->capacity < size) {
2883  if (!(tmp = (cvec_u8*)CVEC_REALLOC(vec->a, vec->elem_size*(size+CVEC_VOID_START_SZ)))) {
2884  CVEC_ASSERT(tmp != NULL);
2885  return 0;
2886  }
2887  vec->a = tmp;
2888  vec->capacity = size + CVEC_VOID_START_SZ;
2889  }
2890  return 1;
2891 }
2892 
2897 int cvec_set_cap_void(cvector_void* vec, cvec_sz size)
2898 {
2899  cvec_sz i;
2900  cvec_u8* tmp;
2901  if (size < vec->size) {
2902  if (vec->elem_free) {
2903  for (i=vec->size-1; i>=size; i--) {
2904  vec->elem_free(&vec->a[i*vec->elem_size]);
2905  }
2906  }
2907  vec->size = size;
2908  }
2909 
2910  vec->capacity = size;
2911 
2912  if (!(tmp = (cvec_u8*)CVEC_REALLOC(vec->a, vec->elem_size*size))) {
2913  CVEC_ASSERT(tmp != NULL);
2914  return 0;
2915  }
2916  vec-> a = tmp;
2917  return 1;
2918 }
2919 
2921 int cvec_set_val_sz_void(cvector_void* vec, void* val)
2922 {
2923  cvec_sz i;
2924 
2925  if (vec->elem_free) {
2926  for(i=0; i<vec->size; i++) {
2927  vec->elem_free(&vec->a[i*vec->elem_size]);
2928  }
2929  }
2930 
2931  if (vec->elem_init) {
2932  for (i=0; i<vec->size; i++) {
2933  if (!vec->elem_init(&vec->a[i*vec->elem_size], val)) {
2934  CVEC_ASSERT(0);
2935  return 0;
2936  }
2937  }
2938  } else {
2939  for (i=0; i<vec->size; i++) {
2940  CVEC_MEMMOVE(&vec->a[i*vec->elem_size], val, vec->elem_size);
2941  }
2942  }
2943  return 1;
2944 }
2945 
2951 int cvec_set_val_cap_void(cvector_void* vec, void* val)
2952 {
2953  cvec_sz i;
2954  if (vec->elem_free) {
2955  for (i=0; i<vec->size; i++) {
2956  vec->elem_free(&vec->a[i*vec->elem_size]);
2957  }
2958  vec->size = vec->capacity;
2959  }
2960 
2961  if (vec->elem_init) {
2962  for (i=0; i<vec->capacity; i++) {
2963  if (!vec->elem_init(&vec->a[i*vec->elem_size], val)) {
2964  CVEC_ASSERT(0);
2965  return 0;
2966  }
2967  }
2968  } else {
2969  for (i=0; i<vec->capacity; i++) {
2970  CVEC_MEMMOVE(&vec->a[i*vec->elem_size], val, vec->elem_size);
2971  }
2972  }
2973  return 1;
2974 }
2975 
2978 void cvec_clear_void(cvector_void* vec)
2979 {
2980  cvec_sz i;
2981  if (vec->elem_free) {
2982  for (i=0; i<vec->size; ++i) {
2983  vec->elem_free(&vec->a[i*vec->elem_size]);
2984  }
2985  }
2986  vec->size = 0;
2987 }
2988 
2992 void cvec_free_void_heap(void* vec)
2993 {
2994  cvec_sz i;
2995  cvector_void* tmp = (cvector_void*)vec;
2996  if (!tmp) return;
2997  if (tmp->elem_free) {
2998  for (i=0; i<tmp->size; i++) {
2999  tmp->elem_free(&tmp->a[i*tmp->elem_size]);
3000  }
3001  }
3002  CVEC_FREE(tmp->a);
3003  CVEC_FREE(tmp);
3004 }
3005 
3007 void cvec_free_void(void* vec)
3008 {
3009  cvec_sz i;
3010  cvector_void* tmp = (cvector_void*)vec;
3011  if (tmp->elem_free) {
3012  for (i=0; i<tmp->size; i++) {
3013  tmp->elem_free(&tmp->a[i*tmp->elem_size]);
3014  }
3015  }
3016 
3017  CVEC_FREE(tmp->a);
3018 
3019  tmp->size = 0;
3020  tmp->capacity = 0;
3021 }
3022 
3202 #endif
3203 
3204 
3205 #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...
Definition: cvector_str.c:140
void cvec_clear_str(cvector_str *vec)
Clears the contents of vector (frees all strings) and sets size to 0.
Definition: cvector_str.c:495
#define CVEC_FREE(p)
Definition: cvector.h:71
cvector_d * cvec_d_heap(cvec_sz size, cvec_sz capacity)
Creates a new cvector_d on the heap.
Definition: cvector_d.c:39
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:250
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.
Definition: cvector_void.c:92
int cvec_set_val_sz_void(cvector_void *vec, void *val)
Set all size elements to val.
Definition: cvector_void.c:581
int cvec_insert_d(cvector_d *vec, cvec_sz i, double a)
Insert a at index i (0 based).
Definition: cvector_d.c:224
int cvec_insert_i(cvector_i *vec, cvec_sz i, int a)
Insert a at index i (0 based).
Definition: cvector_i.c:224
char * cvec_strdup(const char *str)
Useful utility function since strdup isn't in standard C.
Definition: cvector_str.c:35
int cvec_copyc_void(void *dest, void *src)
Makes dest a copy of src.
Definition: cvector_void.c:197
void cvec_free_i_heap(void *vec)
Frees everything so don't use vec after calling this.
Definition: cvector_i.c:348
int cvec_copy_str(cvector_str *dest, cvector_str *src)
Makes dest a copy of src.
Definition: cvector_str.c:190
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.
Definition: cvector_void.c:425
int cvec_copy_void(cvector_void *dest, cvector_void *src)
Makes dest a copy of src.
Definition: cvector_void.c:218
unsigned char cvec_u8
Definition: cvector.h:239
void cvec_free_i(void *vec)
Frees the internal array and sets size and capacity to 0.
Definition: cvector_i.c:357
void cvec_free_d(void *vec)
Frees the internal array and sets size and capacity to 0.
Definition: cvector_d.c:356
int cvec_reserve_void(cvector_void *vec, cvec_sz size)
Makes sure capacity >= size (the parameter not the member).
Definition: cvector_void.c:539
int cvec_set_cap_str(cvector_str *vec, cvec_sz size)
Set capacity to size.
Definition: cvector_str.c:444
#define CVEC_REALLOC(p, sz)
Definition: cvector.h:70
int cvec_pop_i(cvector_i *vec)
Remove and return the last element (size decreased 1).
Definition: cvector_i.c:189
int cvec_extend_str(cvector_str *vec, cvec_sz num)
Increase the size of the array num items.
Definition: cvector_str.c:270
void cvec_set_val_cap_str(cvector_str *vec, char *val)
Fills entire allocated array (capacity) with val.
Definition: cvector_str.c:481
int cvec_copyc_i(void *dest, void *src)
Makes dest a copy of src.
Definition: cvector_i.c:130
void cvec_erase_d(cvector_d *vec, cvec_sz start, cvec_sz end)
Erases elements from start to end inclusive.
Definition: cvector_d.c:283
int cvec_pushm_void(cvector_void *vec, void *a)
Same as push except no elem_init even if it's set.
Definition: cvector_void.c:281
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:271
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.
Definition: cvector_void.c:455
int cvec_copyc_str(void *dest, void *src)
Makes dest a copy of src.
Definition: cvector_str.c:169
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:63
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:250
void cvec_set_val_cap_d(cvector_d *vec, double val)
Fills entire allocated array (capacity) with val.
Definition: cvector_d.c:334
cvec_sz CVEC_I_START_SZ
Definition: cvector_i.c:29
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.
Definition: cvector_void.c:479
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:62
void cvec_remove_void(cvector_void *vec, cvec_sz start, cvec_sz end)
Same as erase except it does not call elem_free.
Definition: cvector_void.c:531
int cvec_copy_d(cvector_d *dest, cvector_d *src)
Makes dest a copy of src.
Definition: cvector_d.c:152
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...
Definition: cvector_void.c:156
int cvec_copy_i(cvector_i *dest, cvector_i *src)
Makes dest a copy of src.
Definition: cvector_i.c:151
int cvec_set_cap_i(cvector_i *vec, cvec_sz size)
Set capacity to size.
Definition: cvector_i.c:309
void * cvec_back_void(cvector_void *vec)
Return pointer to last element.
Definition: cvector_void.c:327
int cvec_reserve_d(cvector_d *vec, cvec_sz size)
Make sure capacity is at least size(parameter not member).
Definition: cvector_d.c:291
#define CVEC_MEMMOVE(dst, src, sz)
Definition: cvector.h:76
void cvec_erase_void(cvector_void *vec, cvec_sz start, cvec_sz end)
Erases elements from start to end inclusive.
Definition: cvector_void.c:517
int cvec_extend_d(cvector_d *vec, cvec_sz num)
Increase the size of the array num items.
Definition: cvector_d.c:202
int cvec_reserve_i(cvector_i *vec, cvec_sz size)
Make sure capacity is at least size(parameter not member).
Definition: cvector_i.c:291
int cvec_push_void(cvector_void *vec, void *a)
Append a to end of vector (size increased 1).
Definition: cvector_void.c:254
int cvec_copyc_d(void *dest, void *src)
Makes dest a copy of src.
Definition: cvector_d.c:131
int cvec_insertm_void(cvector_void *vec, cvec_sz i, void *a)
Same as insert but no elem_init even if defined.
Definition: cvector_void.c:396
#define CVEC_MALLOC(sz)
Definition: cvector.h:69
void cvec_set_val_sz_str(cvector_str *vec, char *val)
Sets all size elements to val.
Definition: cvector_str.c:466
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 ...
Definition: cvector_void.c:134
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.
Definition: cvector_str.c:341
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:271
#define CVEC_ASSERT(x)
Definition: cvector.h:81
int cvec_push_i(cvector_i *vec, int a)
Append a to end of vector (size increased 1).
Definition: cvector_i.c:170
void cvec_erase_i(cvector_i *vec, cvec_sz start, cvec_sz end)
Erases elements from start to end inclusive.
Definition: cvector_i.c:283
int cvec_insertm_str(cvector_str *vec, cvec_sz i, char *a)
Same as insert except no CVEC_STRDUP.
Definition: cvector_str.c:316
void cvec_set_val_sz_d(cvector_d *vec, double val)
Set all size elements to val.
Definition: cvector_d.c:325
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:105
void cvec_erase_str(cvector_str *vec, cvec_sz start, cvec_sz end)
Erases strings from start to end inclusive.
Definition: cvector_str.c:405
void cvec_free_str(void *vec)
Frees the internal array and sets size and capacity to 0.
Definition: cvector_str.c:521
void cvec_pop_void(cvector_void *vec, void *ret)
Remove the last element (size decreased 1).
Definition: cvector_void.c:306
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:88
int cvec_set_cap_void(cvector_void *vec, cvec_sz size)
Set capacity to size.
Definition: cvector_void.c:557
CVEC_SIZE_T cvec_sz
Definition: cvector.h:88
char ** cvec_back_str(cvector_str *vec)
Return pointer to last element.
Definition: cvector_str.c:262
cvector_i * cvec_i_heap(cvec_sz size, cvec_sz capacity)
Creates a new cvector_i on the heap.
Definition: cvector_i.c:39
int cvec_push_str(cvector_str *vec, char *a)
Append a to end of vector (size increased 1).
Definition: cvector_str.c:212
int cvec_insert_arraym_str(cvector_str *vec, cvec_sz i, char **a, cvec_sz num)
Same as insert_array except no CVEC_STRDUP.
Definition: cvector_str.c:367
int * cvec_back_i(cvector_i *vec)
Return pointer to last element.
Definition: cvector_i.c:195
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:89
void cvec_free_void(void *vec)
Frees the internal array and sets size and capacity to 0.
Definition: cvector_void.c:667
int cvec_set_cap_d(cvector_d *vec, cvec_sz size)
Set capacity to size.
Definition: cvector_d.c:309
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.
Definition: cvector_void.c:61
int cvec_pushm_str(cvector_str *vec, char *a)
same as push but without calling CVEC_STRDUP(a), m suffix is for "move"
Definition: cvector_str.c:231
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.
Definition: cvector_void.c:503
void cvec_replace_str(cvector_str *vec, cvec_sz i, char *a, char *ret)
Replace string at i with a.
Definition: cvector_str.c:392
cvec_sz CVEC_VOID_START_SZ
Definition: cvector_void.c:29
void cvec_pop_str(cvector_str *vec, char *ret)
Remove the last element (size decreased 1).
Definition: cvector_str.c:253
void cvec_free_str_heap(void *vec)
Frees contents (individual strings and array) and frees vector so don't use after calling this.
Definition: cvector_str.c:507
int cvec_set_val_cap_void(cvector_void *vec, void *val)
Fills entire allocated array (capacity) with val.
Definition: cvector_void.c:611
double * cvec_back_d(cvector_d *vec)
Return pointer to last element.
Definition: cvector_d.c:195
void cvec_free_void_heap(void *vec)
Frees everything so don't use vec after calling this.
Definition: cvector_void.c:652
int cvec_push_d(cvector_d *vec, double a)
Append a to end of vector (size increased 1).
Definition: cvector_d.c:171
void cvec_clear_i(cvector_i *vec)
Sets size to 0 (does not clear contents).
Definition: cvector_i.c:344
int cvec_reserve_str(cvector_str *vec, cvec_sz size)
Makes sure the vector capacity is >= size (parameter not member).
Definition: cvector_str.c:426
int cvec_extend_void(cvector_void *vec, cvec_sz num)
Increase the size of the array num items.
Definition: cvector_void.c:334
int cvec_insert_str(cvector_str *vec, cvec_sz i, char *a)
Insert a at index i (0 based).
Definition: cvector_str.c:293
#define CVEC_STRDUP
Definition: cvector.h:195
void * cvec_get_void(cvector_void *vec, cvec_sz i)
Return a void pointer to the ith element.
Definition: cvector_void.c:357
int cvec_extend_i(cvector_i *vec, cvec_sz num)
Increase the size of the array num items.
Definition: cvector_i.c:202
void cvec_set_val_cap_i(cvector_i *vec, int val)
Fills entire allocated array (capacity) with val.
Definition: cvector_i.c:335
cvector_str * cvec_str_heap(cvec_sz size, cvec_sz capacity)
Create a new cvector_str on the heap.
Definition: cvector_str.c:64
#define CVEC_SIZE_T
Definition: cvector.h:85
void cvec_remove_str(cvector_str *vec, cvec_sz start, cvec_sz end)
Same as erase except it does not call CVEC_FREE.
Definition: cvector_str.c:418
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...
Definition: cvector_str.c:120
void cvec_clear_d(cvector_d *vec)
Sets size to 0 (does not clear contents).
Definition: cvector_d.c:343
void cvec_set_val_sz_i(cvector_i *vec, int val)
Set all size elements to val.
Definition: cvector_i.c:326
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:91
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...
Definition: cvector_void.c:638
void cvec_free_d_heap(void *vec)
Frees everything so don't use vec after calling this.
Definition: cvector_d.c:347
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:106
double cvec_pop_d(cvector_d *vec)
Remove and return the last element (size decreased 1).
Definition: cvector_d.c:189
void cvec_popm_void(cvector_void *vec, void *ret)
Same as pop except no elem_free even if it's set.
Definition: cvector_void.c:318
int cvec_insert_void(cvector_void *vec, cvec_sz i, void *a)
Insert a at index i (0 based).
Definition: cvector_void.c:366
cvec_sz CVEC_STR_START_SZ
Definition: cvector_str.c:29
cvec_sz CVEC_D_START_SZ
Definition: cvector_d.c:29
#define CVEC_D_ALLOCATOR(x)
Definition: cvector_d.c:31
#define CVEC_I_ALLOCATOR(x)
Definition: cvector_i.c:31
#define CVEC_STR_ALLOCATOR(x)
Definition: cvector_str.c:31
#define CVEC_VOID_ALLOCATOR(x)
Definition: cvector_void.c:31
Data structure for double vector.
Definition: cvector.h:143
cvec_sz size
Current size (amount you use when manipulating array directly).
Definition: cvector.h:145
cvec_sz capacity
Allocated size of array; always >= size.
Definition: cvector.h:146
double * a
Array.
Definition: cvector.h:144
Data structure for int vector.
Definition: cvector.h:100
cvec_sz size
Current size (amount you use when manipulating array directly).
Definition: cvector.h:102
int * a
Array.
Definition: cvector.h:101
cvec_sz capacity
Allocated size of array; always >= size.
Definition: cvector.h:103
Data structure for string vector.
Definition: cvector.h:186
cvec_sz capacity
Allocated size of array; always >= size.
Definition: cvector.h:189
cvec_sz size
Current size (amount you use when manipulating array directly).
Definition: cvector.h:188
char ** a
Array.
Definition: cvector.h:187
Data structure for generic type (cast to void) vectors.
Definition: cvector.h:243
cvec_sz size
Current size (amount you should use when manipulating array directly).
Definition: cvector.h:245
cvec_sz elem_size
Size in bytes of type stored (sizeof(T) where T is type).
Definition: cvector.h:247
cvec_sz capacity
Allocated size of array; always >= size.
Definition: cvector.h:246
void(* elem_free)(void *)
Definition: cvector.h:248
cvec_u8 * a
Array.
Definition: cvector.h:244
int(* elem_init)(void *, void *)
Definition: cvector.h:249