44 #ifdef __cplusplus |
44 #ifdef __cplusplus |
45 extern "C" { |
45 extern "C" { |
46 #endif |
46 #endif |
47 |
47 |
48 /** |
48 /** |
|
49 * Set this flag to true, if you want to disable the use of SBO for |
|
50 * linked list swap operations. |
|
51 */ |
|
52 extern bool CX_DISABLE_LINKED_LIST_SWAP_SBO; |
|
53 |
|
54 /** |
49 * Allocates a linked list for storing elements with \p item_size bytes each. |
55 * Allocates a linked list for storing elements with \p item_size bytes each. |
50 * |
56 * |
51 * @remark Elements added to the list are copied, therefore a possible destructor |
57 * If \p item_size is CX_STORE_POINTERS, the created list will be created as if |
52 * MUST NOT free the memory pointed to by its argument. |
58 * cxListStorePointers() was called immediately after creation. |
53 * |
59 * |
54 * @param allocator the allocator for allocating the list nodes |
60 * @param allocator the allocator for allocating the list nodes |
|
61 * (if \c NULL the cxDefaultAllocator will be used) |
55 * @param comparator the comparator for the elements |
62 * @param comparator the comparator for the elements |
|
63 * (if \c NULL sort and find functions will not work) |
56 * @param item_size the size of each element in bytes |
64 * @param item_size the size of each element in bytes |
57 * @return the created list |
65 * @return the created list |
58 */ |
66 */ |
59 CxList *cxLinkedListCreate( |
67 CxList *cxLinkedListCreate( |
60 CxAllocator const *allocator, |
68 CxAllocator const *allocator, |
61 CxListComparator comparator, |
69 cx_compare_func comparator, |
62 size_t item_size |
70 size_t item_size |
63 ) __attribute__((__nonnull__)); |
71 ); |
64 |
72 |
65 /** |
73 /** |
66 * Allocates a linked list for storing pointers. |
74 * Allocates a linked list for storing elements with \p item_size bytes each. |
67 * |
75 * |
68 * If you want to store the elements directly in this list, use cxLinkedListCreate(). |
76 * The list will use cxDefaultAllocator and no comparator function. If you want |
69 * |
77 * to call functions that need a comparator, you must either set one immediately |
70 * @remark Since only pointers are stored in this list, a possible destructor |
78 * after list creation or use cxLinkedListCreate(). |
71 * MAY free the memory pointed to by its argument in order to prevent memory leaks. |
79 * |
72 * |
80 * If \p item_size is CX_STORE_POINTERS, the created list will be created as if |
73 * @param allocator the allocator for allocating the list nodes |
81 * cxListStorePointers() was called immediately after creation. |
74 * @param comparator the comparator for the elements |
82 * |
|
83 * @param item_size the size of each element in bytes |
75 * @return the created list |
84 * @return the created list |
76 */ |
85 */ |
77 CxList *cxPointerLinkedListCreate( |
86 #define cxLinkedListCreateSimple(item_size) \ |
78 CxAllocator const *allocator, |
87 cxLinkedListCreate(NULL, NULL, item_size) |
79 CxListComparator comparator |
|
80 ) __attribute__((__nonnull__)); |
|
81 |
88 |
82 /** |
89 /** |
83 * Finds the node at a certain index. |
90 * Finds the node at a certain index. |
84 * |
91 * |
85 * This function can be used to start at an arbitrary position within the list. |
92 * This function can be used to start at an arbitrary position within the list. |
107 * Finds the index of an element within a linked list. |
114 * Finds the index of an element within a linked list. |
108 * |
115 * |
109 * @param start a pointer to the start node |
116 * @param start a pointer to the start node |
110 * @param loc_advance the location of the pointer to advance |
117 * @param loc_advance the location of the pointer to advance |
111 * @param loc_data the location of the \c data pointer within your node struct |
118 * @param loc_data the location of the \c data pointer within your node struct |
112 * @param follow_ptr \c false if the pointer denoted by \p loc_data shall be passed to the \p cmp_func. |
|
113 * If \c true, the data at \p loc_data is assumed to be a pointer, dereferenced, and then passed to \p cmp_func. |
|
114 * @param cmp_func a compare function to compare \p elem against the node data |
119 * @param cmp_func a compare function to compare \p elem against the node data |
115 * @param elem a pointer to the element to find |
120 * @param elem a pointer to the element to find |
116 * @return the index of the element or a past-one index if the element could not be found |
121 * @return the index of the element or a negative value if it could not be found |
117 */ |
122 */ |
118 size_t cx_linked_list_find( |
123 ssize_t cx_linked_list_find( |
119 void const *start, |
124 void const *start, |
120 ptrdiff_t loc_advance, |
125 ptrdiff_t loc_advance, |
121 ptrdiff_t loc_data, |
126 ptrdiff_t loc_data, |
122 bool follow_ptr, |
127 cx_compare_func cmp_func, |
123 CxListComparator cmp_func, |
|
124 void const *elem |
128 void const *elem |
125 ) __attribute__((__nonnull__)); |
129 ) __attribute__((__nonnull__)); |
126 |
130 |
127 /** |
131 /** |
128 * Finds the first node in a linked list. |
132 * Finds the first node in a linked list. |
337 ); |
341 ); |
338 |
342 |
339 /** |
343 /** |
340 * Sorts a linked list based on a comparison function. |
344 * Sorts a linked list based on a comparison function. |
341 * |
345 * |
342 * This function can work with linked lists of the following structures: |
346 * This function can work with linked lists of the following structure: |
343 * \code |
347 * \code |
344 * typedef struct node node; |
348 * typedef struct node node; |
345 * struct node { |
349 * struct node { |
346 * node* prev; |
350 * node* prev; |
347 * node* next; |
351 * node* next; |
348 * my_payload data; // in this case set follow_ptr = 0 |
352 * my_payload data; |
349 * } |
|
350 * |
|
351 * typedef struct ptr_node ptr_node; |
|
352 * struct ptr_node { |
|
353 * ptr_node* prev; |
|
354 * ptr_node* next; |
|
355 * my_payload* data; // in this case set follow_ptr = 1 |
|
356 * } |
353 * } |
357 * \endcode |
354 * \endcode |
358 * |
355 * |
359 * @note This is a recursive function with at most logarithmic recursion depth. |
356 * @note This is a recursive function with at most logarithmic recursion depth. |
360 * |
357 * |
361 * @param begin a pointer to the begin node pointer (required) |
358 * @param begin a pointer to the begin node pointer (required) |
362 * @param end a pointer to the end node pointer (optional) |
359 * @param end a pointer to the end node pointer (optional) |
363 * @param loc_prev the location of a \c prev pointer within your node struct (negative if not present) |
360 * @param loc_prev the location of a \c prev pointer within your node struct (negative if not present) |
364 * @param loc_next the location of a \c next pointer within your node struct (required) |
361 * @param loc_next the location of a \c next pointer within your node struct (required) |
365 * @param loc_data the location of the \c data pointer within your node struct |
362 * @param loc_data the location of the \c data pointer within your node struct |
366 * @param follow_ptr \c false if the pointer denoted by \p loc_data shall be passed to the \p cmp_func. |
|
367 * If \c true, the data at \p loc_data is assumed to be a pointer, dereferenced, and then passed to \p cmp_func. |
|
368 * @param cmp_func the compare function defining the sort order |
363 * @param cmp_func the compare function defining the sort order |
369 */ |
364 */ |
370 void cx_linked_list_sort( |
365 void cx_linked_list_sort( |
371 void **begin, |
366 void **begin, |
372 void **end, |
367 void **end, |
373 ptrdiff_t loc_prev, |
368 ptrdiff_t loc_prev, |
374 ptrdiff_t loc_next, |
369 ptrdiff_t loc_next, |
375 ptrdiff_t loc_data, |
370 ptrdiff_t loc_data, |
376 bool follow_ptr, |
371 cx_compare_func cmp_func |
377 CxListComparator cmp_func |
372 ) __attribute__((__nonnull__(1, 6))); |
378 ) __attribute__((__nonnull__(1, 7))); |
|
379 |
373 |
380 |
374 |
381 /** |
375 /** |
382 * Compares two lists element wise. |
376 * Compares two lists element wise. |
383 * |
|
384 * The \c follow_ptr flags have the following meaning: if \c false, the pointer denoted by \p loc_data shall |
|
385 * directly be passed to the \p cmp_func. |
|
386 * If \c true, the data at \p loc_data is assumed to be a pointer, dereferenced, and then passed to \p cmp_func. |
|
387 * |
377 * |
388 * \note Both list must have the same structure. |
378 * \note Both list must have the same structure. |
389 * |
379 * |
390 * @param begin_left the begin of the left list (\c NULL denotes an empty list) |
380 * @param begin_left the begin of the left list (\c NULL denotes an empty list) |
391 * @param begin_right the begin of the right list (\c NULL denotes an empty list) |
381 * @param begin_right the begin of the right list (\c NULL denotes an empty list) |
392 * @param loc_advance the location of the pointer to advance |
382 * @param loc_advance the location of the pointer to advance |
393 * @param loc_data the location of the \c data pointer within your node struct |
383 * @param loc_data the location of the \c data pointer within your node struct |
394 * @param follow_ptr_left indicates whether pointers in the left list shall be dereferenced |
|
395 * @param follow_ptr_right indicates whether pointers in the right list shall be dereferenced |
|
396 * @param cmp_func the function to compare the elements |
384 * @param cmp_func the function to compare the elements |
397 * @return the first non-zero result of invoking \p cmp_func or: negative if the left list is smaller than the |
385 * @return the first non-zero result of invoking \p cmp_func or: negative if the left list is smaller than the |
398 * right list, positive if the left list is larger than the right list, zero if both lists are equal. |
386 * right list, positive if the left list is larger than the right list, zero if both lists are equal. |
399 */ |
387 */ |
400 int cx_linked_list_compare( |
388 int cx_linked_list_compare( |
401 void const *begin_left, |
389 void const *begin_left, |
402 void const *begin_right, |
390 void const *begin_right, |
403 ptrdiff_t loc_advance, |
391 ptrdiff_t loc_advance, |
404 ptrdiff_t loc_data, |
392 ptrdiff_t loc_data, |
405 bool follow_ptr_left, |
393 cx_compare_func cmp_func |
406 bool follow_ptr_right, |
394 ) __attribute__((__nonnull__(5))); |
407 CxListComparator cmp_func |
|
408 ) __attribute__((__nonnull__(7))); |
|
409 |
395 |
410 /** |
396 /** |
411 * Reverses the order of the nodes in a linked list. |
397 * Reverses the order of the nodes in a linked list. |
412 * |
398 * |
413 * @param begin a pointer to the begin node pointer (required) |
399 * @param begin a pointer to the begin node pointer (required) |