CVector 4.3.0
A C++ style vector library in strict ANSI C (C89)
Loading...
Searching...
No Matches
cvector_f_struct.h
Go to the documentation of this file.
1/*
2
3CVector 4.2.1 MIT Licensed vector (dynamic array) library in strict C89
4http://www.robertwinkler.com/projects/cvector.html
5http://www.robertwinkler.com/projects/cvector/
6
7Besides the docs and all the Doxygen comments, see cvector_tests.c for
8examples of how to use it or look at any of these other projects for
9more practical examples:
10
11https://github.com/rswinkle/C_Interpreter
12https://github.com/rswinkle/CPIM2
13https://github.com/rswinkle/spelling_game
14https://github.com/rswinkle/c_bigint
15http://portablegl.com/
16
17The MIT License (MIT)
18
19Copyright (c) 2011-2025 Robert Winkler
20
21Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated
22documentation files (the "Software"), to deal in the Software without restriction, including without limitation
23the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and
24to permit persons to whom the Software is furnished to do so, subject to the following conditions:
25
26The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
27
28THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
29TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
30THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
31CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
32IN THE SOFTWARE.
33*/
34
35#ifndef CVECTOR_f_struct_H
36#define CVECTOR_f_struct_H
37
38#ifndef CVEC_SIZE_T
39#include <stdlib.h>
40#define CVEC_SIZE_T size_t
41#endif
42
43#ifndef CVEC_SZ
44#define CVEC_SZ
46#endif
47
48#ifdef __cplusplus
49extern "C" {
50#endif
51
52
61
63
64int cvec_f_struct(cvector_f_struct* vec, cvec_sz size, cvec_sz capacity, void(*elem_free)(void*), int(*elem_init)(void*, void*));
65int cvec_init_f_struct(cvector_f_struct* vec, f_struct* vals, cvec_sz num, void(*elem_free)(void*), int(*elem_init)(void*, void*));
66
67cvector_f_struct* cvec_f_struct_heap(cvec_sz size, cvec_sz capacity, void (*elem_free)(void*), int(*elem_init)(void*, void*));
68cvector_f_struct* cvec_init_f_struct_heap(f_struct* vals, cvec_sz num, void (*elem_free)(void*), int(*elem_init)(void*, void*));
69
70int cvec_copyc_f_struct(void* dest, void* src);
72
75
81
89#define cvec_shrink_to_fit_f_struct(vec) cvec_set_cap_f_struct((vec), (vec)->size)
93
95
98void cvec_free_f_struct(void* vec);
99
100#ifdef __cplusplus
101}
102#endif
103
104/* CVECTOR_f_struct_H */
105#endif
106
107
108#ifdef CVECTOR_f_struct_IMPLEMENTATION
109
111
112#define CVEC_f_struct_ALLOCATOR(x) ((x+1) * 2)
113
114#if defined(CVEC_MALLOC) && defined(CVEC_FREE) && defined(CVEC_REALLOC)
115/* ok */
116#elif !defined(CVEC_MALLOC) && !defined(CVEC_FREE) && !defined(CVEC_REALLOC)
117/* ok */
118#else
119#error "Must define all or none of CVEC_MALLOC, CVEC_FREE, and CVEC_REALLOC."
120#endif
121
122#ifndef CVEC_MALLOC
123#include <stdlib.h>
124#define CVEC_MALLOC(sz) malloc(sz)
125#define CVEC_REALLOC(p, sz) realloc(p, sz)
126#define CVEC_FREE(p) free(p)
127#endif
128
129#ifndef CVEC_MEMMOVE
130#include <string.h>
131#define CVEC_MEMMOVE(dst, src, sz) memmove(dst, src, sz)
132#endif
133
134#ifndef CVEC_ASSERT
135#include <assert.h>
136#define CVEC_ASSERT(x) assert(x)
137#endif
138
139
140/* general vector */
141
142cvector_f_struct* cvec_f_struct_heap(cvec_sz size, cvec_sz capacity, void(*elem_free)(void*), int(*elem_init)(void*, void*))
143{
144 cvector_f_struct* vec;
145 if (!(vec = (cvector_f_struct*)CVEC_MALLOC(sizeof(cvector_f_struct)))) {
146 CVEC_ASSERT(vec != NULL);
147 return NULL;
148 }
149
150 vec->size = size;
151 vec->capacity = (capacity > vec->size || (vec->size && capacity == vec->size)) ? capacity : vec->size + CVEC_f_struct_SZ;
152
153 if (!(vec->a = (f_struct*)CVEC_MALLOC(vec->capacity * sizeof(f_struct)))) {
154 CVEC_ASSERT(vec->a != NULL);
155 CVEC_FREE(vec);
156 return NULL;
157 }
158
159 vec->elem_free = elem_free;
160 vec->elem_init = elem_init;
161
162 return vec;
163}
164
165cvector_f_struct* cvec_init_f_struct_heap(f_struct* vals, cvec_sz num, void(*elem_free)(void*), int(*elem_init)(void*, void*))
166{
167 cvector_f_struct* vec;
168 cvec_sz i;
169
170 if (!(vec = (cvector_f_struct*)CVEC_MALLOC(sizeof(cvector_f_struct)))) {
171 CVEC_ASSERT(vec != NULL);
172 return NULL;
173 }
174
175 vec->capacity = num + CVEC_f_struct_SZ;
176 vec->size = num;
177 if (!(vec->a = (f_struct*)CVEC_MALLOC(vec->capacity * sizeof(f_struct)))) {
178 CVEC_ASSERT(vec->a != NULL);
179 CVEC_FREE(vec);
180 return NULL;
181 }
182
183 if (elem_init) {
184 for (i=0; i<num; ++i) {
185 if (!elem_init(&vec->a[i], &vals[i])) {
186 CVEC_ASSERT(0);
187 CVEC_FREE(vec->a);
188 CVEC_FREE(vec);
189 return NULL;
190 }
191 }
192 } else {
193 CVEC_MEMMOVE(vec->a, vals, sizeof(f_struct)*num);
194 }
195
196 vec->elem_free = elem_free;
197 vec->elem_init = elem_init;
198
199 return vec;
200}
201
202int cvec_f_struct(cvector_f_struct* vec, cvec_sz size, cvec_sz capacity, void(*elem_free)(void*), int(*elem_init)(void*, void*))
203{
204 vec->size = size;
205 vec->capacity = (capacity > vec->size || (vec->size && capacity == vec->size)) ? capacity : vec->size + CVEC_f_struct_SZ;
206
207 if (!(vec->a = (f_struct*)CVEC_MALLOC(vec->capacity * sizeof(f_struct)))) {
208 CVEC_ASSERT(vec->a != NULL);
209 vec->size = vec->capacity = 0;
210 return 0;
211 }
212
213 vec->elem_free = elem_free;
214 vec->elem_init = elem_init;
215
216 return 1;
217}
218
219int cvec_init_f_struct(cvector_f_struct* vec, f_struct* vals, cvec_sz num, void(*elem_free)(void*), int(*elem_init)(void*, void*))
220{
221 cvec_sz i;
222
223 vec->capacity = num + CVEC_f_struct_SZ;
224 vec->size = num;
225 if (!(vec->a = (f_struct*)CVEC_MALLOC(vec->capacity * sizeof(f_struct)))) {
226 CVEC_ASSERT(vec->a != NULL);
227 vec->size = vec->capacity = 0;
228 return 0;
229 }
230
231 if (elem_init) {
232 for (i=0; i<num; ++i) {
233 if (!elem_init(&vec->a[i], &vals[i])) {
234 CVEC_ASSERT(0);
235 return 0;
236 }
237 }
238 } else {
239 CVEC_MEMMOVE(vec->a, vals, sizeof(f_struct)*num);
240 }
241
242 vec->elem_free = elem_free;
243 vec->elem_init = elem_init;
244
245 return 1;
246}
247
248int cvec_copyc_f_struct(void* dest, void* src)
249{
250 cvector_f_struct* vec1 = (cvector_f_struct*)dest;
252
253 vec1->a = NULL;
254 vec1->size = 0;
255 vec1->capacity = 0;
256
257 return cvec_copy_f_struct(vec1, vec2);
258}
259
261{
262 int i;
263 f_struct* tmp = NULL;
264 if (!(tmp = (f_struct*)CVEC_REALLOC(dest->a, src->capacity*sizeof(f_struct)))) {
265 CVEC_ASSERT(tmp != NULL);
266 return 0;
267 }
268 dest->a = tmp;
269
270 if (src->elem_init) {
271 for (i=0; i<src->size; ++i) {
272 if (!src->elem_init(&dest->a[i], &src->a[i])) {
273 CVEC_ASSERT(0);
274 return 0;
275 }
276 }
277 } else {
278 /* could use memcpy here since we know we just allocated dest->a */
279 CVEC_MEMMOVE(dest->a, src->a, src->size*sizeof(f_struct));
280 }
281
282 dest->size = src->size;
283 dest->capacity = src->capacity;
284 dest->elem_free = src->elem_free;
285 dest->elem_init = src->elem_init;
286 return 1;
287}
288
290{
291 f_struct* tmp;
292 cvec_sz tmp_sz;
293 if (vec->capacity == vec->size) {
294 tmp_sz = CVEC_f_struct_ALLOCATOR(vec->capacity);
295 if (!(tmp = (f_struct*)CVEC_REALLOC(vec->a, sizeof(f_struct)*tmp_sz))) {
296 CVEC_ASSERT(tmp != NULL);
297 return 0;
298 }
299 vec->a = tmp;
300 vec->capacity = tmp_sz;
301 }
302 if (vec->elem_init) {
303 if (!vec->elem_init(&vec->a[vec->size], a)) {
304 CVEC_ASSERT(0);
305 return 0;
306 }
307 } else {
308 CVEC_MEMMOVE(&vec->a[vec->size], a, sizeof(f_struct));
309 }
310
311 vec->size++;
312 return 1;
313}
314
316{
317 f_struct* tmp;
318 cvec_sz tmp_sz;
319 if (vec->capacity == vec->size) {
320 tmp_sz = CVEC_f_struct_ALLOCATOR(vec->capacity);
321 if (!(tmp = (f_struct*)CVEC_REALLOC(vec->a, sizeof(f_struct)*tmp_sz))) {
322 CVEC_ASSERT(tmp != NULL);
323 return 0;
324 }
325 vec->a = tmp;
326 vec->capacity = tmp_sz;
327 }
328 CVEC_MEMMOVE(&vec->a[vec->size], a, sizeof(f_struct));
329
330 vec->size++;
331 return 1;
332}
333
335{
336 vec->size--;
337 if (ret) {
338 CVEC_MEMMOVE(ret, &vec->a[vec->size], sizeof(f_struct));
339 }
340
341 if (vec->elem_free) {
342 vec->elem_free(&vec->a[vec->size]);
343 }
344}
345
347{
348 vec->size--;
349 if (ret) {
350 CVEC_MEMMOVE(ret, &vec->a[vec->size], sizeof(f_struct));
351 }
352}
353
356{
357 return &vec->a[vec->size-1];
358}
359
361{
362 f_struct* tmp;
363 cvec_sz tmp_sz;
364 if (vec->capacity < vec->size + num) {
365 tmp_sz = vec->capacity + num + CVEC_f_struct_SZ;
366 if (!(tmp = (f_struct*)CVEC_REALLOC(vec->a, sizeof(f_struct)*tmp_sz))) {
367 CVEC_ASSERT(tmp != NULL);
368 return 0;
369 }
370 vec->a = tmp;
371 vec->capacity = tmp_sz;
372 }
373
374 vec->size += num;
375 return 1;
376}
377
379{
380 f_struct* tmp;
381 cvec_sz tmp_sz;
382 if (vec->capacity == vec->size) {
383 tmp_sz = CVEC_f_struct_ALLOCATOR(vec->capacity);
384 if (!(tmp = (f_struct*)CVEC_REALLOC(vec->a, sizeof(f_struct)*tmp_sz))) {
385 CVEC_ASSERT(tmp != NULL);
386 return 0;
387 }
388
389 vec->a = tmp;
390 vec->capacity = tmp_sz;
391 }
392 CVEC_MEMMOVE(&vec->a[i+1], &vec->a[i], (vec->size-i)*sizeof(f_struct));
393
394 if (vec->elem_init) {
395 if (!vec->elem_init(&vec->a[i], a)) {
396 CVEC_ASSERT(0);
397 return 0;
398 }
399 } else {
400 CVEC_MEMMOVE(&vec->a[i], a, sizeof(f_struct));
401 }
402
403 vec->size++;
404 return 1;
405}
406
408{
409 f_struct* tmp;
410 cvec_sz tmp_sz;
411 if (vec->capacity == vec->size) {
412 tmp_sz = CVEC_f_struct_ALLOCATOR(vec->capacity);
413 if (!(tmp = (f_struct*)CVEC_REALLOC(vec->a, sizeof(f_struct)*tmp_sz))) {
414 CVEC_ASSERT(tmp != NULL);
415 return 0;
416 }
417
418 vec->a = tmp;
419 vec->capacity = tmp_sz;
420 }
421 CVEC_MEMMOVE(&vec->a[i+1], &vec->a[i], (vec->size-i)*sizeof(f_struct));
422
423 CVEC_MEMMOVE(&vec->a[i], a, sizeof(f_struct));
424
425 vec->size++;
426 return 1;
427}
428
430{
431 f_struct* tmp;
432 cvec_sz tmp_sz, j;
433 if (vec->capacity < vec->size + num) {
434 tmp_sz = vec->capacity + num + CVEC_f_struct_SZ;
435 if (!(tmp = (f_struct*)CVEC_REALLOC(vec->a, sizeof(f_struct)*tmp_sz))) {
436 CVEC_ASSERT(tmp != NULL);
437 return 0;
438 }
439 vec->a = tmp;
440 vec->capacity = tmp_sz;
441 }
442
443 CVEC_MEMMOVE(&vec->a[i+num], &vec->a[i], (vec->size-i)*sizeof(f_struct));
444 if (vec->elem_init) {
445 for (j=0; j<num; ++j) {
446 if (!vec->elem_init(&vec->a[j+i], &a[j])) {
447 CVEC_ASSERT(0);
448 return 0;
449 }
450 }
451 } else {
452 CVEC_MEMMOVE(&vec->a[i], a, num*sizeof(f_struct));
453 }
454 vec->size += num;
455 return 1;
456}
457
459{
460 f_struct* tmp;
461 cvec_sz tmp_sz;
462 if (vec->capacity < vec->size + num) {
463 tmp_sz = vec->capacity + num + CVEC_VOID_START_SZ;
464 if (!(tmp = (f_struct*)CVEC_REALLOC(vec->a, sizeof(f_struct)*tmp_sz))) {
465 CVEC_ASSERT(tmp != NULL);
466 return 0;
467 }
468 vec->a = tmp;
469 vec->capacity = tmp_sz;
470 }
471
472 CVEC_MEMMOVE(&vec->a[i+num], &vec->a[i], (vec->size-i)*sizeof(f_struct));
473
474 CVEC_MEMMOVE(&vec->a[i], a, num*sizeof(f_struct));
475 vec->size += num;
476 return 1;
477}
478
480{
481 if (ret) {
482 CVEC_MEMMOVE(ret, &vec->a[i], sizeof(f_struct));
483 } else if (vec->elem_free) {
484 vec->elem_free(&vec->a[i]);
485 }
486
487 if (vec->elem_init) {
488 if (!vec->elem_init(&vec->a[i], a)) {
489 CVEC_ASSERT(0);
490 return 0;
491 }
492 } else {
493 CVEC_MEMMOVE(&vec->a[i], a, sizeof(f_struct));
494 }
495 return 1;
496}
497
499{
500 if (ret) {
501 CVEC_MEMMOVE(ret, &vec->a[i], sizeof(f_struct));
502 }
503
504 CVEC_MEMMOVE(&vec->a[i], a, sizeof(f_struct));
505}
506
508{
509 cvec_sz i;
510 cvec_sz d = end - start + 1;
511 if (vec->elem_free) {
512 for (i=start; i<=end; i++) {
513 vec->elem_free(&vec->a[i]);
514 }
515 }
516 CVEC_MEMMOVE(&vec->a[start], &vec->a[end+1], (vec->size-1-end)*sizeof(f_struct));
517 vec->size -= d;
518}
519
521{
522 cvec_sz d = end - start + 1;
523 CVEC_MEMMOVE(&vec->a[start], &vec->a[end+1], (vec->size-1-end)*sizeof(f_struct));
524 vec->size -= d;
525}
526
528{
529 f_struct* tmp;
530 if (vec->capacity < size) {
531 if (!(tmp = (f_struct*)CVEC_REALLOC(vec->a, sizeof(f_struct)*(size+CVEC_f_struct_SZ)))) {
532 CVEC_ASSERT(tmp != NULL);
533 return 0;
534 }
535 vec->a = tmp;
536 vec->capacity = size + CVEC_f_struct_SZ;
537 }
538 return 1;
539}
540
542{
543 cvec_sz i;
544 f_struct* tmp;
545 if (size < vec->size) {
546 if (vec->elem_free) {
547 for (i=vec->size-1; i>=size; i--) {
548 vec->elem_free(&vec->a[i]);
549 }
550 }
551 vec->size = size;
552 }
553
554 vec->capacity = size;
555
556 if (!(tmp = (f_struct*)CVEC_REALLOC(vec->a, sizeof(f_struct)*size))) {
557 CVEC_ASSERT(tmp != NULL);
558 return 0;
559 }
560 vec-> a = tmp;
561 return 1;
562}
563
565{
566 cvec_sz i;
567
568 if (vec->elem_free) {
569 for(i=0; i<vec->size; i++) {
570 vec->elem_free(&vec->a[i]);
571 }
572 }
573
574 if (vec->elem_init) {
575 for (i=0; i<vec->size; i++) {
576 if (!vec->elem_init(&vec->a[i], val)) {
577 CVEC_ASSERT(0);
578 return 0;
579 }
580 }
581 } else {
582 for (i=0; i<vec->size; i++) {
583 CVEC_MEMMOVE(&vec->a[i], val, sizeof(f_struct));
584 }
585 }
586 return 1;
587}
588
590{
591 cvec_sz i;
592 if (vec->elem_free) {
593 for (i=0; i<vec->size; i++) {
594 vec->elem_free(&vec->a[i]);
595 }
596 vec->size = vec->capacity;
597 }
598
599 if (vec->elem_init) {
600 for (i=0; i<vec->capacity; i++) {
601 if (!vec->elem_init(&vec->a[i], val)) {
602 CVEC_ASSERT(0);
603 return 0;
604 }
605 }
606 } else {
607 for (i=0; i<vec->capacity; i++) {
608 CVEC_MEMMOVE(&vec->a[i], val, sizeof(f_struct));
609 }
610 }
611 return 1;
612}
613
615{
616 cvec_sz i;
617 if (vec->elem_free) {
618 for (i=0; i<vec->size; ++i) {
619 vec->elem_free(&vec->a[i]);
620 }
621 }
622 vec->size = 0;
623}
624
625void cvec_free_f_struct_heap(void* vec)
626{
627 cvec_sz i;
629 if (!tmp) return;
630 if (tmp->elem_free) {
631 for (i=0; i<tmp->size; i++) {
632 tmp->elem_free(&tmp->a[i]);
633 }
634 }
635 CVEC_FREE(tmp->a);
636 CVEC_FREE(tmp);
637}
638
639void cvec_free_f_struct(void* vec)
640{
641 cvec_sz i;
643 if (tmp->elem_free) {
644 for (i=0; i<tmp->size; i++) {
645 tmp->elem_free(&tmp->a[i]);
646 }
647 }
648
649 CVEC_FREE(tmp->a);
650 tmp->a = NULL;
651 tmp->size = 0;
652 tmp->capacity = 0;
653}
654
655
656#endif
#define CVEC_FREE(p)
Definition cvector.h:68
#define CVEC_REALLOC(p, sz)
Definition cvector.h:67
#define CVEC_MEMMOVE(dst, src, sz)
Definition cvector.h:73
#define CVEC_MALLOC(sz)
Definition cvector.h:66
#define CVEC_ASSERT(x)
Definition cvector.h:78
CVEC_SIZE_T cvec_sz
Definition cvector.h:88
cvec_sz CVEC_VOID_START_SZ
int cvec_copyc_f_struct(void *dest, void *src)
int cvec_replace_f_struct(cvector_f_struct *vec, cvec_sz i, f_struct *a, f_struct *ret)
int cvec_set_val_sz_f_struct(cvector_f_struct *vec, f_struct *val)
int cvec_f_struct(cvector_f_struct *vec, cvec_sz size, cvec_sz capacity, void(*elem_free)(void *), int(*elem_init)(void *, void *))
void cvec_pop_f_struct(cvector_f_struct *vec, f_struct *ret)
void cvec_erase_f_struct(cvector_f_struct *vec, cvec_sz start, cvec_sz end)
int cvec_init_f_struct(cvector_f_struct *vec, f_struct *vals, cvec_sz num, void(*elem_free)(void *), int(*elem_init)(void *, void *))
void cvec_clear_f_struct(cvector_f_struct *vec)
void cvec_popm_f_struct(cvector_f_struct *vec, f_struct *ret)
void cvec_free_f_struct(void *vec)
cvector_f_struct * cvec_f_struct_heap(cvec_sz size, cvec_sz capacity, void(*elem_free)(void *), int(*elem_init)(void *, void *))
int cvec_insert_array_f_struct(cvector_f_struct *vec, cvec_sz i, f_struct *a, cvec_sz num)
int cvec_copy_f_struct(cvector_f_struct *dest, cvector_f_struct *src)
int cvec_insert_f_struct(cvector_f_struct *vec, cvec_sz i, f_struct *a)
void cvec_replacem_f_struct(cvector_f_struct *vec, cvec_sz i, f_struct *a, f_struct *ret)
CVEC_SIZE_T cvec_sz
int cvec_set_cap_f_struct(cvector_f_struct *vec, cvec_sz size)
void cvec_remove_f_struct(cvector_f_struct *vec, cvec_sz start, cvec_sz end)
int cvec_insert_arraym_f_struct(cvector_f_struct *vec, cvec_sz i, f_struct *a, cvec_sz num)
int cvec_push_f_struct(cvector_f_struct *vec, f_struct *val)
int cvec_set_val_cap_f_struct(cvector_f_struct *vec, f_struct *val)
int cvec_extend_f_struct(cvector_f_struct *vec, cvec_sz num)
f_struct * cvec_back_f_struct(cvector_f_struct *vec)
int cvec_pushm_f_struct(cvector_f_struct *vec, f_struct *a)
void cvec_free_f_struct_heap(void *vec)
cvec_sz CVEC_f_struct_SZ
#define CVEC_SIZE_T
int cvec_reserve_f_struct(cvector_f_struct *vec, cvec_sz size)
cvector_f_struct * cvec_init_f_struct_heap(f_struct *vals, cvec_sz num, void(*elem_free)(void *), int(*elem_init)(void *, void *))
int cvec_insertm_f_struct(cvector_f_struct *vec, cvec_sz i, f_struct *a)
void(* elem_free)(void *)
int(* elem_init)(void *, void *)
Structure used to test generic vector.
Definition test_types.h:14