diff -r ae61523bce20 -r 2f71f4ee247a ucx/cx/linked_list.h --- a/ucx/cx/linked_list.h Thu Oct 03 18:52:51 2024 +0200 +++ b/ucx/cx/linked_list.h Sun Oct 06 18:18:04 2024 +0200 @@ -50,9 +50,9 @@ extern unsigned cx_linked_list_swap_sbo_size; /** - * Allocates a linked list for storing elements with \p item_size bytes each. + * Allocates a linked list for storing elements with \p elem_size bytes each. * - * If \p item_size is CX_STORE_POINTERS, the created list will be created as if + * If \p elem_size is CX_STORE_POINTERS, the created list will be created as if * cxListStorePointers() was called immediately after creation and the compare * function will be automatically set to cx_cmp_ptr(), if none is given. * @@ -61,31 +61,31 @@ * @param comparator the comparator for the elements * (if \c NULL, and the list is not storing pointers, sort and find * functions will not work) - * @param item_size the size of each element in bytes + * @param elem_size the size of each element in bytes * @return the created list */ CxList *cxLinkedListCreate( - CxAllocator const *allocator, + const CxAllocator *allocator, cx_compare_func comparator, - size_t item_size + size_t elem_size ); /** - * Allocates a linked list for storing elements with \p item_size bytes each. + * Allocates a linked list for storing elements with \p elem_size bytes each. * * The list will use cxDefaultAllocator and no comparator function. If you want * to call functions that need a comparator, you must either set one immediately * after list creation or use cxLinkedListCreate(). * - * If \p item_size is CX_STORE_POINTERS, the created list will be created as if + * If \p elem_size is CX_STORE_POINTERS, the created list will be created as if * cxListStorePointers() was called immediately after creation and the compare * function will be automatically set to cx_cmp_ptr(). * - * @param item_size the size of each element in bytes + * @param elem_size the size of each element in bytes * @return the created list */ -#define cxLinkedListCreateSimple(item_size) \ - cxLinkedListCreate(NULL, NULL, item_size) +#define cxLinkedListCreateSimple(elem_size) \ + cxLinkedListCreate(NULL, NULL, elem_size) /** * Finds the node at a certain index. @@ -104,12 +104,13 @@ * @param index the search index * @return the node found at the specified index */ +__attribute__((__nonnull__)) void *cx_linked_list_at( - void const *start, + const void *start, size_t start_index, ptrdiff_t loc_advance, size_t index -) __attribute__((__nonnull__)); +); /** * Finds the index of an element within a linked list. @@ -121,13 +122,14 @@ * @param elem a pointer to the element to find * @return the index of the element or a negative value if it could not be found */ +__attribute__((__nonnull__)) ssize_t cx_linked_list_find( - void const *start, + const void *start, ptrdiff_t loc_advance, ptrdiff_t loc_data, cx_compare_func cmp_func, - void const *elem -) __attribute__((__nonnull__)); + const void *elem +); /** * Finds the node containing an element within a linked list. @@ -141,14 +143,15 @@ * @param elem a pointer to the element to find * @return the index of the element or a negative value if it could not be found */ +__attribute__((__nonnull__)) ssize_t cx_linked_list_find_node( void **result, - void const *start, + const void *start, ptrdiff_t loc_advance, ptrdiff_t loc_data, cx_compare_func cmp_func, - void const *elem -) __attribute__((__nonnull__)); + const void *elem +); /** * Finds the first node in a linked list. @@ -161,10 +164,11 @@ * @param loc_prev the location of the \c prev pointer * @return a pointer to the first node */ +__attribute__((__nonnull__)) void *cx_linked_list_first( - void const *node, + const void *node, ptrdiff_t loc_prev -) __attribute__((__nonnull__)); +); /** * Finds the last node in a linked list. @@ -177,10 +181,11 @@ * @param loc_next the location of the \c next pointer * @return a pointer to the last node */ +__attribute__((__nonnull__)) void *cx_linked_list_last( - void const *node, + const void *node, ptrdiff_t loc_next -) __attribute__((__nonnull__)); +); /** * Finds the predecessor of a node in case it is not linked. @@ -192,11 +197,12 @@ * @param node the successor of the node to find * @return the node or \c NULL if \p node has no predecessor */ +__attribute__((__nonnull__)) void *cx_linked_list_prev( - void const *begin, + const void *begin, ptrdiff_t loc_next, - void const *node -) __attribute__((__nonnull__)); + const void *node +); /** * Adds a new node to a linked list. @@ -210,13 +216,14 @@ * @param loc_next the location of a \c next pointer within your node struct (required) * @param new_node a pointer to the node that shall be appended */ +__attribute__((__nonnull__(5))) void cx_linked_list_add( void **begin, void **end, ptrdiff_t loc_prev, ptrdiff_t loc_next, void *new_node -) __attribute__((__nonnull__(5))); +); /** * Prepends a new node to a linked list. @@ -230,13 +237,14 @@ * @param loc_next the location of a \c next pointer within your node struct (required) * @param new_node a pointer to the node that shall be prepended */ +__attribute__((__nonnull__(5))) void cx_linked_list_prepend( void **begin, void **end, ptrdiff_t loc_prev, ptrdiff_t loc_next, void *new_node -) __attribute__((__nonnull__(5))); +); /** * Links two nodes. @@ -246,12 +254,13 @@ * @param loc_prev the location of a \c prev pointer within your node struct (negative if your struct does not have one) * @param loc_next the location of a \c next pointer within your node struct (required) */ +__attribute__((__nonnull__)) void cx_linked_list_link( void *left, void *right, ptrdiff_t loc_prev, ptrdiff_t loc_next -) __attribute__((__nonnull__)); +); /** * Unlinks two nodes. @@ -263,12 +272,13 @@ * @param loc_prev the location of a \c prev pointer within your node struct (negative if your struct does not have one) * @param loc_next the location of a \c next pointer within your node struct (required) */ +__attribute__((__nonnull__)) void cx_linked_list_unlink( void *left, void *right, ptrdiff_t loc_prev, ptrdiff_t loc_next -) __attribute__((__nonnull__)); +); /** * Inserts a new node after a given node of a linked list. @@ -282,8 +292,9 @@ * @param loc_prev the location of a \c prev pointer within your node struct (negative if your struct does not have one) * @param loc_next the location of a \c next pointer within your node struct (required) * @param node the node after which to insert (\c NULL if you want to prepend the node to the list) - * @param new_node a pointer to the node that shall be prepended + * @param new_node a pointer to the node that shall be inserted */ +__attribute__((__nonnull__(6))) void cx_linked_list_insert( void **begin, void **end, @@ -291,7 +302,7 @@ ptrdiff_t loc_next, void *node, void *new_node -) __attribute__((__nonnull__(6))); +); /** * Inserts a chain of nodes after a given node of a linked list. @@ -313,6 +324,7 @@ * @param insert_begin a pointer to the first node of the chain that shall be inserted * @param insert_end a pointer to the last node of the chain (or NULL if the last node shall be determined) */ +__attribute__((__nonnull__(6))) void cx_linked_list_insert_chain( void **begin, void **end, @@ -321,7 +333,60 @@ void *node, void *insert_begin, void *insert_end -) __attribute__((__nonnull__(6))); +); + +/** + * Inserts a node into a sorted linked list. + * The new node must not be part of any list already. + * + * If the list starting with the node pointed to by \p begin is not sorted + * already, the behavior is undefined. + * + * @param begin a pointer to the begin node pointer (required) + * @param end a pointer to the end node pointer (if your list has one) + * @param loc_prev the location of a \c prev pointer within your node struct (negative if your struct does not have one) + * @param loc_next the location of a \c next pointer within your node struct (required) + * @param new_node a pointer to the node that shall be inserted + * @param cmp_func a compare function that will receive the node pointers + */ +__attribute__((__nonnull__(1, 5, 6))) +void cx_linked_list_insert_sorted( + void **begin, + void **end, + ptrdiff_t loc_prev, + ptrdiff_t loc_next, + void *new_node, + cx_compare_func cmp_func +); + +/** + * Inserts a chain of nodes into a sorted linked list. + * The chain must not be part of any list already. + * + * If either the list starting with the node pointed to by \p begin or the list + * starting with \p insert_begin is not sorted, the behavior is undefined. + * + * \attention In contrast to cx_linked_list_insert_chain(), the source chain + * will be broken and inserted into the target list so that the resulting list + * will be sorted according to \p cmp_func. That means, each node in the source + * chain may be re-linked with nodes from the target list. + * + * @param begin a pointer to the begin node pointer (required) + * @param end a pointer to the end node pointer (if your list has one) + * @param loc_prev the location of a \c prev pointer within your node struct (negative if your struct does not have one) + * @param loc_next the location of a \c next pointer within your node struct (required) + * @param insert_begin a pointer to the first node of the chain that shall be inserted + * @param cmp_func a compare function that will receive the node pointers + */ +__attribute__((__nonnull__(1, 5, 6))) +void cx_linked_list_insert_sorted_chain( + void **begin, + void **end, + ptrdiff_t loc_prev, + ptrdiff_t loc_next, + void *insert_begin, + cx_compare_func cmp_func +); /** * Removes a node from the linked list. @@ -342,13 +407,14 @@ * @param loc_next the location of a \c next pointer within your node struct (required) * @param node the node to remove */ +__attribute__((__nonnull__(5))) void cx_linked_list_remove( void **begin, void **end, ptrdiff_t loc_prev, ptrdiff_t loc_next, void *node -) __attribute__((__nonnull__(5))); +); /** @@ -358,7 +424,7 @@ * @return the size of the list or zero if \p node is \c NULL */ size_t cx_linked_list_size( - void const *node, + const void *node, ptrdiff_t loc_next ); @@ -384,6 +450,7 @@ * @param loc_data the location of the \c data pointer within your node struct * @param cmp_func the compare function defining the sort order */ +__attribute__((__nonnull__(1, 6))) void cx_linked_list_sort( void **begin, void **end, @@ -391,7 +458,7 @@ ptrdiff_t loc_next, ptrdiff_t loc_data, cx_compare_func cmp_func -) __attribute__((__nonnull__(1, 6))); +); /** @@ -407,13 +474,14 @@ * @return the first non-zero result of invoking \p cmp_func or: negative if the left list is smaller than the * right list, positive if the left list is larger than the right list, zero if both lists are equal. */ +__attribute__((__nonnull__(5))) int cx_linked_list_compare( - void const *begin_left, - void const *begin_right, + const void *begin_left, + const void *begin_right, ptrdiff_t loc_advance, ptrdiff_t loc_data, cx_compare_func cmp_func -) __attribute__((__nonnull__(5))); +); /** * Reverses the order of the nodes in a linked list. @@ -423,12 +491,13 @@ * @param loc_prev the location of a \c prev pointer within your node struct (negative if your struct does not have one) * @param loc_next the location of a \c next pointer within your node struct (required) */ +__attribute__((__nonnull__(1))) void cx_linked_list_reverse( void **begin, void **end, ptrdiff_t loc_prev, ptrdiff_t loc_next -) __attribute__((__nonnull__(1))); +); #ifdef __cplusplus } // extern "C"