ucx/cx/linked_list.h

changeset 1040
473d8cb58a6c
parent 1016
ccde46662db7
equal deleted inserted replaced
1039:6691e007cef7 1040:473d8cb58a6c
36 #ifndef UCX_LINKED_LIST_H 36 #ifndef UCX_LINKED_LIST_H
37 #define UCX_LINKED_LIST_H 37 #define UCX_LINKED_LIST_H
38 38
39 #include "common.h" 39 #include "common.h"
40 #include "list.h" 40 #include "list.h"
41
42 #ifdef __cplusplus
43 extern "C" {
44 #endif
45 41
46 /** 42 /**
47 * Metadata for a linked list. 43 * Metadata for a linked list.
48 */ 44 */
49 typedef struct cx_linked_list_s { 45 typedef struct cx_linked_list_s {
92 * @param allocator the allocator for allocating the list nodes 88 * @param allocator the allocator for allocating the list nodes
93 * (if @c NULL, the cxDefaultAllocator will be used) 89 * (if @c NULL, the cxDefaultAllocator will be used)
94 * @param elem_size the size of each element in bytes 90 * @param elem_size the size of each element in bytes
95 * @return the created list 91 * @return the created list
96 */ 92 */
97 cx_attr_nodiscard cx_attr_malloc cx_attr_dealloc(cxListFree, 1) 93 CX_EXTERN CX_NODISCARD CX_MALLOC CX_DEALLOC(cxListFree, 1)
98 CX_EXPORT CxList *cxLinkedListCreate(const CxAllocator *allocator, 94 CxList *cxLinkedListCreate(const CxAllocator *allocator,
99 size_t elem_size); 95 size_t elem_size);
100 96
101 /** 97 /**
102 * Instructs the linked list to reserve extra data in each node. 98 * Instructs the linked list to reserve extra data in each node.
103 * 99 *
110 * needs to store extra data in each node. 106 * needs to store extra data in each node.
111 * 107 *
112 * @param list the list (must be a linked list) 108 * @param list the list (must be a linked list)
113 * @param len the length of the extra data 109 * @param len the length of the extra data
114 */ 110 */
115 cx_attr_nonnull 111 CX_EXTERN CX_NONNULL
116 CX_EXPORT void cx_linked_list_extra_data(cx_linked_list *list, size_t len); 112 void cx_linked_list_extra_data(cx_linked_list *list, size_t len);
117 113
118 /** 114 /**
119 * Finds the node at a certain index. 115 * Finds the node at a certain index.
120 * 116 *
121 * This function can be used to start at an arbitrary position within the list. 117 * This function can be used to start at an arbitrary position within the list.
130 * @param start_index the start index 126 * @param start_index the start index
131 * @param loc_advance the location of the pointer to advance 127 * @param loc_advance the location of the pointer to advance
132 * @param index the search index 128 * @param index the search index
133 * @return the node found at the specified index 129 * @return the node found at the specified index
134 */ 130 */
135 cx_attr_nonnull cx_attr_nodiscard 131 CX_EXTERN CX_NONNULL CX_NODISCARD
136 CX_EXPORT void *cx_linked_list_at(const void *start,size_t start_index, 132 void *cx_linked_list_at(const void *start,size_t start_index,
137 ptrdiff_t loc_advance, size_t index); 133 ptrdiff_t loc_advance, size_t index);
138 134
139 /** 135 /**
140 * Finds the node containing an element within a linked list. 136 * Finds the node containing an element within a linked list.
141 * 137 *
146 * @param found_index an optional pointer where the index of the found node 142 * @param found_index an optional pointer where the index of the found node
147 * (given that @p start has index 0) is stored 143 * (given that @p start has index 0) is stored
148 * @param cmp_func a compare function to compare @p elem against the node data 144 * @param cmp_func a compare function to compare @p elem against the node data
149 * @return a pointer to the found node or @c NULL if no matching node was found 145 * @return a pointer to the found node or @c NULL if no matching node was found
150 */ 146 */
151 cx_attr_nonnull_arg(1, 4, 6) 147 CX_EXTERN CX_NONNULL_ARG(1, 4, 6)
152 CX_EXPORT void *cx_linked_list_find(const void *start, ptrdiff_t loc_advance, 148 void *cx_linked_list_find(const void *start, ptrdiff_t loc_advance,
153 ptrdiff_t loc_data, const void *elem, size_t *found_index, 149 ptrdiff_t loc_data, const void *elem, size_t *found_index,
154 cx_compare_func cmp_func); 150 cx_compare_func cmp_func);
155 151
156 /** 152 /**
157 * Finds the node containing an element within a linked list. 153 * Finds the node containing an element within a linked list.
164 * (given that @p start has index 0) is stored 160 * (given that @p start has index 0) is stored
165 * @param cmp_func a compare function to compare @p elem against the node data 161 * @param cmp_func a compare function to compare @p elem against the node data
166 * @param context additional context for the compare function 162 * @param context additional context for the compare function
167 * @return a pointer to the found node or @c NULL if no matching node was found 163 * @return a pointer to the found node or @c NULL if no matching node was found
168 */ 164 */
169 cx_attr_nonnull_arg(1, 4, 6) 165 CX_EXTERN CX_NONNULL_ARG(1, 4, 6)
170 CX_EXPORT void *cx_linked_list_find_c(const void *start, ptrdiff_t loc_advance, 166 void *cx_linked_list_find_c(const void *start, ptrdiff_t loc_advance,
171 ptrdiff_t loc_data, const void *elem, size_t *found_index, 167 ptrdiff_t loc_data, const void *elem, size_t *found_index,
172 cx_compare_func2 cmp_func, void *context); 168 cx_compare_func2 cmp_func, void *context);
173 169
174 /** 170 /**
175 * Finds the first node in a linked list. 171 * Finds the first node in a linked list.
180 * 176 *
181 * @param node a pointer to a node in the list 177 * @param node a pointer to a node in the list
182 * @param loc_prev the location of the @c prev pointer 178 * @param loc_prev the location of the @c prev pointer
183 * @return a pointer to the first node 179 * @return a pointer to the first node
184 */ 180 */
185 cx_attr_nonnull cx_attr_returns_nonnull 181 CX_EXTERN CX_NONNULL CX_RETURNS_NONNULL
186 CX_EXPORT void *cx_linked_list_first(const void *node, ptrdiff_t loc_prev); 182 void *cx_linked_list_first(const void *node, ptrdiff_t loc_prev);
187 183
188 /** 184 /**
189 * Finds the last node in a linked list. 185 * Finds the last node in a linked list.
190 * 186 *
191 * The function starts with the pointer denoted by @p node and traverses the list 187 * The function starts with the pointer denoted by @p node and traverses the list
194 * 190 *
195 * @param node a pointer to a node in the list 191 * @param node a pointer to a node in the list
196 * @param loc_next the location of the @c next pointer 192 * @param loc_next the location of the @c next pointer
197 * @return a pointer to the last node 193 * @return a pointer to the last node
198 */ 194 */
199 cx_attr_nonnull cx_attr_returns_nonnull 195 CX_EXTERN CX_NONNULL CX_RETURNS_NONNULL
200 CX_EXPORT void *cx_linked_list_last(const void *node, ptrdiff_t loc_next); 196 void *cx_linked_list_last(const void *node, ptrdiff_t loc_next);
201 197
202 /** 198 /**
203 * Finds the predecessor of a node in case it is not linked. 199 * Finds the predecessor of a node in case it is not linked.
204 * 200 *
205 * @remark If @p node is not contained in the list starting with @p begin, the behavior is undefined. 201 * @remark If @p node is not contained in the list starting with @p begin, the behavior is undefined.
207 * @param begin the node where to start the search 203 * @param begin the node where to start the search
208 * @param loc_next the location of the @c next pointer 204 * @param loc_next the location of the @c next pointer
209 * @param node the successor of the node to find 205 * @param node the successor of the node to find
210 * @return the node or @c NULL if @p node has no predecessor 206 * @return the node or @c NULL if @p node has no predecessor
211 */ 207 */
212 cx_attr_nonnull 208 CX_EXTERN CX_NONNULL
213 CX_EXPORT void *cx_linked_list_prev(const void *begin, ptrdiff_t loc_next, const void *node); 209 void *cx_linked_list_prev(const void *begin, ptrdiff_t loc_next, const void *node);
214 210
215 /** 211 /**
216 * Adds a new node to a linked list. 212 * Adds a new node to a linked list.
217 * The node must not be part of any list yet. 213 * The node must not be part of any list yet.
218 * 214 *
222 * @param end a pointer to the end node pointer (if your list has one) 218 * @param end a pointer to the end node pointer (if your list has one)
223 * @param loc_prev the location of a @c prev pointer within your node struct (negative if your struct does not have one) 219 * @param loc_prev the location of a @c prev pointer within your node struct (negative if your struct does not have one)
224 * @param loc_next the location of a @c next pointer within your node struct (required) 220 * @param loc_next the location of a @c next pointer within your node struct (required)
225 * @param new_node a pointer to the node that shall be appended 221 * @param new_node a pointer to the node that shall be appended
226 */ 222 */
227 cx_attr_nonnull_arg(5) 223 CX_EXTERN CX_NONNULL_ARG(5)
228 CX_EXPORT void cx_linked_list_add(void **begin, void **end, ptrdiff_t loc_prev, ptrdiff_t loc_next, void *new_node); 224 void cx_linked_list_add(void **begin, void **end, ptrdiff_t loc_prev, ptrdiff_t loc_next, void *new_node);
229 225
230 /** 226 /**
231 * Prepends a new node to a linked list. 227 * Prepends a new node to a linked list.
232 * The node must not be part of any list yet. 228 * The node must not be part of any list yet.
233 * 229 *
237 * @param end a pointer to the end node pointer (if your list has one) 233 * @param end a pointer to the end node pointer (if your list has one)
238 * @param loc_prev the location of a @c prev pointer within your node struct (negative if your struct does not have one) 234 * @param loc_prev the location of a @c prev pointer within your node struct (negative if your struct does not have one)
239 * @param loc_next the location of a @c next pointer within your node struct (required) 235 * @param loc_next the location of a @c next pointer within your node struct (required)
240 * @param new_node a pointer to the node that shall be prepended 236 * @param new_node a pointer to the node that shall be prepended
241 */ 237 */
242 cx_attr_nonnull_arg(5) 238 CX_EXTERN CX_NONNULL_ARG(5)
243 CX_EXPORT void cx_linked_list_prepend(void **begin, void **end, ptrdiff_t loc_prev, ptrdiff_t loc_next, void *new_node); 239 void cx_linked_list_prepend(void **begin, void **end, ptrdiff_t loc_prev, ptrdiff_t loc_next, void *new_node);
244 240
245 /** 241 /**
246 * Links two nodes. 242 * Links two nodes.
247 * 243 *
248 * @param left the new predecessor of @p right 244 * @param left the new predecessor of @p right
249 * @param right the new successor of @p left 245 * @param right the new successor of @p left
250 * @param loc_prev the location of a @c prev pointer within your node struct (negative if your struct does not have one) 246 * @param loc_prev the location of a @c prev pointer within your node struct (negative if your struct does not have one)
251 * @param loc_next the location of a @c next pointer within your node struct (required) 247 * @param loc_next the location of a @c next pointer within your node struct (required)
252 */ 248 */
253 cx_attr_nonnull 249 CX_EXTERN CX_NONNULL
254 CX_EXPORT void cx_linked_list_link(void *left, void *right, ptrdiff_t loc_prev, ptrdiff_t loc_next); 250 void cx_linked_list_link(void *left, void *right, ptrdiff_t loc_prev, ptrdiff_t loc_next);
255 251
256 /** 252 /**
257 * Unlinks two nodes. 253 * Unlinks two nodes.
258 * 254 *
259 * If right is not the successor of left, the behavior is undefined. 255 * If right is not the successor of left, the behavior is undefined.
261 * @param left the predecessor of @p right 257 * @param left the predecessor of @p right
262 * @param right the successor of @p left 258 * @param right the successor of @p left
263 * @param loc_prev the location of a @c prev pointer within your node struct (negative if your struct does not have one) 259 * @param loc_prev the location of a @c prev pointer within your node struct (negative if your struct does not have one)
264 * @param loc_next the location of a @c next pointer within your node struct (required) 260 * @param loc_next the location of a @c next pointer within your node struct (required)
265 */ 261 */
266 cx_attr_nonnull 262 CX_EXTERN CX_NONNULL
267 CX_EXPORT void cx_linked_list_unlink(void *left, void *right, ptrdiff_t loc_prev, ptrdiff_t loc_next); 263 void cx_linked_list_unlink(void *left, void *right, ptrdiff_t loc_prev, ptrdiff_t loc_next);
268 264
269 /** 265 /**
270 * Inserts a new node after a given node of a linked list. 266 * Inserts a new node after a given node of a linked list.
271 * The new node must not be part of any list yet. 267 * The new node must not be part of any list yet.
272 * 268 *
278 * @param loc_prev the location of a @c prev pointer within your node struct (negative if your struct does not have one) 274 * @param loc_prev the location of a @c prev pointer within your node struct (negative if your struct does not have one)
279 * @param loc_next the location of a @c next pointer within your node struct (required) 275 * @param loc_next the location of a @c next pointer within your node struct (required)
280 * @param node the node after which to insert (@c NULL if you want to prepend the node to the list) 276 * @param node the node after which to insert (@c NULL if you want to prepend the node to the list)
281 * @param new_node a pointer to the node that shall be inserted 277 * @param new_node a pointer to the node that shall be inserted
282 */ 278 */
283 cx_attr_nonnull_arg(6) 279 CX_EXTERN CX_NONNULL_ARG(6)
284 CX_EXPORT void cx_linked_list_insert(void **begin, void **end, 280 void cx_linked_list_insert(void **begin, void **end,
285 ptrdiff_t loc_prev, ptrdiff_t loc_next, void *node, void *new_node); 281 ptrdiff_t loc_prev, ptrdiff_t loc_next, void *node, void *new_node);
286 282
287 /** 283 /**
288 * Inserts a chain of nodes after a given node of a linked list. 284 * Inserts a chain of nodes after a given node of a linked list.
289 * The chain must not be part of any list yet. 285 * The chain must not be part of any list yet.
302 * @param loc_next the location of a @c next pointer within your node struct (required) 298 * @param loc_next the location of a @c next pointer within your node struct (required)
303 * @param node the node after which to insert (@c NULL to prepend the chain to the list) 299 * @param node the node after which to insert (@c NULL to prepend the chain to the list)
304 * @param insert_begin a pointer to the first node of the chain that shall be inserted 300 * @param insert_begin a pointer to the first node of the chain that shall be inserted
305 * @param insert_end a pointer to the last node of the chain (or NULL if the last node shall be determined) 301 * @param insert_end a pointer to the last node of the chain (or NULL if the last node shall be determined)
306 */ 302 */
307 cx_attr_nonnull_arg(6) 303 CX_EXTERN CX_NONNULL_ARG(6)
308 CX_EXPORT void cx_linked_list_insert_chain(void **begin, void **end, 304 void cx_linked_list_insert_chain(void **begin, void **end,
309 ptrdiff_t loc_prev, ptrdiff_t loc_next, void *node, void *insert_begin, void *insert_end); 305 ptrdiff_t loc_prev, ptrdiff_t loc_next, void *node, void *insert_begin, void *insert_end);
310 306
311 /** 307 /**
312 * Inserts a node into a sorted linked list. 308 * Inserts a node into a sorted linked list.
313 * The new node must not be part of any list yet. 309 * The new node must not be part of any list yet.
320 * @param loc_prev the location of a @c prev pointer within your node struct (negative if your struct does not have one) 316 * @param loc_prev the location of a @c prev pointer within your node struct (negative if your struct does not have one)
321 * @param loc_next the location of a @c next pointer within your node struct (required) 317 * @param loc_next the location of a @c next pointer within your node struct (required)
322 * @param new_node a pointer to the node that shall be inserted 318 * @param new_node a pointer to the node that shall be inserted
323 * @param cmp_func a compare function that will receive the node pointers 319 * @param cmp_func a compare function that will receive the node pointers
324 */ 320 */
325 cx_attr_nonnull_arg(1, 5, 6) 321 CX_EXTERN CX_NONNULL_ARG(1, 5, 6)
326 CX_EXPORT void cx_linked_list_insert_sorted(void **begin, void **end, 322 void cx_linked_list_insert_sorted(void **begin, void **end,
327 ptrdiff_t loc_prev, ptrdiff_t loc_next, void *new_node, cx_compare_func cmp_func); 323 ptrdiff_t loc_prev, ptrdiff_t loc_next, void *new_node, cx_compare_func cmp_func);
328 324
329 /** 325 /**
330 * Inserts a chain of nodes into a sorted linked list. 326 * Inserts a chain of nodes into a sorted linked list.
331 * The chain must not be part of any list yet. 327 * The chain must not be part of any list yet.
343 * @param loc_prev the location of a @c prev pointer within your node struct (negative if your struct does not have one) 339 * @param loc_prev the location of a @c prev pointer within your node struct (negative if your struct does not have one)
344 * @param loc_next the location of a @c next pointer within your node struct (required) 340 * @param loc_next the location of a @c next pointer within your node struct (required)
345 * @param insert_begin a pointer to the first node of the chain that shall be inserted 341 * @param insert_begin a pointer to the first node of the chain that shall be inserted
346 * @param cmp_func a compare function that will receive the node pointers 342 * @param cmp_func a compare function that will receive the node pointers
347 */ 343 */
348 cx_attr_nonnull_arg(1, 5, 6) 344 CX_EXTERN CX_NONNULL_ARG(1, 5, 6)
349 CX_EXPORT void cx_linked_list_insert_sorted_chain(void **begin, void **end, 345 void cx_linked_list_insert_sorted_chain(void **begin, void **end,
350 ptrdiff_t loc_prev, ptrdiff_t loc_next, void *insert_begin, cx_compare_func cmp_func); 346 ptrdiff_t loc_prev, ptrdiff_t loc_next, void *insert_begin, cx_compare_func cmp_func);
351 347
352 /** 348 /**
353 * Inserts a node into a sorted linked list if no other node with the same value already exists. 349 * Inserts a node into a sorted linked list if no other node with the same value already exists.
354 * The new node must not be part of any list yet. 350 * The new node must not be part of any list yet.
363 * @param new_node a pointer to the node that shall be inserted 359 * @param new_node a pointer to the node that shall be inserted
364 * @param cmp_func a compare function that will receive the node pointers 360 * @param cmp_func a compare function that will receive the node pointers
365 * @retval zero when the node was inserted 361 * @retval zero when the node was inserted
366 * @retval non-zero when a node with the same value already exists 362 * @retval non-zero when a node with the same value already exists
367 */ 363 */
368 cx_attr_nonnull_arg(1, 5, 6) 364 CX_EXTERN CX_NONNULL_ARG(1, 5, 6)
369 CX_EXPORT int cx_linked_list_insert_unique(void **begin, void **end, 365 int cx_linked_list_insert_unique(void **begin, void **end,
370 ptrdiff_t loc_prev, ptrdiff_t loc_next, void *new_node, cx_compare_func cmp_func); 366 ptrdiff_t loc_prev, ptrdiff_t loc_next, void *new_node, cx_compare_func cmp_func);
371 367
372 /** 368 /**
373 * Inserts a chain of nodes into a sorted linked list, avoiding duplicates. 369 * Inserts a chain of nodes into a sorted linked list, avoiding duplicates.
374 * The chain must not be part of any list yet. 370 * The chain must not be part of any list yet.
385 * @param loc_next the location of a @c next pointer within your node struct (required) 381 * @param loc_next the location of a @c next pointer within your node struct (required)
386 * @param insert_begin a pointer to the first node of the chain that shall be inserted 382 * @param insert_begin a pointer to the first node of the chain that shall be inserted
387 * @param cmp_func a compare function that will receive the node pointers 383 * @param cmp_func a compare function that will receive the node pointers
388 * @return a pointer to a new chain with all duplicates that were not inserted (or @c NULL when there were no duplicates) 384 * @return a pointer to a new chain with all duplicates that were not inserted (or @c NULL when there were no duplicates)
389 */ 385 */
390 cx_attr_nonnull_arg(1, 5, 6) cx_attr_nodiscard 386 CX_EXTERN CX_NONNULL_ARG(1, 5, 6) CX_NODISCARD
391 CX_EXPORT void *cx_linked_list_insert_unique_chain(void **begin, void **end, 387 void *cx_linked_list_insert_unique_chain(void **begin, void **end,
392 ptrdiff_t loc_prev, ptrdiff_t loc_next, void *insert_begin, cx_compare_func cmp_func); 388 ptrdiff_t loc_prev, ptrdiff_t loc_next, void *insert_begin, cx_compare_func cmp_func);
389
390 /**
391 * Inserts a node into a sorted linked list.
392 * The new node must not be part of any list yet.
393 *
394 * If the list starting with the node pointed to by @p begin is not sorted
395 * already, the behavior is undefined.
396 *
397 * @param begin a pointer to the beginning node pointer (required)
398 * @param end a pointer to the end node pointer (if your list has one)
399 * @param loc_prev the location of a @c prev pointer within your node struct (negative if your struct does not have one)
400 * @param loc_next the location of a @c next pointer within your node struct (required)
401 * @param new_node a pointer to the node that shall be inserted
402 * @param cmp_func a compare function that will receive the node pointers
403 * @param context context for the compare function
404 */
405 CX_EXTERN CX_NONNULL_ARG(1, 5, 6)
406 void cx_linked_list_insert_sorted_c(void **begin, void **end,
407 ptrdiff_t loc_prev, ptrdiff_t loc_next, void *new_node, cx_compare_func2 cmp_func, void *context);
408
409 /**
410 * Inserts a chain of nodes into a sorted linked list.
411 * The chain must not be part of any list yet.
412 *
413 * If either the list starting with the node pointed to by @p begin or the list
414 * starting with @p insert_begin is not sorted, the behavior is undefined.
415 *
416 * @attention In contrast to cx_linked_list_insert_chain(), the source chain
417 * will be broken and inserted into the target list so that the resulting list
418 * will be sorted according to @p cmp_func. That means each node in the source
419 * chain may be re-linked with nodes from the target list.
420 *
421 * @param begin a pointer to the beginning node pointer (required)
422 * @param end a pointer to the end node pointer (if your list has one)
423 * @param loc_prev the location of a @c prev pointer within your node struct (negative if your struct does not have one)
424 * @param loc_next the location of a @c next pointer within your node struct (required)
425 * @param insert_begin a pointer to the first node of the chain that shall be inserted
426 * @param cmp_func a compare function that will receive the node pointers
427 * @param context context for the compare function
428 */
429 CX_EXTERN CX_NONNULL_ARG(1, 5, 6)
430 void cx_linked_list_insert_sorted_chain_c(void **begin, void **end,
431 ptrdiff_t loc_prev, ptrdiff_t loc_next, void *insert_begin, cx_compare_func2 cmp_func, void *context);
432
433 /**
434 * Inserts a node into a sorted linked list if no other node with the same value already exists.
435 * The new node must not be part of any list yet.
436 *
437 * If the list starting with the node pointed to by @p begin is not sorted
438 * already, the behavior is undefined.
439 *
440 * @param begin a pointer to the beginning node pointer (required)
441 * @param end a pointer to the end node pointer (if your list has one)
442 * @param loc_prev the location of a @c prev pointer within your node struct (negative if your struct does not have one)
443 * @param loc_next the location of a @c next pointer within your node struct (required)
444 * @param new_node a pointer to the node that shall be inserted
445 * @param cmp_func a compare function that will receive the node pointers
446 * @param context the context for the compare function
447 * @retval zero when the node was inserted
448 * @retval non-zero when a node with the same value already exists
449 */
450 CX_EXTERN CX_NONNULL_ARG(1, 5, 6)
451 int cx_linked_list_insert_unique_c(void **begin, void **end,
452 ptrdiff_t loc_prev, ptrdiff_t loc_next, void *new_node, cx_compare_func2 cmp_func, void *context);
453
454 /**
455 * Inserts a chain of nodes into a sorted linked list, avoiding duplicates.
456 * The chain must not be part of any list yet.
457 *
458 * If either the list starting with the node pointed to by @p begin or the list
459 * starting with @p insert_begin is not sorted, the behavior is undefined.
460 *
461 * @attention In contrast to cx_linked_list_insert_sorted(), not all nodes of the
462 * chain might be added. This function returns a new chain consisting of all the duplicates.
463 *
464 * @param begin a pointer to the beginning node pointer (required)
465 * @param end a pointer to the end node pointer (if your list has one)
466 * @param loc_prev the location of a @c prev pointer within your node struct (negative if your struct does not have one)
467 * @param loc_next the location of a @c next pointer within your node struct (required)
468 * @param insert_begin a pointer to the first node of the chain that shall be inserted
469 * @param cmp_func a compare function that will receive the node pointers
470 * @param context context for the compare function
471 * @return a pointer to a new chain with all duplicates that were not inserted (or @c NULL when there were no duplicates)
472 */
473 CX_EXTERN CX_NONNULL_ARG(1, 5, 6) CX_NODISCARD
474 void *cx_linked_list_insert_unique_chain_c(void **begin, void **end,
475 ptrdiff_t loc_prev, ptrdiff_t loc_next, void *insert_begin, cx_compare_func2 cmp_func, void *context);
393 476
394 /** 477 /**
395 * Removes a chain of nodes from the linked list. 478 * Removes a chain of nodes from the linked list.
396 * 479 *
397 * If one of the nodes to remove is the beginning (resp. end) node of the list, and if @p begin (resp. @p end) 480 * If one of the nodes to remove is the beginning (resp. end) node of the list, and if @p begin (resp. @p end)
410 * @param loc_next the location of a @c next pointer within your node struct (required) 493 * @param loc_next the location of a @c next pointer within your node struct (required)
411 * @param node the start node of the chain 494 * @param node the start node of the chain
412 * @param num the number of nodes to remove 495 * @param num the number of nodes to remove
413 * @return the actual number of nodes that were removed (can be less when the list did not have enough nodes) 496 * @return the actual number of nodes that were removed (can be less when the list did not have enough nodes)
414 */ 497 */
415 cx_attr_nonnull_arg(5) 498 CX_EXTERN CX_NONNULL_ARG(5)
416 CX_EXPORT size_t cx_linked_list_remove_chain(void **begin, void **end, 499 size_t cx_linked_list_remove_chain(void **begin, void **end,
417 ptrdiff_t loc_prev, ptrdiff_t loc_next, void *node, size_t num); 500 ptrdiff_t loc_prev, ptrdiff_t loc_next, void *node, size_t num);
418 501
419 /** 502 /**
420 * Removes a node from the linked list. 503 * Removes a node from the linked list.
421 * 504 *
433 * @param end a pointer to the end node pointer (optional) 516 * @param end a pointer to the end node pointer (optional)
434 * @param loc_prev the location of a @c prev pointer within your node struct (negative if your struct does not have one) 517 * @param loc_prev the location of a @c prev pointer within your node struct (negative if your struct does not have one)
435 * @param loc_next the location of a @c next pointer within your node struct (required) 518 * @param loc_next the location of a @c next pointer within your node struct (required)
436 * @param node the node to remove 519 * @param node the node to remove
437 */ 520 */
438 cx_attr_nonnull_arg(5) 521 CX_EXTERN CX_NONNULL_ARG(5)
439 CX_EXPORT void cx_linked_list_remove(void **begin, void **end, 522 void cx_linked_list_remove(void **begin, void **end,
440 ptrdiff_t loc_prev, ptrdiff_t loc_next, void *node); 523 ptrdiff_t loc_prev, ptrdiff_t loc_next, void *node);
441 524
442 /** 525 /**
443 * Determines the size of a linked list starting with @p node. 526 * Determines the size of a linked list starting with @p node.
444 * 527 *
445 * @param node the first node 528 * @param node the first node
446 * @param loc_next the location of the @c next pointer within the node struct 529 * @param loc_next the location of the @c next pointer within the node struct
447 * @return the size of the list or zero if @p node is @c NULL 530 * @return the size of the list or zero if @p node is @c NULL
448 */ 531 */
449 cx_attr_nodiscard 532 CX_EXTERN CX_NODISCARD
450 CX_EXPORT size_t cx_linked_list_size(const void *node, ptrdiff_t loc_next); 533 size_t cx_linked_list_size(const void *node, ptrdiff_t loc_next);
451 534
452 /** 535 /**
453 * Sorts a linked list based on a comparison function. 536 * Sorts a linked list based on a comparison function.
454 * 537 *
455 * @note This is a recursive function with at most logarithmic recursion depth. 538 * @note This is a recursive function with at most logarithmic recursion depth.
459 * @param loc_prev the location of a @c prev pointer within your node struct (negative if not present) 542 * @param loc_prev the location of a @c prev pointer within your node struct (negative if not present)
460 * @param loc_next the location of a @c next pointer within your node struct (required) 543 * @param loc_next the location of a @c next pointer within your node struct (required)
461 * @param loc_data the location of the @c data pointer within your node struct 544 * @param loc_data the location of the @c data pointer within your node struct
462 * @param cmp_func the compare function defining the sort order 545 * @param cmp_func the compare function defining the sort order
463 */ 546 */
464 cx_attr_nonnull_arg(1, 6) 547 CX_EXTERN CX_NONNULL_ARG(1, 6)
465 CX_EXPORT void cx_linked_list_sort(void **begin, void **end, 548 void cx_linked_list_sort(void **begin, void **end,
466 ptrdiff_t loc_prev, ptrdiff_t loc_next, ptrdiff_t loc_data, cx_compare_func cmp_func); 549 ptrdiff_t loc_prev, ptrdiff_t loc_next, ptrdiff_t loc_data, cx_compare_func cmp_func);
467 550
468 /** 551 /**
469 * Sorts a linked list based on a comparison function. 552 * Sorts a linked list based on a comparison function.
470 * 553 *
476 * @param loc_next the location of a @c next pointer within your node struct (required) 559 * @param loc_next the location of a @c next pointer within your node struct (required)
477 * @param loc_data the location of the @c data pointer within your node struct 560 * @param loc_data the location of the @c data pointer within your node struct
478 * @param cmp_func the compare function defining the sort order 561 * @param cmp_func the compare function defining the sort order
479 * @param context additional context for the compare function 562 * @param context additional context for the compare function
480 */ 563 */
481 cx_attr_nonnull_arg(1, 6) 564 CX_EXTERN CX_NONNULL_ARG(1, 6)
482 CX_EXPORT void cx_linked_list_sort_c(void **begin, void **end, 565 void cx_linked_list_sort_c(void **begin, void **end,
483 ptrdiff_t loc_prev, ptrdiff_t loc_next, ptrdiff_t loc_data, cx_compare_func2 cmp_func, void *context); 566 ptrdiff_t loc_prev, ptrdiff_t loc_next, ptrdiff_t loc_data, cx_compare_func2 cmp_func, void *context);
484
485 567
486 /** 568 /**
487 * Compares two lists element wise. 569 * Compares two lists element wise.
488 * 570 *
489 * @attention Both lists must have the same structure. 571 * @attention Both lists must have the same structure.
494 * @param loc_data the location of the @c data pointer within your node struct 576 * @param loc_data the location of the @c data pointer within your node struct
495 * @param cmp_func the function to compare the elements 577 * @param cmp_func the function to compare the elements
496 * @return the first non-zero result of invoking @p cmp_func or: negative if the left list is smaller than the 578 * @return the first non-zero result of invoking @p cmp_func or: negative if the left list is smaller than the
497 * right list, positive if the left list is larger than the right list, zero if both lists are equal. 579 * right list, positive if the left list is larger than the right list, zero if both lists are equal.
498 */ 580 */
499 cx_attr_nonnull_arg(5) 581 CX_EXTERN CX_NONNULL_ARG(5)
500 CX_EXPORT int cx_linked_list_compare(const void *begin_left, const void *begin_right, 582 int cx_linked_list_compare(const void *begin_left, const void *begin_right,
501 ptrdiff_t loc_advance, ptrdiff_t loc_data, cx_compare_func cmp_func); 583 ptrdiff_t loc_advance, ptrdiff_t loc_data, cx_compare_func cmp_func);
502 584
503 /** 585 /**
504 * Compares two lists element wise. 586 * Compares two lists element wise.
505 * 587 *
508 * @param begin_left the beginning of the left list (@c NULL denotes an empty list) 590 * @param begin_left the beginning of the left list (@c NULL denotes an empty list)
509 * @param begin_right the beginning of the right list (@c NULL denotes an empty list) 591 * @param begin_right the beginning of the right list (@c NULL denotes an empty list)
510 * @param loc_advance the location of the pointer to advance 592 * @param loc_advance the location of the pointer to advance
511 * @param loc_data the location of the @c data pointer within your node struct 593 * @param loc_data the location of the @c data pointer within your node struct
512 * @param cmp_func the function to compare the elements 594 * @param cmp_func the function to compare the elements
595 * @param context the context for the compare function
513 * @return the first non-zero result of invoking @p cmp_func or: negative if the left list is smaller than the 596 * @return the first non-zero result of invoking @p cmp_func or: negative if the left list is smaller than the
514 * right list, positive if the left list is larger than the right list, zero if both lists are equal. 597 * right list, positive if the left list is larger than the right list, zero if both lists are equal.
515 */ 598 */
516 cx_attr_nonnull_arg(5) 599 CX_EXTERN CX_NONNULL_ARG(5)
517 CX_EXPORT int cx_linked_list_compare_c(const void *begin_left, const void *begin_right, 600 int cx_linked_list_compare_c(const void *begin_left, const void *begin_right,
518 ptrdiff_t loc_advance, ptrdiff_t loc_data, cx_compare_func2 cmp_func, void *context); 601 ptrdiff_t loc_advance, ptrdiff_t loc_data, cx_compare_func2 cmp_func, void *context);
519 602
520 /** 603 /**
521 * Reverses the order of the nodes in a linked list. 604 * Reverses the order of the nodes in a linked list.
522 * 605 *
523 * @param begin a pointer to the beginning node pointer (required) 606 * @param begin a pointer to the beginning node pointer (required)
524 * @param end a pointer to the end node pointer (optional) 607 * @param end a pointer to the end node pointer (optional)
525 * @param loc_prev the location of a @c prev pointer within your node struct (negative if your struct does not have one) 608 * @param loc_prev the location of a @c prev pointer within your node struct (negative if your struct does not have one)
526 * @param loc_next the location of a @c next pointer within your node struct (required) 609 * @param loc_next the location of a @c next pointer within your node struct (required)
527 */ 610 */
528 cx_attr_nonnull_arg(1) 611 CX_EXTERN CX_NONNULL_ARG(1)
529 CX_EXPORT void cx_linked_list_reverse(void **begin, void **end, ptrdiff_t loc_prev, ptrdiff_t loc_next); 612 void cx_linked_list_reverse(void **begin, void **end, ptrdiff_t loc_prev, ptrdiff_t loc_next);
530
531 #ifdef __cplusplus
532 } // extern "C"
533 #endif
534 613
535 #endif // UCX_LINKED_LIST_H 614 #endif // UCX_LINKED_LIST_H

mercurial