| 228 * Creates a new array reallocator. |
228 * Creates a new array reallocator. |
| 229 * |
229 * |
| 230 * When @p allocator is @c NULL, the cxDefaultAllocator will be used. |
230 * When @p allocator is @c NULL, the cxDefaultAllocator will be used. |
| 231 * |
231 * |
| 232 * When @p stackmem is not @c NULL, the reallocator is supposed to be used |
232 * When @p stackmem is not @c NULL, the reallocator is supposed to be used |
| 233 * @em only for the specific array that is initially located at @p stackmem. |
233 * @em only for the specific array initially located at @p stackmem. |
| 234 * When reallocation is needed, the reallocator checks, if the array is |
234 * When reallocation is needed, the reallocator checks if the array is |
| 235 * still located at @p stackmem and copies the contents to the heap. |
235 * still located at @p stackmem and copies the contents to the heap. |
| 236 * |
236 * |
| 237 * @note Invoking this function with both arguments @c NULL will return a |
237 * @note Invoking this function with both arguments being @c NULL will return a |
| 238 * reallocator that behaves like #cx_array_default_reallocator. |
238 * reallocator that behaves like #cx_array_default_reallocator. |
| 239 * |
239 * |
| 240 * @param allocator the allocator this reallocator shall be based on |
240 * @param allocator the allocator this reallocator shall be based on |
| 241 * @param stackmem the address of the array when the array is initially located |
241 * @param stackmem the address of the array when the array is initially located |
| 242 * on the stack or shall not reallocated in place |
242 * on the stack or shall not reallocate in place |
| 243 * @return an array reallocator |
243 * @return an array reallocator |
| 244 */ |
244 */ |
| 245 cx_attr_export |
245 cx_attr_export |
| 246 CxArrayReallocator cx_array_reallocator( |
246 CxArrayReallocator cx_array_reallocator( |
| 247 const struct cx_allocator_s *allocator, |
247 const struct cx_allocator_s *allocator, |
| 294 * Copies elements from one array to another. |
294 * Copies elements from one array to another. |
| 295 * |
295 * |
| 296 * The elements are copied to the @p target array at the specified @p index, |
296 * The elements are copied to the @p target array at the specified @p index, |
| 297 * overwriting possible elements. The @p index does not need to be in range of |
297 * overwriting possible elements. The @p index does not need to be in range of |
| 298 * the current array @p size. If the new index plus the number of elements added |
298 * the current array @p size. If the new index plus the number of elements added |
| 299 * would extend the array's size, the remaining @p capacity is used. |
299 * extends the array's size, the remaining @p capacity is used. |
| 300 * |
300 * |
| 301 * If the @p capacity is also insufficient to hold the new data, a reallocation |
301 * If the @p capacity is also insufficient to hold the new data, a reallocation |
| 302 * attempt is made with the specified @p reallocator. |
302 * attempt is made with the specified @p reallocator. |
| 303 * You can create your own reallocator by hand, use #cx_array_default_reallocator, |
303 * You can create your own reallocator by hand, use #cx_array_default_reallocator, |
| 304 * or use the convenience function cx_array_reallocator() to create a custom reallocator. |
304 * or use the convenience function cx_array_reallocator() to create a custom reallocator. |
| 305 * |
305 * |
| 306 * The @p width in bytes refers to the size and capacity. |
306 * The @p width in bytes refers to the size and capacity. |
| 307 * Both must have the same width. |
307 * Both must have the same width. |
| 308 * Supported are 0, 1, 2, and 4, as well as 8 if running on a 64 bit |
308 * Supported are 0, 1, 2, and 4, as well as 8 if running on a 64-bit |
| 309 * architecture. If set to zero, the native word width is used. |
309 * architecture. If set to zero, the native word width is used. |
| 310 * |
310 * |
| 311 * @param target a pointer to the target array |
311 * @param target a pointer to the target array |
| 312 * @param size a pointer to the size of the target array |
312 * @param size a pointer to the size of the target array |
| 313 * @param capacity a pointer to the capacity of the target array |
313 * @param capacity a pointer to the capacity of the target array |
| 584 * @see cx_array_simple_insert_sorted_a() |
584 * @see cx_array_simple_insert_sorted_a() |
| 585 */ |
585 */ |
| 586 #define cx_array_simple_insert_sorted(array, src, n, cmp_func) \ |
586 #define cx_array_simple_insert_sorted(array, src, n, cmp_func) \ |
| 587 cx_array_simple_insert_sorted_a(NULL, array, src, n, cmp_func) |
587 cx_array_simple_insert_sorted_a(NULL, array, src, n, cmp_func) |
| 588 |
588 |
| |
589 |
| |
590 /** |
| |
591 * Inserts a sorted array into another sorted array, avoiding duplicates. |
| |
592 * |
| |
593 * If either the target or the source array is not already sorted with respect |
| |
594 * to the specified @p cmp_func, the behavior is undefined. |
| |
595 * |
| |
596 * If the capacity is insufficient to hold the new data, a reallocation |
| |
597 * attempt is made. |
| |
598 * You can create your own reallocator by hand, use #cx_array_default_reallocator, |
| |
599 * or use the convenience function cx_array_reallocator() to create a custom reallocator. |
| |
600 * |
| |
601 * @param target a pointer to the target array |
| |
602 * @param size a pointer to the size of the target array |
| |
603 * @param capacity a pointer to the capacity of the target array |
| |
604 * @param cmp_func the compare function for the elements |
| |
605 * @param src the source array |
| |
606 * @param elem_size the size of one element |
| |
607 * @param elem_count the number of elements to insert |
| |
608 * @param reallocator the array reallocator to use |
| |
609 * (@c NULL defaults to #cx_array_default_reallocator) |
| |
610 * @retval zero success |
| |
611 * @retval non-zero failure |
| |
612 */ |
| |
613 cx_attr_nonnull_arg(1, 2, 3, 5) |
| |
614 cx_attr_export |
| |
615 int cx_array_insert_unique( |
| |
616 void **target, |
| |
617 size_t *size, |
| |
618 size_t *capacity, |
| |
619 cx_compare_func cmp_func, |
| |
620 const void *src, |
| |
621 size_t elem_size, |
| |
622 size_t elem_count, |
| |
623 CxArrayReallocator *reallocator |
| |
624 ); |
| |
625 |
| |
626 /** |
| |
627 * Inserts an element into a sorted array if it does not exist. |
| |
628 * |
| |
629 * If the target array is not already sorted with respect |
| |
630 * to the specified @p cmp_func, the behavior is undefined. |
| |
631 * |
| |
632 * If the capacity is insufficient to hold the new data, a reallocation |
| |
633 * attempt is made. |
| |
634 * |
| |
635 * The \@ SIZE_TYPE is flexible and can be any unsigned integer type. |
| |
636 * It is important, however, that @p size and @p capacity are pointers to |
| |
637 * variables of the same type. |
| |
638 * |
| |
639 * @param target (@c void**) a pointer to the target array |
| |
640 * @param size (@c SIZE_TYPE*) a pointer to the size of the target array |
| |
641 * @param capacity (@c SIZE_TYPE*) a pointer to the capacity of the target array |
| |
642 * @param elem_size (@c size_t) the size of one element |
| |
643 * @param elem (@c void*) a pointer to the element to add |
| |
644 * @param cmp_func (@c cx_cmp_func) the compare function for the elements |
| |
645 * @param reallocator (@c CxArrayReallocator*) the array reallocator to use |
| |
646 * @retval zero success (also when the element was already present) |
| |
647 * @retval non-zero failure |
| |
648 */ |
| |
649 #define cx_array_add_unique(target, size, capacity, elem_size, elem, cmp_func, reallocator) \ |
| |
650 cx_array_insert_unique((void**)(target), size, capacity, cmp_func, elem, elem_size, 1, reallocator) |
| |
651 |
| |
652 /** |
| |
653 * Convenience macro for cx_array_add_unique() with a default |
| |
654 * layout and the specified reallocator. |
| |
655 * |
| |
656 * @param reallocator (@c CxArrayReallocator*) the array reallocator to use |
| |
657 * @param array the name of the array (NOT a pointer or alias to the array) |
| |
658 * @param elem the element to add (NOT a pointer, address is automatically taken) |
| |
659 * @param cmp_func (@c cx_cmp_func) the compare function for the elements |
| |
660 * @retval zero success |
| |
661 * @retval non-zero failure |
| |
662 * @see CX_ARRAY_DECLARE() |
| |
663 * @see cx_array_simple_add_unique() |
| |
664 */ |
| |
665 #define cx_array_simple_add_unique_a(reallocator, array, elem, cmp_func) \ |
| |
666 cx_array_add_unique(&array, &(array##_size), &(array##_capacity), \ |
| |
667 sizeof((array)[0]), &(elem), cmp_func, reallocator) |
| |
668 |
| |
669 /** |
| |
670 * Convenience macro for cx_array_add_unique() with a default |
| |
671 * layout and the default reallocator. |
| |
672 * |
| |
673 * @param array the name of the array (NOT a pointer or alias to the array) |
| |
674 * @param elem the element to add (NOT a pointer, address is automatically taken) |
| |
675 * @param cmp_func (@c cx_cmp_func) the compare function for the elements |
| |
676 * @retval zero success |
| |
677 * @retval non-zero failure |
| |
678 * @see CX_ARRAY_DECLARE() |
| |
679 * @see cx_array_simple_add_unique_a() |
| |
680 */ |
| |
681 #define cx_array_simple_add_unique(array, elem, cmp_func) \ |
| |
682 cx_array_simple_add_unique_a(NULL, array, elem, cmp_func) |
| |
683 |
| |
684 /** |
| |
685 * Convenience macro for cx_array_insert_unique() with a default |
| |
686 * layout and the specified reallocator. |
| |
687 * |
| |
688 * @param reallocator (@c CxArrayReallocator*) the array reallocator to use |
| |
689 * @param array the name of the array (NOT a pointer or alias to the array) |
| |
690 * @param src (@c void*) pointer to the source array |
| |
691 * @param n (@c size_t) number of elements in the source array |
| |
692 * @param cmp_func (@c cx_cmp_func) the compare function for the elements |
| |
693 * @retval zero success |
| |
694 * @retval non-zero failure |
| |
695 * @see CX_ARRAY_DECLARE() |
| |
696 * @see cx_array_simple_insert_unique() |
| |
697 */ |
| |
698 #define cx_array_simple_insert_unique_a(reallocator, array, src, n, cmp_func) \ |
| |
699 cx_array_insert_unique((void**)(&array), &(array##_size), &(array##_capacity), \ |
| |
700 cmp_func, src, sizeof((array)[0]), n, reallocator) |
| |
701 |
| |
702 /** |
| |
703 * Convenience macro for cx_array_insert_unique() with a default |
| |
704 * layout and the default reallocator. |
| |
705 * |
| |
706 * @param array the name of the array (NOT a pointer or alias to the array) |
| |
707 * @param src (@c void*) pointer to the source array |
| |
708 * @param n (@c size_t) number of elements in the source array |
| |
709 * @param cmp_func (@c cx_cmp_func) the compare function for the elements |
| |
710 * @retval zero success |
| |
711 * @retval non-zero failure |
| |
712 * @see CX_ARRAY_DECLARE() |
| |
713 * @see cx_array_simple_insert_unique_a() |
| |
714 */ |
| |
715 #define cx_array_simple_insert_unique(array, src, n, cmp_func) \ |
| |
716 cx_array_simple_insert_unique_a(NULL, array, src, n, cmp_func) |
| |
717 |
| 589 /** |
718 /** |
| 590 * Searches the largest lower bound in a sorted array. |
719 * Searches the largest lower bound in a sorted array. |
| 591 * |
720 * |
| 592 * In other words, this function returns the index of the largest element |
721 * In other words, this function returns the index of the largest element |
| 593 * in @p arr that is less or equal to @p elem with respect to @p cmp_func. |
722 * in @p arr that is less or equal to @p elem with respect to @p cmp_func. |