# HG changeset patch # User Mike Becker # Date 1766162237 -3600 # Node ID 006e076a8db7ecdffc257539b35929e0ace36a1c # Parent fe24b68758bf802bf73983df8abe64f42df5b326 remove cx_ccmp_memcmp() again - i.e. we don't provide any 3-arg cmp func in compare.h diff -r fe24b68758bf -r 006e076a8db7 docs/Writerside/topics/compare.h.md --- a/docs/Writerside/topics/compare.h.md Fri Dec 19 17:24:18 2025 +0100 +++ b/docs/Writerside/topics/compare.h.md Fri Dec 19 17:37:17 2025 +0100 @@ -2,10 +2,9 @@ The `compare.h` header file contains a collection of compare functions for various primitive types. -They come in three flavors: +They come in two flavors: - prefixed with `cx_vcmp` they are taking the values directly as arguments - prefixed with `cx_cmp` the signature is designed to be compatible with the `cx_compare_func` function pointer type. -- prefixed with `cx_ccmp` the signature is designed to be compatible with the `cx_compare_func2` function pointer type. ## Examples @@ -31,13 +30,13 @@ ``` If you only have a `cx_compare_func` at hand but need to call a function that expects a `cx_compare_func2` and a `context`, -you can use `cx_ccmp_wrap` and the `cx_compare_func_wrapper` struct to wrap your function. +you can use `cx_cmp_wrap` and the `cx_compare_func_wrapper` struct to wrap your function. ```C void some_fun(int x, int y, cx_compare_func2 f, void *context); cx_compare_func_wrapper wrapper = {my_cmp_fun}; -some_fun(x, y, cx_ccmp_wrap, &wrapper); +some_fun(x, y, cx_cmp_wrap, &wrapper); ``` ## List of Functions @@ -84,10 +83,32 @@ int cx_cmp_uintptr(const void *a, const void *b); int cx_cmp_ulongint(const void *a, const void *b); int cx_cmp_ulonglong(const void *a, const void *b); +``` -// Three-arguments Flavour -int cx_ccmp_memcmp(const void *a, const void *b, void *size); -int cx_ccmp_wrap(const void *a, const void *b, void *cmp_fun_wrapper); +## Comparing with Context + +Sometimes it might be necessary to have some context available during the comparison. +For this purpose, the `cx_compare_func2` specifies a signature with an additional `void*` argument. +The [Collections](collection.h.md) API supports those functions via the `cxSetAdvancedCompareFunc()` macro. + +On the other hand, some API might provide _only_ the variant with three arguments, +but you want to use one of the compare functions defined above. +In this case, they can easily be wrapped + +```C +#include + +typedef struct { + cx_compare_func cmp; +} cx_compare_func_wrapper; + +// signature is cx_compare_func2 compatible +int cx_cmp_wrap(const void *a, const void *b, void *wrapper); + +// example: imagine there is some_sort_fun() +// that only supports 3-argument compare functions +cx_compare_func_wrapper wrapper = {cx_cmp_int}; +some_sort_fun(array, cx_cmp_wrap, &wrapper); ``` diff -r fe24b68758bf -r 006e076a8db7 src/array_list.c --- a/src/array_list.c Fri Dec 19 17:24:18 2025 +0100 +++ b/src/array_list.c Fri Dec 19 17:37:17 2025 +0100 @@ -350,7 +350,7 @@ ) { cx_compare_func_wrapper wrapper = {cmp_func}; return cx_array_insert_sorted_c_(allocator, array, elem_size, sorted_data, - n, cx_ccmp_wrap, &wrapper, allow_duplicates); + n, cx_cmp_wrap, &wrapper, allow_duplicates); } #ifndef WITH_QSORT_R @@ -578,7 +578,7 @@ cx_compare_func cmp_func ) { cx_compare_func_wrapper wrapper = {cmp_func}; - return cx_array_binary_search_inf_c(arr, size, elem_size, elem, cx_ccmp_wrap, &wrapper); + return cx_array_binary_search_inf_c(arr, size, elem_size, elem, cx_cmp_wrap, &wrapper); } size_t cx_array_binary_search( @@ -589,7 +589,7 @@ cx_compare_func cmp_func ) { cx_compare_func_wrapper wrapper = {cmp_func}; - return cx_array_binary_search_c(arr, size, elem_size, elem, cx_ccmp_wrap, &wrapper); + return cx_array_binary_search_c(arr, size, elem_size, elem, cx_cmp_wrap, &wrapper); } size_t cx_array_binary_search_sup( @@ -600,7 +600,7 @@ cx_compare_func cmp_func ) { cx_compare_func_wrapper wrapper = {cmp_func}; - return cx_array_binary_search_sup_c(arr, size, elem_size, elem, cx_ccmp_wrap, &wrapper); + return cx_array_binary_search_sup_c(arr, size, elem_size, elem, cx_cmp_wrap, &wrapper); } #ifndef CX_ARRAY_SWAP_SBO_SIZE diff -r fe24b68758bf -r 006e076a8db7 src/compare.c --- a/src/compare.c Fri Dec 19 17:24:18 2025 +0100 +++ b/src/compare.c Fri Dec 19 17:37:17 2025 +0100 @@ -291,16 +291,7 @@ } } -int cx_ccmp_memcmp( - const void *ptr1, - const void *ptr2, - void *size -) { - size_t n = *(size_t*)size; - return memcmp(ptr1, ptr2, n); -} - -int cx_ccmp_wrap( +int cx_cmp_wrap( const void *ptr1, const void *ptr2, void *w diff -r fe24b68758bf -r 006e076a8db7 src/cx/compare.h --- a/src/cx/compare.h Fri Dec 19 17:24:18 2025 +0100 +++ b/src/cx/compare.h Fri Dec 19 17:37:17 2025 +0100 @@ -534,18 +534,7 @@ cx_attr_nonnull cx_attr_nodiscard CX_EXPORT int cx_cmp_ptr(const void *ptr1, const void *ptr2); -/** - * A @c cx_compare_func2 compatible wrapper for @c memcmp(). - * - * @param ptr1 pointer one - * @param ptr2 pointer two - * @param n (@c size_t*) a pointer to the length - * @return the result of @c memcmp() - */ -cx_attr_nonnull cx_attr_nodiscard -CX_EXPORT int cx_ccmp_memcmp(const void *ptr1, const void *ptr2, void *n); - -/** Wraps a compare function for cx_ccmp_wrap. */ +/** Wraps a compare function for cx_cmp_wrap. */ typedef struct { /** The wrapped compare function */ cx_compare_func cmp; @@ -554,20 +543,14 @@ /** * A @c cx_compare_func2 wrapper for a @c cx_compare_func(). * - * This is not strictly compatible with a @c cx_compare_func2 because - * ISO C does not define conversions between function and object pointers. - * - * But it works on all tested platforms to cast a pointer to this function to - * a @c cx_compare_func2. - * * @param ptr1 pointer one * @param ptr2 pointer two * @param cmp_wrapper a pointer to a @c cx_compare_func_wrapper * @return the result of the invoked compare function - * @see cx_compare_func_wrapper_s + * @see cx_compare_func_wrapper */ cx_attr_nonnull cx_attr_nodiscard -CX_EXPORT int cx_ccmp_wrap(const void *ptr1, const void *ptr2, void* cmp_wrapper); +CX_EXPORT int cx_cmp_wrap(const void *ptr1, const void *ptr2, void* cmp_wrapper); #ifdef __cplusplus } // extern "C" diff -r fe24b68758bf -r 006e076a8db7 src/linked_list.c --- a/src/linked_list.c Fri Dec 19 17:24:18 2025 +0100 +++ b/src/linked_list.c Fri Dec 19 17:37:17 2025 +0100 @@ -105,7 +105,7 @@ ) { cx_compare_func_wrapper wrapper = {cmp_func}; return cx_linked_list_find_c(start, loc_advance, loc_data, - elem, found_index, cx_ccmp_wrap, &wrapper); + elem, found_index, cx_cmp_wrap, &wrapper); } void *cx_linked_list_first( @@ -420,7 +420,7 @@ cx_compare_func_wrapper wrapper = {cmp_func}; cx_linked_list_insert_sorted_chain_impl( begin, end, loc_prev, loc_next, - insert_begin, cx_ccmp_wrap, &wrapper, true); + insert_begin, cx_cmp_wrap, &wrapper, true); } int cx_linked_list_insert_unique( @@ -447,7 +447,7 @@ cx_compare_func_wrapper wrapper = {cmp_func}; return cx_linked_list_insert_sorted_chain_impl( begin, end, loc_prev, loc_next, - insert_begin, cx_ccmp_wrap, &wrapper, false); + insert_begin, cx_cmp_wrap, &wrapper, false); } void cx_linked_list_insert_sorted_c( @@ -717,7 +717,7 @@ cx_compare_func cmp_func ) { cx_compare_func_wrapper wrapper = {cmp_func}; - cx_linked_list_sort_c(begin, end, loc_prev, loc_next, loc_data, cx_ccmp_wrap, &wrapper); + cx_linked_list_sort_c(begin, end, loc_prev, loc_next, loc_data, cx_cmp_wrap, &wrapper); } int cx_linked_list_compare_c( @@ -753,7 +753,7 @@ ) { cx_compare_func_wrapper wrapper = {cmp_func}; return cx_linked_list_compare_c(begin_left, begin_right, - loc_advance, loc_data, cx_ccmp_wrap, &wrapper); + loc_advance, loc_data, cx_cmp_wrap, &wrapper); } void cx_linked_list_reverse(