111 va_end(ap); |
111 va_end(ap); |
112 |
112 |
113 return 0; |
113 return 0; |
114 } |
114 } |
115 |
115 |
116 UcxArray ucx_array_new(size_t capacity, size_t elemsize) { |
116 UcxArray* ucx_array_new(size_t capacity, size_t elemsize) { |
117 return ucx_array_new_a(capacity, elemsize, ucx_default_allocator()); |
117 return ucx_array_new_a(capacity, elemsize, ucx_default_allocator()); |
118 } |
118 } |
119 |
119 |
120 UcxArray ucx_array_new_a(size_t capacity, size_t elemsize, |
120 UcxArray* ucx_array_new_a(size_t capacity, size_t elemsize, |
121 UcxAllocator* allocator) { |
121 UcxAllocator* allocator) { |
122 UcxArray array; |
122 UcxArray* array = almalloc(allocator, sizeof(UcxArray)); |
123 |
123 if(array) { |
124 array.allocator = allocator; |
124 ucx_array_init_a(array, capacity, elemsize, allocator); |
125 array.elemsize = elemsize; |
125 } |
126 array.size = 0; |
|
127 array.data = alcalloc(allocator, capacity, elemsize); |
|
128 |
|
129 if (array.data) { |
|
130 array.capacity = capacity; |
|
131 } else { |
|
132 array.capacity = 0; |
|
133 } |
|
134 |
|
135 return array; |
126 return array; |
136 } |
127 } |
137 |
128 |
138 UcxArray ucx_array_clone(UcxArray array) { |
129 void ucx_array_init(UcxArray* array, size_t capacity, size_t elemsize) { |
139 UcxArray clone; |
130 ucx_array_init_a(array, capacity, elemsize, ucx_default_allocator()); |
140 |
131 } |
141 clone.allocator = array.allocator; |
132 |
142 clone.elemsize = array.elemsize; |
133 void ucx_array_init_a(UcxArray* array, size_t capacity, size_t elemsize, |
143 clone.size = array.size; |
134 UcxAllocator* allocator) { |
144 clone.data = alcalloc(array.allocator, array.capacity, array.elemsize); |
135 |
145 |
136 array->allocator = allocator; |
146 if (clone.data) { |
137 array->elemsize = elemsize; |
147 clone.capacity = array.capacity; |
138 array->size = 0; |
148 memcpy(clone.data, array.data, array.size*array.elemsize); |
139 array->data = alcalloc(allocator, capacity, elemsize); |
149 } else { |
140 |
150 clone.capacity = clone.size = 0; |
141 if (array->data) { |
151 } |
142 array->capacity = capacity; |
152 |
143 } else { |
153 return clone; |
144 array->capacity = 0; |
154 } |
145 } |
155 |
146 } |
156 int ucx_array_equals(UcxArray array1, UcxArray array2, |
147 |
|
148 int ucx_array_clone(UcxArray* dest, UcxArray const* src) { |
|
149 if (ucx_array_ensurecap(dest, src->capacity)) { |
|
150 return 1; |
|
151 } |
|
152 |
|
153 dest->elemsize = src->elemsize; |
|
154 dest->size = src->size; |
|
155 |
|
156 if (dest->data) { |
|
157 memcpy(dest->data, src->data, src->size*src->elemsize); |
|
158 } |
|
159 |
|
160 return 0; |
|
161 } |
|
162 |
|
163 int ucx_array_equals(UcxArray const *array1, UcxArray const *array2, |
157 cmp_func cmpfnc, void* data) { |
164 cmp_func cmpfnc, void* data) { |
158 |
165 |
159 if (array1.size != array2.size || array1.elemsize != array2.elemsize) { |
166 if (array1->size != array2->size || array1->elemsize != array2->elemsize) { |
160 return 0; |
167 return 0; |
161 } else { |
168 } else { |
162 if (array1.size == 0) |
169 if (array1->size == 0) |
163 return 1; |
170 return 1; |
164 |
171 |
|
172 size_t elemsize; |
165 if (cmpfnc == NULL) { |
173 if (cmpfnc == NULL) { |
166 cmpfnc = ucx_cmp_mem; |
174 cmpfnc = ucx_cmp_mem; |
167 data = &array1.elemsize; |
175 elemsize = array1->elemsize; |
|
176 data = &elemsize; |
168 } |
177 } |
169 |
178 |
170 for (size_t i = 0 ; i < array1.size ; i++) { |
179 for (size_t i = 0 ; i < array1->size ; i++) { |
171 int r = cmpfnc( |
180 int r = cmpfnc( |
172 ucx_array_at(array1, i), |
181 ucx_array_at(array1, i), |
173 ucx_array_at(array2, i), |
182 ucx_array_at(array2, i), |
174 data); |
183 data); |
175 if (r != 0) |
184 if (r != 0) |
178 return 1; |
187 return 1; |
179 } |
188 } |
180 } |
189 } |
181 |
190 |
182 void ucx_array_destroy(UcxArray *array) { |
191 void ucx_array_destroy(UcxArray *array) { |
183 alfree(array->allocator, array->data); |
192 if(array->data) |
|
193 alfree(array->allocator, array->data); |
184 array->data = NULL; |
194 array->data = NULL; |
185 array->capacity = array->size = 0; |
195 array->capacity = array->size = 0; |
186 } |
196 } |
187 |
197 |
|
198 void ucx_array_free(UcxArray *array) { |
|
199 ucx_array_destroy(array); |
|
200 alfree(array->allocator, array); |
|
201 } |
|
202 |
188 int ucx_array_append_from(UcxArray *array, void *data, size_t count) { |
203 int ucx_array_append_from(UcxArray *array, void *data, size_t count) { |
189 if (ucx_array_ensurecap(array, array->size + count)) |
204 if (ucx_array_ensurecap(array, array->size + count)) |
190 return 1; |
205 return 1; |
191 |
206 |
192 void* dest = ucx_array_at(*array, array->size); |
207 void* dest = ucx_array_at(array, array->size); |
193 if (data) { |
208 if (data) { |
194 memcpy(dest, data, array->elemsize*count); |
209 memcpy(dest, data, array->elemsize*count); |
195 } else { |
210 } else { |
196 memset(dest, 0, array->elemsize*count); |
211 memset(dest, 0, array->elemsize*count); |
197 } |
212 } |
203 int ucx_array_prepend_from(UcxArray *array, void *data, size_t count) { |
218 int ucx_array_prepend_from(UcxArray *array, void *data, size_t count) { |
204 if (ucx_array_ensurecap(array, array->size + count)) |
219 if (ucx_array_ensurecap(array, array->size + count)) |
205 return 1; |
220 return 1; |
206 |
221 |
207 if (array->size > 0) { |
222 if (array->size > 0) { |
208 void *dest = ucx_array_at(*array, count); |
223 void *dest = ucx_array_at(array, count); |
209 memmove(dest, array->data, array->elemsize*array->size); |
224 memmove(dest, array->data, array->elemsize*array->size); |
210 } |
225 } |
211 |
226 |
212 if (data) { |
227 if (data) { |
213 memcpy(array->data, data, array->elemsize*count); |
228 memcpy(array->data, data, array->elemsize*count); |
276 if (ucx_array_reserve(array1, capacity)) { |
291 if (ucx_array_reserve(array1, capacity)) { |
277 return 1; |
292 return 1; |
278 } |
293 } |
279 } |
294 } |
280 |
295 |
281 void* dest = ucx_array_at(*array1, array1->size); |
296 void* dest = ucx_array_at(array1, array1->size); |
282 memcpy(dest, array2->data, array2->size*array2->elemsize); |
297 memcpy(dest, array2->data, array2->size*array2->elemsize); |
283 |
298 |
284 array1->size += array2->size; |
299 array1->size += array2->size; |
285 |
300 |
286 return 0; |
301 return 0; |
287 } |
302 } |
288 |
303 |
289 void *ucx_array_at(UcxArray array, size_t index) { |
304 void *ucx_array_at(UcxArray const *array, size_t index) { |
290 char* memory = array.data; |
305 char* memory = array->data; |
291 char* loc = memory + index*array.elemsize; |
306 char* loc = memory + index*array->elemsize; |
292 return loc; |
307 return loc; |
293 } |
308 } |
294 |
309 |
295 size_t ucx_array_find(UcxArray array, void *elem, cmp_func cmpfnc, void *data) { |
310 size_t ucx_array_find(UcxArray const *array, void *elem, |
296 |
311 cmp_func cmpfnc, void *data) { |
|
312 |
|
313 size_t elemsize; |
297 if (cmpfnc == NULL) { |
314 if (cmpfnc == NULL) { |
298 cmpfnc = ucx_cmp_mem; |
315 cmpfnc = ucx_cmp_mem; |
299 data = &array.elemsize; |
316 elemsize = array->elemsize; |
300 } |
317 data = &elemsize; |
301 |
318 } |
302 if (array.size > 0) { |
319 |
303 for (size_t i = 0 ; i < array.size ; i++) { |
320 if (array->size > 0) { |
|
321 for (size_t i = 0 ; i < array->size ; i++) { |
304 void* ptr = ucx_array_at(array, i); |
322 void* ptr = ucx_array_at(array, i); |
305 if (cmpfnc(ptr, elem, data) == 0) { |
323 if (cmpfnc(ptr, elem, data) == 0) { |
306 return i; |
324 return i; |
307 } |
325 } |
308 } |
326 } |
309 return array.size; |
327 return array->size; |
310 } else { |
328 } else { |
311 return 0; |
329 return 0; |
312 } |
330 } |
313 } |
331 } |
314 |
332 |
315 int ucx_array_contains(UcxArray array, void *elem, cmp_func cmpfnc, void *data) { |
333 int ucx_array_contains(UcxArray const *array, void *elem, |
316 return ucx_array_find(array, elem, cmpfnc, data) != array.size; |
334 cmp_func cmpfnc, void *data) { |
|
335 return ucx_array_find(array, elem, cmpfnc, data) != array->size; |
317 } |
336 } |
318 |
337 |
319 static void ucx_mergesort_merge(void *arrdata,size_t elemsize, |
338 static void ucx_mergesort_merge(void *arrdata,size_t elemsize, |
320 cmp_func cmpfnc, void *data, |
339 cmp_func cmpfnc, void *data, |
321 size_t start, size_t mid, size_t end) { |
340 size_t start, size_t mid, size_t end) { |
395 info.data = data; |
414 info.data = data; |
396 qsort_r(array, count, elemsize, &info, cmp_func_swap_args); |
415 qsort_r(array, count, elemsize, &info, cmp_func_swap_args); |
397 } |
416 } |
398 #endif /* USE_UCX_QSORT_R */ |
417 #endif /* USE_UCX_QSORT_R */ |
399 |
418 |
400 void ucx_array_sort(UcxArray array, cmp_func cmpfnc, void *data) { |
419 void ucx_array_sort(UcxArray* array, cmp_func cmpfnc, void *data) { |
401 ucx_array_sort_impl(array.data, array.size, array.elemsize, cmpfnc, data); |
420 ucx_array_sort_impl(array->data, array->size, array->elemsize, |
|
421 cmpfnc, data); |
402 } |
422 } |
403 |
423 |
404 void ucx_array_remove(UcxArray *array, size_t index) { |
424 void ucx_array_remove(UcxArray *array, size_t index) { |
405 array->size--; |
425 array->size--; |
406 if (index < array->size) { |
426 if (index < array->size) { |
407 void* dest = ucx_array_at(*array, index); |
427 void* dest = ucx_array_at(array, index); |
408 void* src = ucx_array_at(*array, index+1); |
428 void* src = ucx_array_at(array, index+1); |
409 memmove(dest, src, (array->size - index)*array->elemsize); |
429 memmove(dest, src, (array->size - index)*array->elemsize); |
410 } |
430 } |
411 } |
431 } |
412 |
432 |
413 void ucx_array_remove_fast(UcxArray *array, size_t index) { |
433 void ucx_array_remove_fast(UcxArray *array, size_t index) { |
414 array->size--; |
434 array->size--; |
415 if (index < array->size) { |
435 if (index < array->size) { |
416 void* dest = ucx_array_at(*array, index); |
436 void* dest = ucx_array_at(array, index); |
417 void* src = ucx_array_at(*array, array->size); |
437 void* src = ucx_array_at(array, array->size); |
418 memcpy(dest, src, array->elemsize); |
438 memcpy(dest, src, array->elemsize); |
419 } |
439 } |
420 } |
440 } |
421 |
441 |
422 int ucx_array_shrink(UcxArray* array) { |
442 int ucx_array_shrink(UcxArray* array) { |