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
68
typedef
CVEC_SIZE_TYPE
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
CVEC_SIZE_TYPE
#define CVEC_SIZE_TYPE
Definition:
cvector_macro.h:63
cvec_sz
CVEC_SIZE_TYPE cvec_sz
Definition:
cvector_macro.h:68
Generated on Fri Mar 17 2023 00:49:55 for CVector by
1.9.1