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