CVector 4.3.0
A C++ style vector library in strict ANSI C (C89)
Loading...
Searching...
No Matches
cvector_template.h
Go to the documentation of this file.
1#ifndef CVECTOR_TYPE_H
2#define CVECTOR_TYPE_H
3
4#ifndef CVEC_SIZE_T
5#include <stdlib.h>
6#define CVEC_SIZE_T size_t
7#endif
8
9#ifndef CVEC_SZ
10#define CVEC_SZ
12#endif
13
14#ifdef __cplusplus
15extern "C" {
16#endif
17
25
26
27
29
30int cvec_TYPE(cvector_TYPE* vec, cvec_sz size, cvec_sz capacity);
31int cvec_init_TYPE(cvector_TYPE* vec, TYPE* vals, cvec_sz num);
32
35int cvec_copyc_TYPE(void* dest, void* src);
37
38int cvec_push_TYPE(cvector_TYPE* vec, TYPE a);
40
47#define cvec_shrink_to_fit_TYPE(vec) cvec_set_cap_TYPE((vec), (vec)->size)
51
53
55void cvec_free_TYPE_heap(void* vec);
56void cvec_free_TYPE(void* vec);
57
58#ifdef __cplusplus
59}
60#endif
61
62/* CVECTOR_TYPE_H */
63#endif
64
65
66#ifdef CVECTOR_TYPE_IMPLEMENTATION
67
69
70#define CVEC_TYPE_ALLOCATOR(x) ((x+1) * 2)
71
72#if defined(CVEC_MALLOC) && defined(CVEC_FREE) && defined(CVEC_REALLOC)
73/* ok */
74#elif !defined(CVEC_MALLOC) && !defined(CVEC_FREE) && !defined(CVEC_REALLOC)
75/* ok */
76#else
77#error "Must define all or none of CVEC_MALLOC, CVEC_FREE, and CVEC_REALLOC."
78#endif
79
80#ifndef CVEC_MALLOC
81#include <stdlib.h>
82#define CVEC_MALLOC(sz) malloc(sz)
83#define CVEC_REALLOC(p, sz) realloc(p, sz)
84#define CVEC_FREE(p) free(p)
85#endif
86
87#ifndef CVEC_MEMMOVE
88#include <string.h>
89#define CVEC_MEMMOVE(dst, src, sz) memmove(dst, src, sz)
90#endif
91
92#ifndef CVEC_ASSERT
93#include <assert.h>
94#define CVEC_ASSERT(x) assert(x)
95#endif
96
98{
99 cvector_TYPE* vec;
100 if (!(vec = (cvector_TYPE*)CVEC_MALLOC(sizeof(cvector_TYPE)))) {
101 CVEC_ASSERT(vec != NULL);
102 return NULL;
103 }
104
105 vec->size = size;
106 vec->capacity = (capacity > vec->size || (vec->size && capacity == vec->size)) ? capacity : vec->size + CVEC_TYPE_SZ;
107
108 if (!(vec->a = (TYPE*)CVEC_MALLOC(vec->capacity*sizeof(TYPE)))) {
109 CVEC_ASSERT(vec->a != NULL);
110 CVEC_FREE(vec);
111 return NULL;
112 }
113
114 return vec;
115}
116
118{
119 cvector_TYPE* vec;
120
121 if (!(vec = (cvector_TYPE*)CVEC_MALLOC(sizeof(cvector_TYPE)))) {
122 CVEC_ASSERT(vec != NULL);
123 return NULL;
124 }
125
126 vec->capacity = num + CVEC_TYPE_SZ;
127 vec->size = num;
128 if (!(vec->a = (TYPE*)CVEC_MALLOC(vec->capacity*sizeof(TYPE)))) {
129 CVEC_ASSERT(vec->a != NULL);
130 CVEC_FREE(vec);
131 return NULL;
132 }
133
134 CVEC_MEMMOVE(vec->a, vals, sizeof(TYPE)*num);
135
136 return vec;
137}
138
139int cvec_TYPE(cvector_TYPE* vec, cvec_sz size, cvec_sz capacity)
140{
141 vec->size = size;
142 vec->capacity = (capacity > vec->size || (vec->size && capacity == vec->size)) ? capacity : vec->size + CVEC_TYPE_SZ;
143
144 if (!(vec->a = (TYPE*)CVEC_MALLOC(vec->capacity*sizeof(TYPE)))) {
145 CVEC_ASSERT(vec->a != NULL);
146 vec->size = vec->capacity = 0;
147 return 0;
148 }
149
150 return 1;
151}
152
153int cvec_init_TYPE(cvector_TYPE* vec, TYPE* vals, cvec_sz num)
154{
155 vec->capacity = num + CVEC_TYPE_SZ;
156 vec->size = num;
157 if (!(vec->a = (TYPE*)CVEC_MALLOC(vec->capacity*sizeof(TYPE)))) {
158 CVEC_ASSERT(vec->a != NULL);
159 vec->size = vec->capacity = 0;
160 return 0;
161 }
162
163 CVEC_MEMMOVE(vec->a, vals, sizeof(TYPE)*num);
164
165 return 1;
166}
167
168int cvec_copyc_TYPE(void* dest, void* src)
169{
170 cvector_TYPE* vec1 = (cvector_TYPE*)dest;
171 cvector_TYPE* vec2 = (cvector_TYPE*)src;
172
173 vec1->a = NULL;
174 vec1->size = 0;
175 vec1->capacity = 0;
176
177 return cvec_copy_TYPE(vec1, vec2);
178}
179
181{
182 TYPE* tmp = NULL;
183 if (!(tmp = (TYPE*)CVEC_REALLOC(dest->a, src->capacity*sizeof(TYPE)))) {
184 CVEC_ASSERT(tmp != NULL);
185 return 0;
186 }
187 dest->a = tmp;
188
189 CVEC_MEMMOVE(dest->a, src->a, src->size*sizeof(TYPE));
190 dest->size = src->size;
191 dest->capacity = src->capacity;
192 return 1;
193}
194
195
196int cvec_push_TYPE(cvector_TYPE* vec, TYPE a)
197{
198 TYPE* tmp;
199 cvec_sz tmp_sz;
200 if (vec->capacity > vec->size) {
201 vec->a[vec->size++] = a;
202 } else {
203 tmp_sz = CVEC_TYPE_ALLOCATOR(vec->capacity);
204 if (!(tmp = (TYPE*)CVEC_REALLOC(vec->a, sizeof(TYPE)*tmp_sz))) {
205 CVEC_ASSERT(tmp != NULL);
206 return 0;
207 }
208 vec->a = tmp;
209 vec->a[vec->size++] = a;
210 vec->capacity = tmp_sz;
211 }
212 return 1;
213}
214
216{
217 return vec->a[--vec->size];
218}
219
221{
222 return &vec->a[vec->size-1];
223}
224
226{
227 TYPE* tmp;
228 cvec_sz tmp_sz;
229 if (vec->capacity < vec->size + num) {
230 tmp_sz = vec->capacity + num + CVEC_TYPE_SZ;
231 if (!(tmp = (TYPE*)CVEC_REALLOC(vec->a, sizeof(TYPE)*tmp_sz))) {
232 CVEC_ASSERT(tmp != NULL);
233 return 0;
234 }
235 vec->a = tmp;
236 vec->capacity = tmp_sz;
237 }
238
239 vec->size += num;
240 return 1;
241}
242
243int cvec_insert_TYPE(cvector_TYPE* vec, cvec_sz i, TYPE a)
244{
245 TYPE* tmp;
246 cvec_sz tmp_sz;
247 if (vec->capacity > vec->size) {
248 CVEC_MEMMOVE(&vec->a[i+1], &vec->a[i], (vec->size-i)*sizeof(TYPE));
249 vec->a[i] = a;
250 } else {
251 tmp_sz = CVEC_TYPE_ALLOCATOR(vec->capacity);
252 if (!(tmp = (TYPE*)CVEC_REALLOC(vec->a, sizeof(TYPE)*tmp_sz))) {
253 CVEC_ASSERT(tmp != NULL);
254 return 0;
255 }
256 vec->a = tmp;
257 CVEC_MEMMOVE(&vec->a[i+1], &vec->a[i], (vec->size-i)*sizeof(TYPE));
258 vec->a[i] = a;
259 vec->capacity = tmp_sz;
260 }
261
262 vec->size++;
263 return 1;
264}
265
266int cvec_insert_array_TYPE(cvector_TYPE* vec, cvec_sz i, TYPE* a, cvec_sz num)
267{
268 TYPE* tmp;
269 cvec_sz tmp_sz;
270 if (vec->capacity < vec->size + num) {
271 tmp_sz = vec->capacity + num + CVEC_TYPE_SZ;
272 if (!(tmp = (TYPE*)CVEC_REALLOC(vec->a, sizeof(TYPE)*tmp_sz))) {
273 CVEC_ASSERT(tmp != NULL);
274 return 0;
275 }
276 vec->a = tmp;
277 vec->capacity = tmp_sz;
278 }
279
280 CVEC_MEMMOVE(&vec->a[i+num], &vec->a[i], (vec->size-i)*sizeof(TYPE));
281 CVEC_MEMMOVE(&vec->a[i], a, num*sizeof(TYPE));
282 vec->size += num;
283 return 1;
284}
285
286TYPE cvec_replace_TYPE(cvector_TYPE* vec, cvec_sz i, TYPE a)
287{
288 TYPE tmp = vec->a[i];
289 vec->a[i] = a;
290 return tmp;
291}
292
293void cvec_erase_TYPE(cvector_TYPE* vec, cvec_sz start, cvec_sz end)
294{
295 cvec_sz d = end - start + 1;
296 CVEC_MEMMOVE(&vec->a[start], &vec->a[end+1], (vec->size-1-end)*sizeof(TYPE));
297 vec->size -= d;
298}
299
300
302{
303 TYPE* tmp;
304 if (vec->capacity < size) {
305 if (!(tmp = (TYPE*)CVEC_REALLOC(vec->a, sizeof(TYPE)*(size+CVEC_TYPE_SZ)))) {
306 CVEC_ASSERT(tmp != NULL);
307 return 0;
308 }
309 vec->a = tmp;
310 vec->capacity = size + CVEC_TYPE_SZ;
311 }
312 return 1;
313}
314
316{
317 TYPE* tmp;
318 if (size < vec->size) {
319 vec->size = size;
320 }
321
322 if (!(tmp = (TYPE*)CVEC_REALLOC(vec->a, sizeof(TYPE)*size))) {
323 CVEC_ASSERT(tmp != NULL);
324 return 0;
325 }
326 vec->a = tmp;
327 vec->capacity = size;
328 return 1;
329}
330
331void cvec_set_val_sz_TYPE(cvector_TYPE* vec, TYPE val)
332{
333 cvec_sz i;
334 for (i=0; i<vec->size; i++) {
335 vec->a[i] = val;
336 }
337}
338
339void cvec_set_val_cap_TYPE(cvector_TYPE* vec, TYPE val)
340{
341 cvec_sz i;
342 for (i=0; i<vec->capacity; i++) {
343 vec->a[i] = val;
344 }
345}
346
347void cvec_clear_TYPE(cvector_TYPE* vec) { vec->size = 0; }
348
349void cvec_free_TYPE_heap(void* vec)
350{
351 cvector_TYPE* tmp = (cvector_TYPE*)vec;
352 if (!tmp) return;
353 CVEC_FREE(tmp->a);
354 CVEC_FREE(tmp);
355}
356
357void cvec_free_TYPE(void* vec)
358{
359 cvector_TYPE* tmp = (cvector_TYPE*)vec;
360 CVEC_FREE(tmp->a);
361 tmp->a = NULL;
362 tmp->size = 0;
363 tmp->capacity = 0;
364}
365
366#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_SIZE_T cvec_sz
int cvec_set_cap_TYPE(cvector_TYPE *vec, cvec_sz size)
int cvec_reserve_TYPE(cvector_TYPE *vec, cvec_sz size)
int cvec_init_TYPE(cvector_TYPE *vec, TYPE *vals, cvec_sz num)
int cvec_copy_TYPE(cvector_TYPE *dest, cvector_TYPE *src)
void cvec_erase_TYPE(cvector_TYPE *vec, cvec_sz start, cvec_sz end)
void cvec_free_TYPE(void *vec)
TYPE * cvec_back_TYPE(cvector_TYPE *vec)
TYPE cvec_replace_TYPE(cvector_TYPE *vec, cvec_sz i, TYPE a)
TYPE cvec_pop_TYPE(cvector_TYPE *vec)
void cvec_free_TYPE_heap(void *vec)
void cvec_set_val_sz_TYPE(cvector_TYPE *vec, TYPE val)
cvector_TYPE * cvec_TYPE_heap(cvec_sz size, cvec_sz capacity)
CVEC_SIZE_T cvec_sz
void cvec_clear_TYPE(cvector_TYPE *vec)
int cvec_insert_array_TYPE(cvector_TYPE *vec, cvec_sz i, TYPE *a, cvec_sz num)
int cvec_copyc_TYPE(void *dest, void *src)
void cvec_set_val_cap_TYPE(cvector_TYPE *vec, TYPE val)
int cvec_push_TYPE(cvector_TYPE *vec, TYPE a)
int cvec_TYPE(cvector_TYPE *vec, cvec_sz size, cvec_sz capacity)
int cvec_insert_TYPE(cvector_TYPE *vec, cvec_sz i, TYPE a)
#define CVEC_SIZE_T
cvector_TYPE * cvec_init_TYPE_heap(TYPE *vals, cvec_sz num)
cvec_sz CVEC_TYPE_SZ
int cvec_extend_TYPE(cvector_TYPE *vec, cvec_sz num)
Data structure for TYPE vector.
TYPE * a
Array.
cvec_sz size
Current size (amount you use when manipulating array directly).
cvec_sz capacity
Allocated size of array; always >= size.