92 * @param capacity the new capacity (number of elements) |
92 * @param capacity the new capacity (number of elements) |
93 * @param elem_size the size of each element |
93 * @param elem_size the size of each element |
94 * @param alloc a reference to this allocator |
94 * @param alloc a reference to this allocator |
95 * @return a pointer to the reallocated memory or \c NULL on failure |
95 * @return a pointer to the reallocated memory or \c NULL on failure |
96 */ |
96 */ |
|
97 cx_attr_nodiscard |
|
98 cx_attr_nonnull_arg(4) |
|
99 cx_attr_allocsize(2, 3) |
97 void *(*realloc)( |
100 void *(*realloc)( |
98 void *array, |
101 void *array, |
99 size_t capacity, |
102 size_t capacity, |
100 size_t elem_size, |
103 size_t elem_size, |
101 struct cx_array_reallocator_s *alloc |
104 struct cx_array_reallocator_s *alloc |
182 * @param elem_count the number of elements to copy |
185 * @param elem_count the number of elements to copy |
183 * @param reallocator the array reallocator to use, or \c NULL |
186 * @param reallocator the array reallocator to use, or \c NULL |
184 * if reallocation shall not happen |
187 * if reallocation shall not happen |
185 * @return zero on success, non-zero error code on failure |
188 * @return zero on success, non-zero error code on failure |
186 */ |
189 */ |
187 __attribute__((__nonnull__(1, 2, 5))) |
190 cx_attr_nonnull_arg(1, 2, 5) |
188 enum cx_array_result cx_array_copy( |
191 enum cx_array_result cx_array_copy( |
189 void **target, |
192 void **target, |
190 size_t *size, |
193 size_t *size, |
191 size_t *capacity, |
194 size_t *capacity, |
192 size_t index, |
195 size_t index, |
260 * @param elem_size the size of one element |
263 * @param elem_size the size of one element |
261 * @param elem_count the number of elements to insert |
264 * @param elem_count the number of elements to insert |
262 * @param reallocator the array reallocator to use |
265 * @param reallocator the array reallocator to use |
263 * @return zero on success, non-zero error code on failure |
266 * @return zero on success, non-zero error code on failure |
264 */ |
267 */ |
265 __attribute__((__nonnull__)) |
268 cx_attr_nonnull |
266 enum cx_array_result cx_array_insert_sorted( |
269 enum cx_array_result cx_array_insert_sorted( |
267 void **target, |
270 void **target, |
268 size_t *size, |
271 size_t *size, |
269 size_t *capacity, |
272 size_t *capacity, |
270 cx_compare_func cmp_func, |
273 cx_compare_func cmp_func, |
340 * @param elem_size the size of one element |
343 * @param elem_size the size of one element |
341 * @param elem the element to find |
344 * @param elem the element to find |
342 * @param cmp_func the compare function |
345 * @param cmp_func the compare function |
343 * @return the index of the largest lower bound, or \p size |
346 * @return the index of the largest lower bound, or \p size |
344 */ |
347 */ |
345 __attribute__((__nonnull__)) |
348 cx_attr_nonnull |
346 size_t cx_array_binary_search_inf( |
349 size_t cx_array_binary_search_inf( |
347 const void *arr, |
350 const void *arr, |
348 size_t size, |
351 size_t size, |
349 size_t elem_size, |
352 size_t elem_size, |
350 const void *elem, |
353 const void *elem, |
363 * @param elem the element to find |
366 * @param elem the element to find |
364 * @param cmp_func the compare function |
367 * @param cmp_func the compare function |
365 * @return the index of the element in the array, or \p size if the element |
368 * @return the index of the element in the array, or \p size if the element |
366 * cannot be found |
369 * cannot be found |
367 */ |
370 */ |
368 __attribute__((__nonnull__)) |
371 cx_attr_nonnull |
369 static inline size_t cx_array_binary_search( |
372 size_t cx_array_binary_search( |
370 const void *arr, |
373 const void *arr, |
371 size_t size, |
374 size_t size, |
372 size_t elem_size, |
375 size_t elem_size, |
373 const void *elem, |
376 const void *elem, |
374 cx_compare_func cmp_func |
377 cx_compare_func cmp_func |
375 ) { |
378 ); |
376 size_t index = cx_array_binary_search_inf( |
|
377 arr, size, elem_size, elem, cmp_func |
|
378 ); |
|
379 if (index < size && cmp_func(((const char *) arr) + index * elem_size, elem) == 0) { |
|
380 return index; |
|
381 } else { |
|
382 return size; |
|
383 } |
|
384 } |
|
385 |
379 |
386 /** |
380 /** |
387 * Searches the smallest upper bound in a sorted array. |
381 * Searches the smallest upper bound in a sorted array. |
388 * |
382 * |
389 * In other words, this function returns the index of the smallest element |
383 * In other words, this function returns the index of the smallest element |
401 * @param elem_size the size of one element |
395 * @param elem_size the size of one element |
402 * @param elem the element to find |
396 * @param elem the element to find |
403 * @param cmp_func the compare function |
397 * @param cmp_func the compare function |
404 * @return the index of the smallest upper bound, or \p size |
398 * @return the index of the smallest upper bound, or \p size |
405 */ |
399 */ |
406 __attribute__((__nonnull__)) |
400 cx_attr_nonnull |
407 static inline size_t cx_array_binary_search_sup( |
401 size_t cx_array_binary_search_sup( |
408 const void *arr, |
402 const void *arr, |
409 size_t size, |
403 size_t size, |
410 size_t elem_size, |
404 size_t elem_size, |
411 const void *elem, |
405 const void *elem, |
412 cx_compare_func cmp_func |
406 cx_compare_func cmp_func |
413 ) { |
407 ); |
414 size_t inf = cx_array_binary_search_inf(arr, size, elem_size, elem, cmp_func); |
|
415 if (inf == size) { |
|
416 // no infimum means, first element is supremum |
|
417 return 0; |
|
418 } else if (cmp_func(((const char *) arr) + inf * elem_size, elem) == 0) { |
|
419 return inf; |
|
420 } else { |
|
421 return inf + 1; |
|
422 } |
|
423 } |
|
424 |
408 |
425 /** |
409 /** |
426 * Swaps two array elements. |
410 * Swaps two array elements. |
427 * |
411 * |
428 * @param arr the array |
412 * @param arr the array |
429 * @param elem_size the element size |
413 * @param elem_size the element size |
430 * @param idx1 index of first element |
414 * @param idx1 index of first element |
431 * @param idx2 index of second element |
415 * @param idx2 index of second element |
432 */ |
416 */ |
433 __attribute__((__nonnull__)) |
417 cx_attr_nonnull |
434 void cx_array_swap( |
418 void cx_array_swap( |
435 void *arr, |
419 void *arr, |
436 size_t elem_size, |
420 size_t elem_size, |
437 size_t idx1, |
421 size_t idx1, |
438 size_t idx2 |
422 size_t idx2 |
452 * functions will not work) |
436 * functions will not work) |
453 * @param elem_size the size of each element in bytes |
437 * @param elem_size the size of each element in bytes |
454 * @param initial_capacity the initial number of elements the array can store |
438 * @param initial_capacity the initial number of elements the array can store |
455 * @return the created list |
439 * @return the created list |
456 */ |
440 */ |
|
441 cx_attr_nodiscard |
|
442 cx_attr_malloc |
|
443 cx_attr_dealloc(cxListDestroy, 1) |
457 CxList *cxArrayListCreate( |
444 CxList *cxArrayListCreate( |
458 const CxAllocator *allocator, |
445 const CxAllocator *allocator, |
459 cx_compare_func comparator, |
446 cx_compare_func comparator, |
460 size_t elem_size, |
447 size_t elem_size, |
461 size_t initial_capacity |
448 size_t initial_capacity |