14 #define DEBUG(...) fprintf(stderr, __VA_ARGS__)
17 #define DEFINE_VECTOR(_typename_, _ctype_) \
18 void _typename_##_realloc(_typename_* const vec) { \
19 if (vec->data == NULL) { \
20 if (0 == vec->capacity) { \
21 DEBUG("REALLOC NULL\n"); \
23 DEBUG("REALLOC NULL -> %zu (%zub)", vec->capacity, (vec->capacity * sizeof(_ctype_))); \
24 if ((vec->data = malloc(vec->capacity * sizeof(_ctype_))) == NULL) { \
25 DEBUG("\nMemory reallocation failure\n"); \
28 DEBUG(" [%p]\n", (void*) vec->data); \
29 assert(vec->data != NULL); \
32 if (0 == vec->capacity) { \
33 DEBUG("REALLOC [%p] -> NULL\n", (void*) vec->data); \
37 DEBUG("REALLOC [%p] -> %zu (%zub)", (void*) vec->data, vec->capacity, (vec->capacity * sizeof(_ctype_))); \
38 if ((vec->data = realloc(vec->data, vec->capacity * sizeof(_ctype_))) == NULL) { \
39 DEBUG("\nMemory reallocation failure\n"); \
42 DEBUG(" [%p]\n", (void*) vec->data); \
43 assert(vec->data != NULL); \
48 void _typename_##_malloc(_typename_* const vec) { \
49 assert(vec->data == NULL); \
50 if (0 == vec->capacity) { \
51 DEBUG("MALLOC NULL\n"); \
54 DEBUG("MALLOC %zu (%zub)", vec->capacity, (vec->capacity * sizeof(_ctype_))); \
55 if ((vec->data = malloc(vec->capacity * sizeof(_ctype_))) == NULL) { \
56 DEBUG("\nMemory allocation failure\n"); \
59 DEBUG(" [%p]\n", (void*) vec->data); \
60 assert(vec->data != NULL); \
64 VECTOR_CREATE_FUNCTION_PROTOTYPE(_typename_, _ctype_) { \
65 _typename_ vec = { 0, size, NULL }; \
66 _typename_##_malloc(&vec); \
70 VECTOR_FREE_FUNCTION_PROTOTYPE(_typename_, _ctype_) { \
71 if (vec->data == NULL) { \
72 DEBUG("FREE NULL\n"); \
74 DEBUG("FREE [%p]\n", (void*) vec->data); \
80 VECTOR_GETV_FUNCTION_PROTOTYPE(_typename_, _ctype_) { \
81 assert(index < vec->size); \
82 return vec->data[index]; \
85 VECTOR_GETP_FUNCTION_PROTOTYPE(_typename_, _ctype_) { \
86 assert(index < vec->size); \
87 return &vec->data[index]; \
90 VECTOR_SET_FUNCTION_PROTOTYPE(_typename_, _ctype_) { \
91 assert(index < vec->size); \
92 vec->data[index] = val; \
95 VECTOR_PUSH_FUNCTION_PROTOTYPE(_typename_, _ctype_) { \
97 if (vec->size > vec->capacity) { \
98 vec->capacity = vec->capacity * 2 + 1; \
99 _typename_##_realloc(vec); \
101 vec->data[vec->size - 1] = val; \
104 VECTOR_PRINT_FUNCTION_PROTOTYPE(_typename_, _ctype_) { \
105 char const* const sep = ((separator == NULL) ? ", " : separator); \
107 for (size_t i=0; i<vec->size; i++) { \
108 printf(element_format, vec->data[i]); \
109 if (i != (vec->size - 1)) { \
116 VECTOR_FRONT_FUNCTION_PROTOTYPE(_typename_, _ctype_) { \
117 assert(vec->size > 0); \
118 return vec->data[0]; \
121 VECTOR_BACK_FUNCTION_PROTOTYPE(_typename_, _ctype_) { \
122 assert(vec->size > 0); \
123 return vec->data[vec->size - 1]; \
126 VECTOR_DATA_FUNCTION_PROTOTYPE(_typename_, _ctype_) { \
130 VECTOR_EMPTY_FUNCTION_PROTOTYPE(_typename_, _ctype_) { \
131 return (vec->size == 0) ? true : false; \
134 VECTOR_SHRINK_FUNCTION_PROTOTYPE(_typename_, _ctype_) { \
135 if (vec->size != vec->capacity) { \
136 vec->capacity = vec->size; \
137 _typename_##_realloc(vec); \
141 VECTOR_CLEAR_FUNCTION_PROTOTYPE(_typename_, _ctype_) { \
145 VECTOR_INSERT_FUNCTION_PROTOTYPE(_typename_, _ctype_) { \
146 assert(pos < vec->size); \
147 assert(vec->size > 0); \
148 assert(vec->data != NULL); \
149 size_t i = vec->size; \
151 if (vec->size > vec->capacity) { \
152 vec->capacity = vec->capacity * 2 + 1; \
153 _typename_##_realloc(vec); \
155 for (; i>pos; i--) { \
156 vec->data[i] = vec->data[i-1]; \
158 vec->data[pos] = elem; \
161 VECTOR_ERASE_FUNCTION_PROTOTYPE(_typename_, _ctype_) { \
162 assert(pos < vec->size); \
163 assert(vec->size > 0); \
164 assert(vec->data != NULL); \
166 for (size_t i=pos; i<vec->size; i++) { \
167 vec->data[i] = vec->data[i+1]; \
171 VECTOR_POP_FUNCTION_PROTOTYPE(_typename_, _ctype_) { \
172 assert(vec->size > 0); \
173 assert(vec->data != NULL); \
174 return vec->data[--vec->size]; \
177 VECTOR_SWAP_FUNCTION_PROTOTYPE(_typename_, _ctype_) { \
178 _typename_ tmp = *vec1; \
183 VECTOR_INSERT_VECTOR_FUNCTION_PROTOTYPE(_typename_, _ctype_) { \
184 assert(pos < vec->size); \
185 assert(vec->size > 0); \
186 assert(vec->data != NULL); \
187 assert(((ins_vec->capacity > 0) && (ins_vec->data != NULL) \
188 && (((vec->data + vec->capacity - 1) < ins_vec->data) \
189 || (vec->data > (ins_vec->data + ins_vec->capacity - 1)))) \
190 || ((ins_vec->capacity == 0) && (ins_vec->data != NULL))); \
191 _typename_##_insert_array(vec, pos, ins_vec->data, ins_vec->size); \
194 VECTOR_INSERT_ARRAY_FUNCTION_PROTOTYPE(_typename_, _ctype_) { \
195 assert(pos < vec->size); \
196 assert(vec->size > 0); \
197 assert(vec->data != NULL); \
198 assert(((array_size > 0) && (array != NULL) \
199 && (((vec->data + vec->capacity - 1) < array) \
200 || (vec->data > (array + array_size - 1)))) \
201 || ((array_size == 0) && (array != NULL))); \
202 vec->size += array_size; \
203 if (vec->size > vec->capacity) { \
204 vec->capacity = vec->size * 2; \
205 _typename_##_realloc(vec); \
207 for (size_t i=0; i<array_size; i++) { \
208 vec->data[(array_size-1)+pos+i] = vec->data[pos+i]; \
209 vec->data[pos+i] = array[i]; \
213 VECTOR_PUSH_ARRAY_FUNCTION_PROTOTYPE(_typename_, _ctype_) { \
214 assert(((array_size == 0) && (array == NULL)) \
215 || ((array_size > 0) && (array != NULL))); \
216 size_t pos = vec->size; \
217 vec->size += array_size; \
218 if (vec->size > vec->capacity) { \
219 vec->capacity = vec->size * 2; \
220 _typename_##_realloc(vec); \
222 for (size_t i=0; i<array_size; i++) { \
223 vec->data[i+pos] = array[i]; \
227 VECTOR_PUSH_VECTOR_FUNCTION_PROTOTYPE(_typename_, _ctype_) { \
228 assert(push_vec->data != NULL); \
229 assert(vec->data != NULL); \
230 _typename_##_push_array(vec, push_vec->data, push_vec->size); \
233 VECTOR_COPY_FUNCTION_PROTOTYPE(_typename_, _ctype_) { \
234 assert(vec->data != NULL); \
236 res.size = vec->size; \
237 res.capacity = vec->capacity; \
239 _typename_##_malloc(&res); \
240 memcpy(res.data, vec->data, (vec->size * sizeof(_ctype_))); \
244 VECTOR_EQV_FUNCTION_PROTOTYPE(_typename_, _ctype_) { \
245 assert((vec1->data != NULL) && (vec2->data != NULL)); \
246 if (vec1->size != vec2->size) { \
249 for(size_t i=0; i<vec1->size; i++) { \
250 if (!eqv(vec1->data[i], vec2->data[i])) { \