CVector  4.1.0
A C++ style vector library in strict ANSI C (C89)
cvector_macro.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 #ifndef CVECTOR_MACRO_H
36 #define CVECTOR_MACRO_H
37 
38 #if defined(CVEC_MALLOC) && defined(CVEC_FREE) && defined(CVEC_REALLOC)
39 /* ok */
40 #elif !defined(CVEC_MALLOC) && !defined(CVEC_FREE) && !defined(CVEC_REALLOC)
41 /* ok */
42 #else
43 #error "Must define all or none of CVEC_MALLOC, CVEC_FREE, and CVEC_REALLOC."
44 #endif
45 
46 #ifndef CVEC_MALLOC
47 #define CVEC_MALLOC(sz) malloc(sz)
48 #define CVEC_REALLOC(p, sz) realloc(p, sz)
49 #define CVEC_FREE(p) free(p)
50 #endif
51 
52 #ifndef CVEC_MEMMOVE
53 #include <string.h>
54 #define CVEC_MEMMOVE(dst, src, sz) memmove(dst, src, sz)
55 #endif
56 
57 #ifndef CVEC_ASSERT
58 #include <assert.h>
59 #define CVEC_ASSERT(x) assert(x)
60 #endif
61 
62 #ifndef CVEC_SIZE_TYPE
63 #define CVEC_SIZE_TYPE size_t
64 #endif
65 
66 #ifndef CVEC_SZ
67 #define CVEC_SZ
69 #endif
70 
71 
72 /*
73  User can optionally wrap CVEC_NEW_DECLS(2) with extern "C"
74  since it's not part of the macro
75 */
76 
77 #define CVEC_NEW_DECLS(TYPE) \
78  typedef struct cvector_##TYPE { \
79  TYPE* a; \
80  cvec_sz size; \
81  cvec_sz capacity; \
82  } cvector_##TYPE; \
83  \
84  extern cvec_sz CVEC_##TYPE##_SZ; \
85  \
86  int cvec_##TYPE(cvector_##TYPE* vec, cvec_sz size, cvec_sz capacity); \
87  int cvec_init_##TYPE(cvector_##TYPE* vec, TYPE* vals, cvec_sz num); \
88  \
89  cvector_##TYPE* cvec_##TYPE##_heap(cvec_sz size, cvec_sz capacity); \
90  cvector_##TYPE* cvec_init_##TYPE##_heap(TYPE* vals, cvec_sz num); \
91  \
92  int cvec_copyc_##TYPE(void* dest, void* src); \
93  int cvec_copy_##TYPE(cvector_##TYPE* dest, cvector_##TYPE* src); \
94  \
95  int cvec_push_##TYPE(cvector_##TYPE* vec, TYPE a); \
96  TYPE cvec_pop_##TYPE(cvector_##TYPE* vec); \
97  \
98  int cvec_extend_##TYPE(cvector_##TYPE* vec, cvec_sz num); \
99  int cvec_insert_##TYPE(cvector_##TYPE* vec, cvec_sz i, TYPE a); \
100  int cvec_insert_array_##TYPE(cvector_##TYPE* vec, cvec_sz i, TYPE* a, cvec_sz num); \
101  TYPE cvec_replace_##TYPE(cvector_##TYPE* vec, cvec_sz i, TYPE a); \
102  void cvec_erase_##TYPE(cvector_##TYPE* vec, cvec_sz start, cvec_sz end); \
103  int cvec_reserve_##TYPE(cvector_##TYPE* vec, cvec_sz size); \
104  int cvec_set_cap_##TYPE(cvector_##TYPE* vec, cvec_sz size); \
105  void cvec_set_val_sz_##TYPE(cvector_##TYPE* vec, TYPE val); \
106  void cvec_set_val_cap_##TYPE(cvector_##TYPE* vec, TYPE val); \
107  \
108  TYPE* cvec_back_##TYPE(cvector_##TYPE* vec); \
109  \
110  void cvec_clear_##TYPE(cvector_##TYPE* vec); \
111  void cvec_free_##TYPE##_heap(void* vec); \
112  void cvec_free_##TYPE(void* vec);
113 
114 #define CVEC_NEW_DEFS(TYPE, RESIZE_MACRO) \
115  cvec_sz CVEC_##TYPE##_SZ = 50; \
116  \
117  cvector_##TYPE* cvec_##TYPE##_heap(cvec_sz size, cvec_sz capacity) \
118  { \
119  cvector_##TYPE* vec; \
120  if (!(vec = (cvector_##TYPE*)CVEC_MALLOC(sizeof(cvector_##TYPE)))) { \
121  CVEC_ASSERT(vec != NULL); \
122  return NULL; \
123  } \
124  \
125  vec->size = size; \
126  vec->capacity = (capacity > vec->size || (vec->size && capacity == vec->size)) \
127  ? capacity \
128  : vec->size + CVEC_##TYPE##_SZ; \
129  \
130  if (!(vec->a = (TYPE*)CVEC_MALLOC(vec->capacity * sizeof(TYPE)))) { \
131  CVEC_ASSERT(vec->a != NULL); \
132  CVEC_FREE(vec); \
133  return NULL; \
134  } \
135  \
136  return vec; \
137  } \
138  \
139  cvector_##TYPE* cvec_init_##TYPE##_heap(TYPE* vals, cvec_sz num) \
140  { \
141  cvector_##TYPE* vec; \
142  \
143  if (!(vec = (cvector_##TYPE*)CVEC_MALLOC(sizeof(cvector_##TYPE)))) { \
144  CVEC_ASSERT(vec != NULL); \
145  return NULL; \
146  } \
147  \
148  vec->capacity = num + CVEC_##TYPE##_SZ; \
149  vec->size = num; \
150  if (!(vec->a = (TYPE*)CVEC_MALLOC(vec->capacity * sizeof(TYPE)))) { \
151  CVEC_ASSERT(vec->a != NULL); \
152  CVEC_FREE(vec); \
153  return NULL; \
154  } \
155  \
156  CVEC_MEMMOVE(vec->a, vals, sizeof(TYPE) * num); \
157  \
158  return vec; \
159  } \
160  \
161  int cvec_##TYPE(cvector_##TYPE* vec, cvec_sz size, cvec_sz capacity) \
162  { \
163  vec->size = size; \
164  vec->capacity = (capacity > vec->size || (vec->size && capacity == vec->size)) \
165  ? capacity \
166  : vec->size + CVEC_##TYPE##_SZ; \
167  \
168  if (!(vec->a = (TYPE*)CVEC_MALLOC(vec->capacity * sizeof(TYPE)))) { \
169  CVEC_ASSERT(vec->a != NULL); \
170  vec->size = vec->capacity = 0; \
171  return 0; \
172  } \
173  \
174  return 1; \
175  } \
176  \
177  int cvec_init_##TYPE(cvector_##TYPE* vec, TYPE* vals, cvec_sz num) \
178  { \
179  vec->capacity = num + CVEC_##TYPE##_SZ; \
180  vec->size = num; \
181  if (!(vec->a = (TYPE*)CVEC_MALLOC(vec->capacity * sizeof(TYPE)))) { \
182  CVEC_ASSERT(vec->a != NULL); \
183  vec->size = vec->capacity = 0; \
184  return 0; \
185  } \
186  \
187  CVEC_MEMMOVE(vec->a, vals, sizeof(TYPE) * num); \
188  \
189  return 1; \
190  } \
191  \
192  int cvec_copyc_##TYPE(void* dest, void* src) \
193  { \
194  cvector_##TYPE* vec1 = (cvector_##TYPE*)dest; \
195  cvector_##TYPE* vec2 = (cvector_##TYPE*)src; \
196  \
197  vec1->a = NULL; \
198  vec1->size = 0; \
199  vec1->capacity = 0; \
200  \
201  return cvec_copy_##TYPE(vec1, vec2); \
202  } \
203  \
204  int cvec_copy_##TYPE(cvector_##TYPE* dest, cvector_##TYPE* src) \
205  { \
206  TYPE* tmp = NULL; \
207  if (!(tmp = (TYPE*)CVEC_REALLOC(dest->a, src->capacity*sizeof(TYPE)))) { \
208  CVEC_ASSERT(tmp != NULL); \
209  return 0; \
210  } \
211  dest->a = tmp; \
212  \
213  CVEC_MEMMOVE(dest->a, src->a, src->size*sizeof(TYPE)); \
214  dest->size = src->size; \
215  dest->capacity = src->capacity; \
216  return 1; \
217  } \
218  \
219  int cvec_push_##TYPE(cvector_##TYPE* vec, TYPE a) \
220  { \
221  TYPE* tmp; \
222  cvec_sz tmp_sz; \
223  if (vec->capacity > vec->size) { \
224  vec->a[vec->size++] = a; \
225  } else { \
226  tmp_sz = RESIZE_MACRO(vec->capacity); \
227  if (!(tmp = (TYPE*)CVEC_REALLOC(vec->a, sizeof(TYPE) * tmp_sz))) { \
228  CVEC_ASSERT(tmp != NULL); \
229  return 0; \
230  } \
231  vec->a = tmp; \
232  vec->a[vec->size++] = a; \
233  vec->capacity = tmp_sz; \
234  } \
235  return 1; \
236  } \
237  \
238  TYPE cvec_pop_##TYPE(cvector_##TYPE* vec) { return vec->a[--vec->size]; } \
239  \
240  TYPE* cvec_back_##TYPE(cvector_##TYPE* vec) { return &vec->a[vec->size - 1]; } \
241  \
242  int cvec_extend_##TYPE(cvector_##TYPE* vec, cvec_sz num) \
243  { \
244  TYPE* tmp; \
245  cvec_sz tmp_sz; \
246  if (vec->capacity < vec->size + num) { \
247  tmp_sz = vec->capacity + num + CVEC_##TYPE##_SZ; \
248  if (!(tmp = (TYPE*)CVEC_REALLOC(vec->a, sizeof(TYPE) * tmp_sz))) { \
249  CVEC_ASSERT(tmp != NULL); \
250  return 0; \
251  } \
252  vec->a = tmp; \
253  vec->capacity = tmp_sz; \
254  } \
255  \
256  vec->size += num; \
257  return 1; \
258  } \
259  \
260  int cvec_insert_##TYPE(cvector_##TYPE* vec, cvec_sz i, TYPE a) \
261  { \
262  TYPE* tmp; \
263  cvec_sz tmp_sz; \
264  if (vec->capacity > vec->size) { \
265  CVEC_MEMMOVE(&vec->a[i + 1], &vec->a[i], (vec->size - i) * sizeof(TYPE)); \
266  vec->a[i] = a; \
267  } else { \
268  tmp_sz = RESIZE_MACRO(vec->capacity); \
269  if (!(tmp = (TYPE*)CVEC_REALLOC(vec->a, sizeof(TYPE) * tmp_sz))) { \
270  CVEC_ASSERT(tmp != NULL); \
271  return 0; \
272  } \
273  vec->a = tmp; \
274  CVEC_MEMMOVE(&vec->a[i + 1], &vec->a[i], (vec->size - i) * sizeof(TYPE)); \
275  vec->a[i] = a; \
276  vec->capacity = tmp_sz; \
277  } \
278  \
279  vec->size++; \
280  return 1; \
281  } \
282  \
283  int cvec_insert_array_##TYPE(cvector_##TYPE* vec, cvec_sz i, TYPE* a, cvec_sz num) \
284  { \
285  TYPE* tmp; \
286  cvec_sz tmp_sz; \
287  if (vec->capacity < vec->size + num) { \
288  tmp_sz = vec->capacity + num + CVEC_##TYPE##_SZ; \
289  if (!(tmp = (TYPE*)CVEC_REALLOC(vec->a, sizeof(TYPE) * tmp_sz))) { \
290  CVEC_ASSERT(tmp != NULL); \
291  return 0; \
292  } \
293  vec->a = tmp; \
294  vec->capacity = tmp_sz; \
295  } \
296  \
297  CVEC_MEMMOVE(&vec->a[i + num], &vec->a[i], (vec->size - i) * sizeof(TYPE)); \
298  CVEC_MEMMOVE(&vec->a[i], a, num * sizeof(TYPE)); \
299  vec->size += num; \
300  return 1; \
301  } \
302  \
303  TYPE cvec_replace_##TYPE(cvector_##TYPE* vec, cvec_sz i, TYPE a) \
304  { \
305  TYPE tmp = vec->a[i]; \
306  vec->a[i] = a; \
307  return tmp; \
308  } \
309  \
310  void cvec_erase_##TYPE(cvector_##TYPE* vec, cvec_sz start, cvec_sz end) \
311  { \
312  cvec_sz d = end - start + 1; \
313  CVEC_MEMMOVE(&vec->a[start], &vec->a[end + 1], (vec->size - 1 - end) * sizeof(TYPE)); \
314  vec->size -= d; \
315  } \
316  \
317  int cvec_reserve_##TYPE(cvector_##TYPE* vec, cvec_sz size) \
318  { \
319  TYPE* tmp; \
320  if (vec->capacity < size) { \
321  if (!(tmp = (TYPE*)CVEC_REALLOC(vec->a, sizeof(TYPE) * (size + CVEC_##TYPE##_SZ)))) { \
322  CVEC_ASSERT(tmp != NULL); \
323  return 0; \
324  } \
325  vec->a = tmp; \
326  vec->capacity = size + CVEC_##TYPE##_SZ; \
327  } \
328  return 1; \
329  } \
330  \
331  int cvec_set_cap_##TYPE(cvector_##TYPE* vec, cvec_sz size) \
332  { \
333  TYPE* tmp; \
334  if (size < vec->size) { \
335  vec->size = size; \
336  } \
337  \
338  if (!(tmp = (TYPE*)CVEC_REALLOC(vec->a, sizeof(TYPE) * size))) { \
339  CVEC_ASSERT(tmp != NULL); \
340  return 0; \
341  } \
342  vec->a = tmp; \
343  vec->capacity = size; \
344  return 1; \
345  } \
346  \
347  void cvec_set_val_sz_##TYPE(cvector_##TYPE* vec, TYPE val) \
348  { \
349  cvec_sz i; \
350  for (i = 0; i < vec->size; i++) { \
351  vec->a[i] = val; \
352  } \
353  } \
354  \
355  void cvec_set_val_cap_##TYPE(cvector_##TYPE* vec, TYPE val) \
356  { \
357  cvec_sz i; \
358  for (i = 0; i < vec->capacity; i++) { \
359  vec->a[i] = val; \
360  } \
361  } \
362  \
363  void cvec_clear_##TYPE(cvector_##TYPE* vec) { vec->size = 0; } \
364  \
365  void cvec_free_##TYPE##_heap(void* vec) \
366  { \
367  cvector_##TYPE* tmp = (cvector_##TYPE*)vec; \
368  if (!tmp) return; \
369  CVEC_FREE(tmp->a); \
370  CVEC_FREE(tmp); \
371  } \
372  \
373  void cvec_free_##TYPE(void* vec) \
374  { \
375  cvector_##TYPE* tmp = (cvector_##TYPE*)vec; \
376  CVEC_FREE(tmp->a); \
377  tmp->size = 0; \
378  tmp->capacity = 0; \
379  }
380 
381 #define CVEC_NEW_DECLS2(TYPE) \
382  typedef struct cvector_##TYPE { \
383  TYPE* a; \
384  cvec_sz size; \
385  cvec_sz capacity; \
386  void (*elem_free)(void*); \
387  int (*elem_init)(void*, void*); \
388  } cvector_##TYPE; \
389  \
390  extern cvec_sz CVEC_##TYPE##_SZ; \
391  \
392  int cvec_##TYPE(cvector_##TYPE* vec, cvec_sz size, cvec_sz capacity, void (*elem_free)(void*), \
393  int (*elem_init)(void*, void*)); \
394  int cvec_init_##TYPE(cvector_##TYPE* vec, TYPE* vals, cvec_sz num, void (*elem_free)(void*), \
395  int (*elem_init)(void*, void*)); \
396  \
397  cvector_##TYPE* cvec_##TYPE##_heap(cvec_sz size, cvec_sz capacity, void (*elem_free)(void*), \
398  int (*elem_init)(void*, void*)); \
399  cvector_##TYPE* cvec_init_##TYPE##_heap(TYPE* vals, cvec_sz num, void (*elem_free)(void*), \
400  int (*elem_init)(void*, void*)); \
401  \
402  int cvec_copyc_##TYPE(void* dest, void* src); \
403  int cvec_copy_##TYPE(cvector_##TYPE* dest, cvector_##TYPE* src); \
404  \
405  int cvec_push_##TYPE(cvector_##TYPE* vec, TYPE* val); \
406  void cvec_pop_##TYPE(cvector_##TYPE* vec, TYPE* ret); \
407  \
408  int cvec_pushm_##TYPE(cvector_##TYPE* vec, TYPE* a); \
409  void cvec_popm_##TYPE(cvector_##TYPE* vec, TYPE* ret); \
410  int cvec_insertm_##TYPE(cvector_##TYPE* vec, cvec_sz i, TYPE* a); \
411  int cvec_insert_arraym_##TYPE(cvector_##TYPE* vec, cvec_sz i, TYPE* a, cvec_sz num); \
412  void cvec_replacem_##TYPE(cvector_##TYPE* vec, cvec_sz i, TYPE* a, TYPE* ret); \
413  \
414  int cvec_extend_##TYPE(cvector_##TYPE* vec, cvec_sz num); \
415  int cvec_insert_##TYPE(cvector_##TYPE* vec, cvec_sz i, TYPE* a); \
416  int cvec_insert_array_##TYPE(cvector_##TYPE* vec, cvec_sz i, TYPE* a, cvec_sz num); \
417  int cvec_replace_##TYPE(cvector_##TYPE* vec, cvec_sz i, TYPE* a, TYPE* ret); \
418  void cvec_erase_##TYPE(cvector_##TYPE* vec, cvec_sz start, cvec_sz end); \
419  void cvec_remove_##TYPE(cvector_##TYPE* vec, cvec_sz start, cvec_sz end); \
420  int cvec_reserve_##TYPE(cvector_##TYPE* vec, cvec_sz size); \
421  int cvec_set_cap_##TYPE(cvector_##TYPE* vec, cvec_sz size); \
422  int cvec_set_val_sz_##TYPE(cvector_##TYPE* vec, TYPE* val); \
423  int cvec_set_val_cap_##TYPE(cvector_##TYPE* vec, TYPE* val); \
424  \
425  TYPE* cvec_back_##TYPE(cvector_##TYPE* vec); \
426  \
427  void cvec_clear_##TYPE(cvector_##TYPE* vec); \
428  void cvec_free_##TYPE##_heap(void* vec); \
429  void cvec_free_##TYPE(void* vec);
430 
431 #define CVEC_NEW_DEFS2(TYPE, RESIZE_MACRO) \
432  cvec_sz CVEC_##TYPE##_SZ = 20; \
433  \
434  cvector_##TYPE* cvec_##TYPE##_heap(cvec_sz size, cvec_sz capacity, void (*elem_free)(void*), \
435  int (*elem_init)(void*, void*)) \
436  { \
437  cvector_##TYPE* vec; \
438  if (!(vec = (cvector_##TYPE*)CVEC_MALLOC(sizeof(cvector_##TYPE)))) { \
439  CVEC_ASSERT(vec != NULL); \
440  return NULL; \
441  } \
442  \
443  vec->size = size; \
444  vec->capacity = (capacity > vec->size || (vec->size && capacity == vec->size)) \
445  ? capacity \
446  : vec->size + CVEC_##TYPE##_SZ; \
447  \
448  if (!(vec->a = (TYPE*)CVEC_MALLOC(vec->capacity * sizeof(TYPE)))) { \
449  CVEC_ASSERT(vec->a != NULL); \
450  CVEC_FREE(vec); \
451  return NULL; \
452  } \
453  \
454  vec->elem_free = elem_free; \
455  vec->elem_init = elem_init; \
456  \
457  return vec; \
458  } \
459  \
460  cvector_##TYPE* cvec_init_##TYPE##_heap(TYPE* vals, cvec_sz num, void (*elem_free)(void*), \
461  int (*elem_init)(void*, void*)) \
462  { \
463  cvector_##TYPE* vec; \
464  cvec_sz i; \
465  \
466  if (!(vec = (cvector_##TYPE*)CVEC_MALLOC(sizeof(cvector_##TYPE)))) { \
467  CVEC_ASSERT(vec != NULL); \
468  return NULL; \
469  } \
470  \
471  vec->capacity = num + CVEC_##TYPE##_SZ; \
472  vec->size = num; \
473  if (!(vec->a = (TYPE*)CVEC_MALLOC(vec->capacity * sizeof(TYPE)))) { \
474  CVEC_ASSERT(vec->a != NULL); \
475  CVEC_FREE(vec); \
476  return NULL; \
477  } \
478  \
479  if (elem_init) { \
480  for (i = 0; i < num; ++i) { \
481  if (!elem_init(&vec->a[i], &vals[i])) { \
482  CVEC_ASSERT(0); \
483  CVEC_FREE(vec->a); \
484  CVEC_FREE(vec); \
485  return NULL; \
486  } \
487  } \
488  } else { \
489  CVEC_MEMMOVE(vec->a, vals, sizeof(TYPE) * num); \
490  } \
491  \
492  vec->elem_free = elem_free; \
493  vec->elem_init = elem_init; \
494  \
495  return vec; \
496  } \
497  \
498  int cvec_##TYPE(cvector_##TYPE* vec, cvec_sz size, cvec_sz capacity, void (*elem_free)(void*), \
499  int (*elem_init)(void*, void*)) \
500  { \
501  vec->size = size; \
502  vec->capacity = (capacity > vec->size || (vec->size && capacity == vec->size)) \
503  ? capacity \
504  : vec->size + CVEC_##TYPE##_SZ; \
505  \
506  if (!(vec->a = (TYPE*)CVEC_MALLOC(vec->capacity * sizeof(TYPE)))) { \
507  CVEC_ASSERT(vec->a != NULL); \
508  vec->size = vec->capacity = 0; \
509  return 0; \
510  } \
511  \
512  vec->elem_free = elem_free; \
513  vec->elem_init = elem_init; \
514  \
515  return 1; \
516  } \
517  \
518  int cvec_init_##TYPE(cvector_##TYPE* vec, TYPE* vals, cvec_sz num, void (*elem_free)(void*), \
519  int (*elem_init)(void*, void*)) \
520  { \
521  cvec_sz i; \
522  \
523  vec->capacity = num + CVEC_##TYPE##_SZ; \
524  vec->size = num; \
525  if (!(vec->a = (TYPE*)CVEC_MALLOC(vec->capacity * sizeof(TYPE)))) { \
526  CVEC_ASSERT(vec->a != NULL); \
527  vec->size = vec->capacity = 0; \
528  return 0; \
529  } \
530  \
531  if (elem_init) { \
532  for (i = 0; i < num; ++i) { \
533  if (!elem_init(&vec->a[i], &vals[i])) { \
534  CVEC_ASSERT(0); \
535  return 0; \
536  } \
537  } \
538  } else { \
539  CVEC_MEMMOVE(vec->a, vals, sizeof(TYPE) * num); \
540  } \
541  \
542  vec->elem_free = elem_free; \
543  vec->elem_init = elem_init; \
544  \
545  return 1; \
546  } \
547  \
548  int cvec_copyc_##TYPE(void* dest, void* src) \
549  { \
550  cvector_##TYPE* vec1 = (cvector_##TYPE*)dest; \
551  cvector_##TYPE* vec2 = (cvector_##TYPE*)src; \
552  \
553  vec1->a = NULL; \
554  vec1->size = 0; \
555  vec1->capacity = 0; \
556  \
557  return cvec_copy_##TYPE(vec1, vec2); \
558  } \
559  \
560  int cvec_copy_##TYPE(cvector_##TYPE* dest, cvector_##TYPE* src) \
561  { \
562  int i; \
563  TYPE* tmp = NULL; \
564  if (!(tmp = (TYPE*)CVEC_REALLOC(dest->a, src->capacity*sizeof(TYPE)))) { \
565  CVEC_ASSERT(tmp != NULL); \
566  return 0; \
567  } \
568  dest->a = tmp; \
569  \
570  if (src->elem_init) { \
571  for (i=0; i<src->size; ++i) { \
572  if (!src->elem_init(&dest->a[i], &src->a[i])) { \
573  CVEC_ASSERT(0); \
574  return 0; \
575  } \
576  } \
577  } else { \
578  CVEC_MEMMOVE(dest->a, src->a, src->size*sizeof(TYPE)); \
579  } \
580  \
581  dest->size = src->size; \
582  dest->capacity = src->capacity; \
583  dest->elem_free = src->elem_free; \
584  dest->elem_init = src->elem_init; \
585  return 1; \
586  } \
587  \
588  int cvec_push_##TYPE(cvector_##TYPE* vec, TYPE* a) \
589  { \
590  TYPE* tmp; \
591  cvec_sz tmp_sz; \
592  if (vec->capacity == vec->size) { \
593  tmp_sz = RESIZE_MACRO(vec->capacity); \
594  if (!(tmp = (TYPE*)CVEC_REALLOC(vec->a, sizeof(TYPE) * tmp_sz))) { \
595  CVEC_ASSERT(tmp != NULL); \
596  return 0; \
597  } \
598  vec->a = tmp; \
599  vec->capacity = tmp_sz; \
600  } \
601  if (vec->elem_init) { \
602  if (!vec->elem_init(&vec->a[vec->size], a)) { \
603  CVEC_ASSERT(0); \
604  return 0; \
605  } \
606  } else { \
607  CVEC_MEMMOVE(&vec->a[vec->size], a, sizeof(TYPE)); \
608  } \
609  \
610  vec->size++; \
611  return 1; \
612  } \
613  \
614  int cvec_pushm_##TYPE(cvector_##TYPE* vec, TYPE* a) \
615  { \
616  TYPE* tmp; \
617  cvec_sz tmp_sz; \
618  if (vec->capacity == vec->size) { \
619  tmp_sz = RESIZE_MACRO(vec->capacity); \
620  if (!(tmp = (TYPE*)CVEC_REALLOC(vec->a, sizeof(TYPE) * tmp_sz))) { \
621  CVEC_ASSERT(tmp != NULL); \
622  return 0; \
623  } \
624  vec->a = tmp; \
625  vec->capacity = tmp_sz; \
626  } \
627  CVEC_MEMMOVE(&vec->a[vec->size], a, sizeof(TYPE)); \
628  \
629  vec->size++; \
630  return 1; \
631  } \
632  \
633  void cvec_pop_##TYPE(cvector_##TYPE* vec, TYPE* ret) \
634  { \
635  if (ret) { \
636  CVEC_MEMMOVE(ret, &vec->a[--vec->size], sizeof(TYPE)); \
637  } else { \
638  vec->size--; \
639  } \
640  \
641  if (vec->elem_free) { \
642  vec->elem_free(&vec->a[vec->size]); \
643  } \
644  } \
645  \
646  void cvec_popm_##TYPE(cvector_##TYPE* vec, TYPE* ret) \
647  { \
648  vec->size--; \
649  if (ret) { \
650  CVEC_MEMMOVE(ret, &vec->a[vec->size], sizeof(TYPE)); \
651  } \
652  } \
653  \
654  TYPE* cvec_back_##TYPE(cvector_##TYPE* vec) { return &vec->a[vec->size - 1]; } \
655  \
656  int cvec_extend_##TYPE(cvector_##TYPE* vec, cvec_sz num) \
657  { \
658  TYPE* tmp; \
659  cvec_sz tmp_sz; \
660  if (vec->capacity < vec->size + num) { \
661  tmp_sz = vec->capacity + num + CVEC_##TYPE##_SZ; \
662  if (!(tmp = (TYPE*)CVEC_REALLOC(vec->a, sizeof(TYPE) * tmp_sz))) { \
663  CVEC_ASSERT(tmp != NULL); \
664  return 0; \
665  } \
666  vec->a = tmp; \
667  vec->capacity = tmp_sz; \
668  } \
669  \
670  vec->size += num; \
671  return 1; \
672  } \
673  \
674  int cvec_insert_##TYPE(cvector_##TYPE* vec, cvec_sz i, TYPE* a) \
675  { \
676  TYPE* tmp; \
677  cvec_sz tmp_sz; \
678  if (vec->capacity == vec->size) { \
679  tmp_sz = RESIZE_MACRO(vec->capacity); \
680  if (!(tmp = (TYPE*)CVEC_REALLOC(vec->a, sizeof(TYPE) * tmp_sz))) { \
681  CVEC_ASSERT(tmp != NULL); \
682  return 0; \
683  } \
684  \
685  vec->a = tmp; \
686  vec->capacity = tmp_sz; \
687  } \
688  CVEC_MEMMOVE(&vec->a[i + 1], &vec->a[i], (vec->size - i) * sizeof(TYPE)); \
689  \
690  if (vec->elem_init) { \
691  if (!vec->elem_init(&vec->a[i], a)) { \
692  CVEC_ASSERT(0); \
693  return 0; \
694  } \
695  } else { \
696  CVEC_MEMMOVE(&vec->a[i], a, sizeof(TYPE)); \
697  } \
698  \
699  vec->size++; \
700  return 1; \
701  } \
702  \
703  int cvec_insertm_##TYPE(cvector_##TYPE* vec, cvec_sz i, TYPE* a) \
704  { \
705  TYPE* tmp; \
706  cvec_sz tmp_sz; \
707  if (vec->capacity == vec->size) { \
708  tmp_sz = RESIZE_MACRO(vec->capacity); \
709  if (!(tmp = (TYPE*)CVEC_REALLOC(vec->a, sizeof(TYPE) * tmp_sz))) { \
710  CVEC_ASSERT(tmp != NULL); \
711  return 0; \
712  } \
713  \
714  vec->a = tmp; \
715  vec->capacity = tmp_sz; \
716  } \
717  CVEC_MEMMOVE(&vec->a[i + 1], &vec->a[i], (vec->size - i) * sizeof(TYPE)); \
718  \
719  CVEC_MEMMOVE(&vec->a[i], a, sizeof(TYPE)); \
720  \
721  vec->size++; \
722  return 1; \
723  } \
724  \
725  int cvec_insert_array_##TYPE(cvector_##TYPE* vec, cvec_sz i, TYPE* a, cvec_sz num) \
726  { \
727  TYPE* tmp; \
728  cvec_sz tmp_sz, j; \
729  if (vec->capacity < vec->size + num) { \
730  tmp_sz = vec->capacity + num + CVEC_##TYPE##_SZ; \
731  if (!(tmp = (TYPE*)CVEC_REALLOC(vec->a, sizeof(TYPE) * tmp_sz))) { \
732  CVEC_ASSERT(tmp != NULL); \
733  return 0; \
734  } \
735  vec->a = tmp; \
736  vec->capacity = tmp_sz; \
737  } \
738  \
739  CVEC_MEMMOVE(&vec->a[i + num], &vec->a[i], (vec->size - i) * sizeof(TYPE)); \
740  if (vec->elem_init) { \
741  for (j = 0; j < num; ++j) { \
742  if (!vec->elem_init(&vec->a[j + i], &a[j])) { \
743  CVEC_ASSERT(0); \
744  return 0; \
745  } \
746  } \
747  } else { \
748  CVEC_MEMMOVE(&vec->a[i], a, num * sizeof(TYPE)); \
749  } \
750  vec->size += num; \
751  return 1; \
752  } \
753  \
754  int cvec_insert_arraym_##TYPE(cvector_##TYPE* vec, cvec_sz i, TYPE* a, cvec_sz num) \
755  { \
756  TYPE* tmp; \
757  cvec_sz tmp_sz; \
758  if (vec->capacity < vec->size + num) { \
759  tmp_sz = vec->capacity + num + CVEC_##TYPE##_SZ; \
760  if (!(tmp = (TYPE*)CVEC_REALLOC(vec->a, sizeof(TYPE) * tmp_sz))) { \
761  CVEC_ASSERT(tmp != NULL); \
762  return 0; \
763  } \
764  vec->a = tmp; \
765  vec->capacity = tmp_sz; \
766  } \
767  \
768  CVEC_MEMMOVE(&vec->a[i + num], &vec->a[i], (vec->size - i) * sizeof(TYPE)); \
769  \
770  CVEC_MEMMOVE(&vec->a[i], a, num * sizeof(TYPE)); \
771  vec->size += num; \
772  return 1; \
773  } \
774  \
775  int cvec_replace_##TYPE(cvector_##TYPE* vec, cvec_sz i, TYPE* a, TYPE* ret) \
776  { \
777  if (ret) { \
778  CVEC_MEMMOVE(ret, &vec->a[i], sizeof(TYPE)); \
779  } else if (vec->elem_free) { \
780  vec->elem_free(&vec->a[i]); \
781  } \
782  \
783  if (vec->elem_init) { \
784  if (!vec->elem_init(&vec->a[i], a)) { \
785  CVEC_ASSERT(0); \
786  return 0; \
787  } \
788  } else { \
789  CVEC_MEMMOVE(&vec->a[i], a, sizeof(TYPE)); \
790  } \
791  return 1; \
792  } \
793  \
794  void cvec_replacem_##TYPE(cvector_##TYPE* vec, cvec_sz i, TYPE* a, TYPE* ret) \
795  { \
796  if (ret) { \
797  CVEC_MEMMOVE(ret, &vec->a[i], sizeof(TYPE)); \
798  } \
799  \
800  CVEC_MEMMOVE(&vec->a[i], a, sizeof(TYPE)); \
801  } \
802  \
803  void cvec_erase_##TYPE(cvector_##TYPE* vec, cvec_sz start, cvec_sz end) \
804  { \
805  cvec_sz i; \
806  cvec_sz d = end - start + 1; \
807  if (vec->elem_free) { \
808  for (i = start; i <= end; i++) { \
809  vec->elem_free(&vec->a[i]); \
810  } \
811  } \
812  CVEC_MEMMOVE(&vec->a[start], &vec->a[end + 1], (vec->size - 1 - end) * sizeof(TYPE)); \
813  vec->size -= d; \
814  } \
815  \
816  void cvec_remove_##TYPE(cvector_##TYPE* vec, cvec_sz start, cvec_sz end) \
817  { \
818  cvec_sz d = end - start + 1; \
819  CVEC_MEMMOVE(&vec->a[start], &vec->a[end + 1], (vec->size - 1 - end) * sizeof(TYPE)); \
820  vec->size -= d; \
821  } \
822  \
823  int cvec_reserve_##TYPE(cvector_##TYPE* vec, cvec_sz size) \
824  { \
825  TYPE* tmp; \
826  if (vec->capacity < size) { \
827  if (!(tmp = (TYPE*)CVEC_REALLOC(vec->a, sizeof(TYPE) * (size + CVEC_##TYPE##_SZ)))) { \
828  CVEC_ASSERT(tmp != NULL); \
829  return 0; \
830  } \
831  vec->a = tmp; \
832  vec->capacity = size + CVEC_##TYPE##_SZ; \
833  } \
834  return 1; \
835  } \
836  \
837  int cvec_set_cap_##TYPE(cvector_##TYPE* vec, cvec_sz size) \
838  { \
839  cvec_sz i; \
840  TYPE* tmp; \
841  if (size < vec->size) { \
842  if (vec->elem_free) { \
843  for (i = vec->size - 1; i >= size; i--) { \
844  vec->elem_free(&vec->a[i]); \
845  } \
846  } \
847  vec->size = size; \
848  } \
849  \
850  vec->capacity = size; \
851  \
852  if (!(tmp = (TYPE*)CVEC_REALLOC(vec->a, sizeof(TYPE) * size))) { \
853  CVEC_ASSERT(tmp != NULL); \
854  return 0; \
855  } \
856  vec->a = tmp; \
857  return 1; \
858  } \
859  \
860  int cvec_set_val_sz_##TYPE(cvector_##TYPE* vec, TYPE* val) \
861  { \
862  cvec_sz i; \
863  \
864  if (vec->elem_free) { \
865  for (i = 0; i < vec->size; i++) { \
866  vec->elem_free(&vec->a[i]); \
867  } \
868  } \
869  \
870  if (vec->elem_init) { \
871  for (i = 0; i < vec->size; i++) { \
872  if (!vec->elem_init(&vec->a[i], val)) { \
873  CVEC_ASSERT(0); \
874  return 0; \
875  } \
876  } \
877  } else { \
878  for (i = 0; i < vec->size; i++) { \
879  CVEC_MEMMOVE(&vec->a[i], val, sizeof(TYPE)); \
880  } \
881  } \
882  return 1; \
883  } \
884  \
885  int cvec_set_val_cap_##TYPE(cvector_##TYPE* vec, TYPE* val) \
886  { \
887  cvec_sz i; \
888  if (vec->elem_free) { \
889  for (i = 0; i < vec->size; i++) { \
890  vec->elem_free(&vec->a[i]); \
891  } \
892  vec->size = vec->capacity; \
893  } \
894  \
895  if (vec->elem_init) { \
896  for (i = 0; i < vec->capacity; i++) { \
897  if (!vec->elem_init(&vec->a[i], val)) { \
898  CVEC_ASSERT(0); \
899  return 0; \
900  } \
901  } \
902  } else { \
903  for (i = 0; i < vec->capacity; i++) { \
904  CVEC_MEMMOVE(&vec->a[i], val, sizeof(TYPE)); \
905  } \
906  } \
907  return 1; \
908  } \
909  \
910  void cvec_clear_##TYPE(cvector_##TYPE* vec) \
911  { \
912  cvec_sz i; \
913  if (vec->elem_free) { \
914  for (i = 0; i < vec->size; ++i) { \
915  vec->elem_free(&vec->a[i]); \
916  } \
917  } \
918  vec->size = 0; \
919  } \
920  \
921  void cvec_free_##TYPE##_heap(void* vec) \
922  { \
923  cvec_sz i; \
924  cvector_##TYPE* tmp = (cvector_##TYPE*)vec; \
925  if (!tmp) return; \
926  if (tmp->elem_free) { \
927  for (i = 0; i < tmp->size; i++) { \
928  tmp->elem_free(&tmp->a[i]); \
929  } \
930  } \
931  CVEC_FREE(tmp->a); \
932  CVEC_FREE(tmp); \
933  } \
934  \
935  void cvec_free_##TYPE(void* vec) \
936  { \
937  cvec_sz i; \
938  cvector_##TYPE* tmp = (cvector_##TYPE*)vec; \
939  if (tmp->elem_free) { \
940  for (i = 0; i < tmp->size; i++) { \
941  tmp->elem_free(&tmp->a[i]); \
942  } \
943  } \
944  \
945  CVEC_FREE(tmp->a); \
946  \
947  tmp->size = 0; \
948  tmp->capacity = 0; \
949  }
950 
951 #endif
#define CVEC_SIZE_TYPE
Definition: cvector_macro.h:63
CVEC_SIZE_TYPE cvec_sz
Definition: cvector_macro.h:68