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