44 extern "C" { |
43 extern "C" { |
45 #endif |
44 #endif |
46 |
45 |
47 /** |
46 /** |
48 * The maximum item size that uses SBO swap instead of relinking. |
47 * The maximum item size that uses SBO swap instead of relinking. |
49 */ |
48 * |
50 extern unsigned cx_linked_list_swap_sbo_size; |
49 */ |
51 |
50 extern const unsigned cx_linked_list_swap_sbo_size; |
52 /** |
51 |
53 * Allocates a linked list for storing elements with \p elem_size bytes each. |
52 /** |
54 * |
53 * Allocates a linked list for storing elements with @p elem_size bytes each. |
55 * If \p elem_size is CX_STORE_POINTERS, the created list will be created as if |
54 * |
|
55 * If @p elem_size is CX_STORE_POINTERS, the created list will be created as if |
56 * cxListStorePointers() was called immediately after creation and the compare |
56 * cxListStorePointers() was called immediately after creation and the compare |
57 * function will be automatically set to cx_cmp_ptr(), if none is given. |
57 * function will be automatically set to cx_cmp_ptr(), if none is given. |
58 * |
58 * |
59 * @param allocator the allocator for allocating the list nodes |
59 * @param allocator the allocator for allocating the list nodes |
60 * (if \c NULL the cxDefaultAllocator will be used) |
60 * (if @c NULL, a default stdlib allocator will be used) |
61 * @param comparator the comparator for the elements |
61 * @param comparator the comparator for the elements |
62 * (if \c NULL, and the list is not storing pointers, sort and find |
62 * (if @c NULL, and the list is not storing pointers, sort and find |
63 * functions will not work) |
63 * functions will not work) |
64 * @param elem_size the size of each element in bytes |
64 * @param elem_size the size of each element in bytes |
65 * @return the created list |
65 * @return the created list |
66 */ |
66 */ |
|
67 cx_attr_nodiscard |
|
68 cx_attr_malloc |
|
69 cx_attr_dealloc(cxListFree, 1) |
67 CxList *cxLinkedListCreate( |
70 CxList *cxLinkedListCreate( |
68 CxAllocator const *allocator, |
71 const CxAllocator *allocator, |
69 cx_compare_func comparator, |
72 cx_compare_func comparator, |
70 size_t elem_size |
73 size_t elem_size |
71 ); |
74 ); |
72 |
75 |
73 /** |
76 /** |
74 * Allocates a linked list for storing elements with \p elem_size bytes each. |
77 * Allocates a linked list for storing elements with @p elem_size bytes each. |
75 * |
78 * |
76 * The list will use cxDefaultAllocator and no comparator function. If you want |
79 * The list will use cxDefaultAllocator and no comparator function. If you want |
77 * to call functions that need a comparator, you must either set one immediately |
80 * to call functions that need a comparator, you must either set one immediately |
78 * after list creation or use cxLinkedListCreate(). |
81 * after list creation or use cxLinkedListCreate(). |
79 * |
82 * |
80 * If \p elem_size is CX_STORE_POINTERS, the created list will be created as if |
83 * If @p elem_size is CX_STORE_POINTERS, the created list will be created as if |
81 * cxListStorePointers() was called immediately after creation and the compare |
84 * cxListStorePointers() was called immediately after creation and the compare |
82 * function will be automatically set to cx_cmp_ptr(). |
85 * function will be automatically set to cx_cmp_ptr(). |
83 * |
86 * |
84 * @param elem_size the size of each element in bytes |
87 * @param elem_size (@c size_t) the size of each element in bytes |
85 * @return the created list |
88 * @return (@c CxList*) the created list |
86 */ |
89 */ |
87 #define cxLinkedListCreateSimple(elem_size) \ |
90 #define cxLinkedListCreateSimple(elem_size) \ |
88 cxLinkedListCreate(NULL, NULL, elem_size) |
91 cxLinkedListCreate(NULL, NULL, elem_size) |
89 |
92 |
90 /** |
93 /** |
91 * Finds the node at a certain index. |
94 * Finds the node at a certain index. |
92 * |
95 * |
93 * This function can be used to start at an arbitrary position within the list. |
96 * This function can be used to start at an arbitrary position within the list. |
94 * If the search index is large than the start index, \p loc_advance must denote |
97 * If the search index is large than the start index, @p loc_advance must denote |
95 * the location of some sort of \c next pointer (i.e. a pointer to the next node). |
98 * the location of some sort of @c next pointer (i.e. a pointer to the next node). |
96 * But it is also possible that the search index is smaller than the start index |
99 * But it is also possible that the search index is smaller than the start index |
97 * (e.g. in cases where traversing a list backwards is faster) in which case |
100 * (e.g. in cases where traversing a list backwards is faster) in which case |
98 * \p loc_advance must denote the location of some sort of \c prev pointer |
101 * @p loc_advance must denote the location of some sort of @c prev pointer |
99 * (i.e. a pointer to the previous node). |
102 * (i.e. a pointer to the previous node). |
100 * |
103 * |
101 * @param start a pointer to the start node |
104 * @param start a pointer to the start node |
102 * @param start_index the start index |
105 * @param start_index the start index |
103 * @param loc_advance the location of the pointer to advance |
106 * @param loc_advance the location of the pointer to advance |
104 * @param index the search index |
107 * @param index the search index |
105 * @return the node found at the specified index |
108 * @return the node found at the specified index |
106 */ |
109 */ |
|
110 cx_attr_nonnull |
|
111 cx_attr_nodiscard |
107 void *cx_linked_list_at( |
112 void *cx_linked_list_at( |
108 void const *start, |
113 const void *start, |
109 size_t start_index, |
114 size_t start_index, |
110 ptrdiff_t loc_advance, |
115 ptrdiff_t loc_advance, |
111 size_t index |
116 size_t index |
112 ) __attribute__((__nonnull__)); |
117 ); |
113 |
118 |
114 /** |
119 /** |
115 * Finds the index of an element within a linked list. |
120 * Finds the index of an element within a linked list. |
116 * |
121 * |
117 * @param start a pointer to the start node |
122 * @param start a pointer to the start node |
118 * @param loc_advance the location of the pointer to advance |
123 * @param loc_advance the location of the pointer to advance |
119 * @param loc_data the location of the \c data pointer within your node struct |
124 * @param loc_data the location of the @c data pointer within your node struct |
120 * @param cmp_func a compare function to compare \p elem against the node data |
125 * @param cmp_func a compare function to compare @p elem against the node data |
121 * @param elem a pointer to the element to find |
126 * @param elem a pointer to the element to find |
122 * @return the index of the element or a negative value if it could not be found |
127 * @return the index of the element or a negative value if it could not be found |
123 */ |
128 */ |
|
129 cx_attr_nonnull |
124 ssize_t cx_linked_list_find( |
130 ssize_t cx_linked_list_find( |
125 void const *start, |
131 const void *start, |
126 ptrdiff_t loc_advance, |
132 ptrdiff_t loc_advance, |
127 ptrdiff_t loc_data, |
133 ptrdiff_t loc_data, |
128 cx_compare_func cmp_func, |
134 cx_compare_func cmp_func, |
129 void const *elem |
135 const void *elem |
130 ) __attribute__((__nonnull__)); |
136 ); |
131 |
137 |
132 /** |
138 /** |
133 * Finds the node containing an element within a linked list. |
139 * Finds the node containing an element within a linked list. |
134 * |
140 * |
135 * @param result a pointer to the memory where the node pointer (or \c NULL if the element |
141 * @param result a pointer to the memory where the node pointer (or @c NULL if the element |
136 * could not be found) shall be stored to |
142 * could not be found) shall be stored to |
137 * @param start a pointer to the start node |
143 * @param start a pointer to the start node |
138 * @param loc_advance the location of the pointer to advance |
144 * @param loc_advance the location of the pointer to advance |
139 * @param loc_data the location of the \c data pointer within your node struct |
145 * @param loc_data the location of the @c data pointer within your node struct |
140 * @param cmp_func a compare function to compare \p elem against the node data |
146 * @param cmp_func a compare function to compare @p elem against the node data |
141 * @param elem a pointer to the element to find |
147 * @param elem a pointer to the element to find |
142 * @return the index of the element or a negative value if it could not be found |
148 * @return the index of the element or a negative value if it could not be found |
143 */ |
149 */ |
|
150 cx_attr_nonnull |
144 ssize_t cx_linked_list_find_node( |
151 ssize_t cx_linked_list_find_node( |
145 void **result, |
152 void **result, |
146 void const *start, |
153 const void *start, |
147 ptrdiff_t loc_advance, |
154 ptrdiff_t loc_advance, |
148 ptrdiff_t loc_data, |
155 ptrdiff_t loc_data, |
149 cx_compare_func cmp_func, |
156 cx_compare_func cmp_func, |
150 void const *elem |
157 const void *elem |
151 ) __attribute__((__nonnull__)); |
158 ); |
152 |
159 |
153 /** |
160 /** |
154 * Finds the first node in a linked list. |
161 * Finds the first node in a linked list. |
155 * |
162 * |
156 * The function starts with the pointer denoted by \p node and traverses the list |
163 * The function starts with the pointer denoted by @p node and traverses the list |
157 * along a prev pointer whose location within the node struct is |
164 * along a prev pointer whose location within the node struct is |
158 * denoted by \p loc_prev. |
165 * denoted by @p loc_prev. |
159 * |
166 * |
160 * @param node a pointer to a node in the list |
167 * @param node a pointer to a node in the list |
161 * @param loc_prev the location of the \c prev pointer |
168 * @param loc_prev the location of the @c prev pointer |
162 * @return a pointer to the first node |
169 * @return a pointer to the first node |
163 */ |
170 */ |
|
171 cx_attr_nonnull |
|
172 cx_attr_returns_nonnull |
164 void *cx_linked_list_first( |
173 void *cx_linked_list_first( |
165 void const *node, |
174 const void *node, |
166 ptrdiff_t loc_prev |
175 ptrdiff_t loc_prev |
167 ) __attribute__((__nonnull__)); |
176 ); |
168 |
177 |
169 /** |
178 /** |
170 * Finds the last node in a linked list. |
179 * Finds the last node in a linked list. |
171 * |
180 * |
172 * The function starts with the pointer denoted by \p node and traverses the list |
181 * The function starts with the pointer denoted by @p node and traverses the list |
173 * along a next pointer whose location within the node struct is |
182 * along a next pointer whose location within the node struct is |
174 * denoted by \p loc_next. |
183 * denoted by @p loc_next. |
175 * |
184 * |
176 * @param node a pointer to a node in the list |
185 * @param node a pointer to a node in the list |
177 * @param loc_next the location of the \c next pointer |
186 * @param loc_next the location of the @c next pointer |
178 * @return a pointer to the last node |
187 * @return a pointer to the last node |
179 */ |
188 */ |
|
189 cx_attr_nonnull |
|
190 cx_attr_returns_nonnull |
180 void *cx_linked_list_last( |
191 void *cx_linked_list_last( |
181 void const *node, |
192 const void *node, |
182 ptrdiff_t loc_next |
193 ptrdiff_t loc_next |
183 ) __attribute__((__nonnull__)); |
194 ); |
184 |
195 |
185 /** |
196 /** |
186 * Finds the predecessor of a node in case it is not linked. |
197 * Finds the predecessor of a node in case it is not linked. |
187 * |
198 * |
188 * \remark If \p node is not contained in the list starting with \p begin, the behavior is undefined. |
199 * @remark If @p node is not contained in the list starting with @p begin, the behavior is undefined. |
189 * |
200 * |
190 * @param begin the node where to start the search |
201 * @param begin the node where to start the search |
191 * @param loc_next the location of the \c next pointer |
202 * @param loc_next the location of the @c next pointer |
192 * @param node the successor of the node to find |
203 * @param node the successor of the node to find |
193 * @return the node or \c NULL if \p node has no predecessor |
204 * @return the node or @c NULL if @p node has no predecessor |
194 */ |
205 */ |
|
206 cx_attr_nonnull |
195 void *cx_linked_list_prev( |
207 void *cx_linked_list_prev( |
196 void const *begin, |
208 const void *begin, |
197 ptrdiff_t loc_next, |
209 ptrdiff_t loc_next, |
198 void const *node |
210 const void *node |
199 ) __attribute__((__nonnull__)); |
211 ); |
200 |
212 |
201 /** |
213 /** |
202 * Adds a new node to a linked list. |
214 * Adds a new node to a linked list. |
203 * The node must not be part of any list already. |
215 * The node must not be part of any list already. |
204 * |
216 * |
205 * \remark One of the pointers \p begin or \p end may be \c NULL, but not both. |
217 * @remark One of the pointers @p begin or @p end may be @c NULL, but not both. |
206 * |
218 * |
207 * @param begin a pointer to the begin node pointer (if your list has one) |
219 * @param begin a pointer to the beginning node pointer (if your list has one) |
208 * @param end a pointer to the end node pointer (if your list has one) |
220 * @param end a pointer to the end node pointer (if your list has one) |
209 * @param loc_prev the location of a \c prev pointer within your node struct (negative if your struct does not have one) |
221 * @param loc_prev the location of a @c prev pointer within your node struct (negative if your struct does not have one) |
210 * @param loc_next the location of a \c next pointer within your node struct (required) |
222 * @param loc_next the location of a @c next pointer within your node struct (required) |
211 * @param new_node a pointer to the node that shall be appended |
223 * @param new_node a pointer to the node that shall be appended |
212 */ |
224 */ |
|
225 cx_attr_nonnull_arg(5) |
213 void cx_linked_list_add( |
226 void cx_linked_list_add( |
214 void **begin, |
227 void **begin, |
215 void **end, |
228 void **end, |
216 ptrdiff_t loc_prev, |
229 ptrdiff_t loc_prev, |
217 ptrdiff_t loc_next, |
230 ptrdiff_t loc_next, |
218 void *new_node |
231 void *new_node |
219 ) __attribute__((__nonnull__(5))); |
232 ); |
220 |
233 |
221 /** |
234 /** |
222 * Prepends a new node to a linked list. |
235 * Prepends a new node to a linked list. |
223 * The node must not be part of any list already. |
236 * The node must not be part of any list already. |
224 * |
237 * |
225 * \remark One of the pointers \p begin or \p end may be \c NULL, but not both. |
238 * @remark One of the pointers @p begin or @p end may be @c NULL, but not both. |
226 * |
239 * |
227 * @param begin a pointer to the begin node pointer (if your list has one) |
240 * @param begin a pointer to the beginning node pointer (if your list has one) |
228 * @param end a pointer to the end node pointer (if your list has one) |
241 * @param end a pointer to the end node pointer (if your list has one) |
229 * @param loc_prev the location of a \c prev pointer within your node struct (negative if your struct does not have one) |
242 * @param loc_prev the location of a @c prev pointer within your node struct (negative if your struct does not have one) |
230 * @param loc_next the location of a \c next pointer within your node struct (required) |
243 * @param loc_next the location of a @c next pointer within your node struct (required) |
231 * @param new_node a pointer to the node that shall be prepended |
244 * @param new_node a pointer to the node that shall be prepended |
232 */ |
245 */ |
|
246 cx_attr_nonnull_arg(5) |
233 void cx_linked_list_prepend( |
247 void cx_linked_list_prepend( |
234 void **begin, |
248 void **begin, |
235 void **end, |
249 void **end, |
236 ptrdiff_t loc_prev, |
250 ptrdiff_t loc_prev, |
237 ptrdiff_t loc_next, |
251 ptrdiff_t loc_next, |
238 void *new_node |
252 void *new_node |
239 ) __attribute__((__nonnull__(5))); |
253 ); |
240 |
254 |
241 /** |
255 /** |
242 * Links two nodes. |
256 * Links two nodes. |
243 * |
257 * |
244 * @param left the new predecessor of \p right |
258 * @param left the new predecessor of @p right |
245 * @param right the new successor of \p left |
259 * @param right the new successor of @p left |
246 * @param loc_prev the location of a \c prev pointer within your node struct (negative if your struct does not have one) |
260 * @param loc_prev the location of a @c prev pointer within your node struct (negative if your struct does not have one) |
247 * @param loc_next the location of a \c next pointer within your node struct (required) |
261 * @param loc_next the location of a @c next pointer within your node struct (required) |
248 */ |
262 */ |
|
263 cx_attr_nonnull |
249 void cx_linked_list_link( |
264 void cx_linked_list_link( |
250 void *left, |
265 void *left, |
251 void *right, |
266 void *right, |
252 ptrdiff_t loc_prev, |
267 ptrdiff_t loc_prev, |
253 ptrdiff_t loc_next |
268 ptrdiff_t loc_next |
254 ) __attribute__((__nonnull__)); |
269 ); |
255 |
270 |
256 /** |
271 /** |
257 * Unlinks two nodes. |
272 * Unlinks two nodes. |
258 * |
273 * |
259 * If right is not the successor of left, the behavior is undefined. |
274 * If right is not the successor of left, the behavior is undefined. |
260 * |
275 * |
261 * @param left the predecessor of \p right |
276 * @param left the predecessor of @p right |
262 * @param right the successor of \p left |
277 * @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) |
278 * @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) |
279 * @param loc_next the location of a @c next pointer within your node struct (required) |
265 */ |
280 */ |
|
281 cx_attr_nonnull |
266 void cx_linked_list_unlink( |
282 void cx_linked_list_unlink( |
267 void *left, |
283 void *left, |
268 void *right, |
284 void *right, |
269 ptrdiff_t loc_prev, |
285 ptrdiff_t loc_prev, |
270 ptrdiff_t loc_next |
286 ptrdiff_t loc_next |
271 ) __attribute__((__nonnull__)); |
287 ); |
272 |
288 |
273 /** |
289 /** |
274 * Inserts a new node after a given node of a linked list. |
290 * Inserts a new node after a given node of a linked list. |
275 * The new node must not be part of any list already. |
291 * The new node must not be part of any list already. |
276 * |
292 * |
277 * \note If you specify \c NULL as the \p node to insert after, this function needs either the \p begin or |
293 * @note If you specify @c NULL as the @p node to insert after, this function needs either the @p begin or |
278 * the \p end pointer to determine the start of the list. Then the new node will be prepended to the list. |
294 * the @p end pointer to determine the start of the list. Then the new node will be prepended to the list. |
279 * |
295 * |
280 * @param begin a pointer to the begin node pointer (if your list has one) |
296 * @param begin a pointer to the beginning node pointer (if your list has one) |
281 * @param end a pointer to the end node pointer (if your list has one) |
297 * @param end a pointer to the end node pointer (if your list has one) |
282 * @param loc_prev the location of a \c prev pointer within your node struct (negative if your struct does not have one) |
298 * @param loc_prev the location of a @c prev pointer within your node struct (negative if your struct does not have one) |
283 * @param loc_next the location of a \c next pointer within your node struct (required) |
299 * @param loc_next the location of a @c next pointer within your node struct (required) |
284 * @param node the node after which to insert (\c NULL if you want to prepend the node to the list) |
300 * @param node the node after which to insert (@c NULL if you want to prepend the node to the list) |
285 * @param new_node a pointer to the node that shall be prepended |
301 * @param new_node a pointer to the node that shall be inserted |
286 */ |
302 */ |
|
303 cx_attr_nonnull_arg(6) |
287 void cx_linked_list_insert( |
304 void cx_linked_list_insert( |
288 void **begin, |
305 void **begin, |
289 void **end, |
306 void **end, |
290 ptrdiff_t loc_prev, |
307 ptrdiff_t loc_prev, |
291 ptrdiff_t loc_next, |
308 ptrdiff_t loc_next, |
292 void *node, |
309 void *node, |
293 void *new_node |
310 void *new_node |
294 ) __attribute__((__nonnull__(6))); |
311 ); |
295 |
312 |
296 /** |
313 /** |
297 * Inserts a chain of nodes after a given node of a linked list. |
314 * Inserts a chain of nodes after a given node of a linked list. |
298 * The chain must not be part of any list already. |
315 * The chain must not be part of any list already. |
299 * |
316 * |
300 * If you do not explicitly specify the end of the chain, it will be determined by traversing |
317 * If you do not explicitly specify the end of the chain, it will be determined by traversing |
301 * the \c next pointer. |
318 * the @c next pointer. |
302 * |
319 * |
303 * \note If you specify \c NULL as the \p node to insert after, this function needs either the \p begin or |
320 * @note If you specify @c NULL as the @p node to insert after, this function needs either the @p begin or |
304 * the \p end pointer to determine the start of the list. If only the \p end pointer is specified, you also need |
321 * the @p end pointer to determine the start of the list. If only the @p end pointer is specified, you also need |
305 * to provide a valid \p loc_prev location. |
322 * to provide a valid @p loc_prev location. |
306 * Then the chain will be prepended to the list. |
323 * Then the chain will be prepended to the list. |
307 * |
324 * |
308 * @param begin a pointer to the begin node pointer (if your list has one) |
325 * @param begin a pointer to the beginning node pointer (if your list has one) |
309 * @param end a pointer to the end node pointer (if your list has one) |
326 * @param end a pointer to the end node pointer (if your list has one) |
310 * @param loc_prev the location of a \c prev pointer within your node struct (negative if your struct does not have one) |
327 * @param loc_prev the location of a @c prev pointer within your node struct (negative if your struct does not have one) |
311 * @param loc_next the location of a \c next pointer within your node struct (required) |
328 * @param loc_next the location of a @c next pointer within your node struct (required) |
312 * @param node the node after which to insert (\c NULL to prepend the chain to the list) |
329 * @param node the node after which to insert (@c NULL to prepend the chain to the list) |
313 * @param insert_begin a pointer to the first node of the chain that shall be inserted |
330 * @param insert_begin a pointer to the first node of the chain that shall be inserted |
314 * @param insert_end a pointer to the last node of the chain (or NULL if the last node shall be determined) |
331 * @param insert_end a pointer to the last node of the chain (or NULL if the last node shall be determined) |
315 */ |
332 */ |
|
333 cx_attr_nonnull_arg(6) |
316 void cx_linked_list_insert_chain( |
334 void cx_linked_list_insert_chain( |
317 void **begin, |
335 void **begin, |
318 void **end, |
336 void **end, |
319 ptrdiff_t loc_prev, |
337 ptrdiff_t loc_prev, |
320 ptrdiff_t loc_next, |
338 ptrdiff_t loc_next, |
321 void *node, |
339 void *node, |
322 void *insert_begin, |
340 void *insert_begin, |
323 void *insert_end |
341 void *insert_end |
324 ) __attribute__((__nonnull__(6))); |
342 ); |
|
343 |
|
344 /** |
|
345 * Inserts a node into a sorted linked list. |
|
346 * The new node must not be part of any list already. |
|
347 * |
|
348 * If the list starting with the node pointed to by @p begin is not sorted |
|
349 * already, the behavior is undefined. |
|
350 * |
|
351 * @param begin a pointer to the beginning node pointer (required) |
|
352 * @param end a pointer to the end node pointer (if your list has one) |
|
353 * @param loc_prev the location of a @c prev pointer within your node struct (negative if your struct does not have one) |
|
354 * @param loc_next the location of a @c next pointer within your node struct (required) |
|
355 * @param new_node a pointer to the node that shall be inserted |
|
356 * @param cmp_func a compare function that will receive the node pointers |
|
357 */ |
|
358 cx_attr_nonnull_arg(1, 5, 6) |
|
359 void cx_linked_list_insert_sorted( |
|
360 void **begin, |
|
361 void **end, |
|
362 ptrdiff_t loc_prev, |
|
363 ptrdiff_t loc_next, |
|
364 void *new_node, |
|
365 cx_compare_func cmp_func |
|
366 ); |
|
367 |
|
368 /** |
|
369 * Inserts a chain of nodes into a sorted linked list. |
|
370 * The chain must not be part of any list already. |
|
371 * |
|
372 * If either the list starting with the node pointed to by @p begin or the list |
|
373 * starting with @p insert_begin is not sorted, the behavior is undefined. |
|
374 * |
|
375 * @attention In contrast to cx_linked_list_insert_chain(), the source chain |
|
376 * will be broken and inserted into the target list so that the resulting list |
|
377 * will be sorted according to @p cmp_func. That means, each node in the source |
|
378 * chain may be re-linked with nodes from the target list. |
|
379 * |
|
380 * @param begin a pointer to the beginning node pointer (required) |
|
381 * @param end a pointer to the end node pointer (if your list has one) |
|
382 * @param loc_prev the location of a @c prev pointer within your node struct (negative if your struct does not have one) |
|
383 * @param loc_next the location of a @c next pointer within your node struct (required) |
|
384 * @param insert_begin a pointer to the first node of the chain that shall be inserted |
|
385 * @param cmp_func a compare function that will receive the node pointers |
|
386 */ |
|
387 cx_attr_nonnull_arg(1, 5, 6) |
|
388 void cx_linked_list_insert_sorted_chain( |
|
389 void **begin, |
|
390 void **end, |
|
391 ptrdiff_t loc_prev, |
|
392 ptrdiff_t loc_next, |
|
393 void *insert_begin, |
|
394 cx_compare_func cmp_func |
|
395 ); |
|
396 |
|
397 /** |
|
398 * Removes a chain of nodes from the linked list. |
|
399 * |
|
400 * If one of the nodes to remove is the beginning (resp. end) node of the list and if @p begin (resp. @p end) |
|
401 * addresses are provided, the pointers are adjusted accordingly. |
|
402 * |
|
403 * The following combinations of arguments are valid (more arguments are optional): |
|
404 * @li @p loc_next and @p loc_prev (ancestor node is determined by using the prev pointer, overall O(1) performance) |
|
405 * @li @p loc_next and @p begin (ancestor node is determined by list traversal, overall O(n) performance) |
|
406 * |
|
407 * @remark The @c next and @c prev pointers of the removed node are not cleared by this function and may still be used |
|
408 * to traverse to a former adjacent node in the list, or within the chain. |
|
409 * |
|
410 * @param begin a pointer to the beginning node pointer (optional) |
|
411 * @param end a pointer to the end node pointer (optional) |
|
412 * @param loc_prev the location of a @c prev pointer within your node struct (negative if your struct does not have one) |
|
413 * @param loc_next the location of a @c next pointer within your node struct (required) |
|
414 * @param node the start node of the chain |
|
415 * @param num the number of nodes to remove |
|
416 * @return the actual number of nodes that were removed (can be less when the list did not have enough nodes) |
|
417 */ |
|
418 cx_attr_nonnull_arg(5) |
|
419 size_t cx_linked_list_remove_chain( |
|
420 void **begin, |
|
421 void **end, |
|
422 ptrdiff_t loc_prev, |
|
423 ptrdiff_t loc_next, |
|
424 void *node, |
|
425 size_t num |
|
426 ); |
325 |
427 |
326 /** |
428 /** |
327 * Removes a node from the linked list. |
429 * Removes a node from the linked list. |
328 * |
430 * |
329 * If the node to remove is the begin (resp. end) node of the list and if \p begin (resp. \p end) |
431 * If the node to remove is the beginning (resp. end) node of the list and if @p begin (resp. @p end) |
330 * addresses are provided, the pointers are adjusted accordingly. |
432 * addresses are provided, the pointers are adjusted accordingly. |
331 * |
433 * |
332 * The following combinations of arguments are valid (more arguments are optional): |
434 * The following combinations of arguments are valid (more arguments are optional): |
333 * \li \p loc_next and \p loc_prev (ancestor node is determined by using the prev pointer, overall O(1) performance) |
435 * @li @p loc_next and @p loc_prev (ancestor node is determined by using the prev pointer, overall O(1) performance) |
334 * \li \p loc_next and \p begin (ancestor node is determined by list traversal, overall O(n) performance) |
436 * @li @p loc_next and @p begin (ancestor node is determined by list traversal, overall O(n) performance) |
335 * |
437 * |
336 * \remark The \c next and \c prev pointers of the removed node are not cleared by this function and may still be used |
438 * @remark The @c next and @c prev pointers of the removed node are not cleared by this function and may still be used |
337 * to traverse to a former adjacent node in the list. |
439 * to traverse to a former adjacent node in the list. |
338 * |
440 * |
339 * @param begin a pointer to the begin node pointer (optional) |
441 * @param begin a pointer to the beginning node pointer (optional) |
340 * @param end a pointer to the end node pointer (optional) |
442 * @param end a pointer to the end node pointer (optional) |
341 * @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_prev the location of a @c prev pointer within your node struct (negative if your struct does not have one) |
342 * @param loc_next the location of a \c next pointer within your node struct (required) |
444 * @param loc_next the location of a @c next pointer within your node struct (required) |
343 * @param node the node to remove |
445 * @param node the node to remove |
344 */ |
446 */ |
345 void cx_linked_list_remove( |
447 cx_attr_nonnull_arg(5) |
|
448 static inline void cx_linked_list_remove( |
346 void **begin, |
449 void **begin, |
347 void **end, |
450 void **end, |
348 ptrdiff_t loc_prev, |
451 ptrdiff_t loc_prev, |
349 ptrdiff_t loc_next, |
452 ptrdiff_t loc_next, |
350 void *node |
453 void *node |
351 ) __attribute__((__nonnull__(5))); |
454 ) { |
352 |
455 cx_linked_list_remove_chain(begin, end, loc_prev, loc_next, node, 1); |
353 |
456 } |
354 /** |
457 |
355 * Determines the size of a linked list starting with \p node. |
458 /** |
|
459 * Determines the size of a linked list starting with @p node. |
|
460 * |
356 * @param node the first node |
461 * @param node the first node |
357 * @param loc_next the location of the \c next pointer within the node struct |
462 * @param loc_next the location of the @c next pointer within the node struct |
358 * @return the size of the list or zero if \p node is \c NULL |
463 * @return the size of the list or zero if @p node is @c NULL |
359 */ |
464 */ |
360 size_t cx_linked_list_size( |
465 size_t cx_linked_list_size( |
361 void const *node, |
466 const void *node, |
362 ptrdiff_t loc_next |
467 ptrdiff_t loc_next |
363 ); |
468 ); |
364 |
469 |
365 /** |
470 /** |
366 * Sorts a linked list based on a comparison function. |
471 * Sorts a linked list based on a comparison function. |
367 * |
472 * |
368 * This function can work with linked lists of the following structure: |
473 * This function can work with linked lists of the following structure: |
369 * \code |
474 * @code |
370 * typedef struct node node; |
475 * typedef struct node node; |
371 * struct node { |
476 * struct node { |
372 * node* prev; |
477 * node* prev; |
373 * node* next; |
478 * node* next; |
374 * my_payload data; |
479 * my_payload data; |
375 * } |
480 * } |
376 * \endcode |
481 * @endcode |
377 * |
482 * |
378 * @note This is a recursive function with at most logarithmic recursion depth. |
483 * @note This is a recursive function with at most logarithmic recursion depth. |
379 * |
484 * |
380 * @param begin a pointer to the begin node pointer (required) |
485 * @param begin a pointer to the beginning node pointer (required) |
381 * @param end a pointer to the end node pointer (optional) |
486 * @param end a pointer to the end node pointer (optional) |
382 * @param loc_prev the location of a \c prev pointer within your node struct (negative if not present) |
487 * @param loc_prev the location of a @c prev pointer within your node struct (negative if not present) |
383 * @param loc_next the location of a \c next pointer within your node struct (required) |
488 * @param loc_next the location of a @c next pointer within your node struct (required) |
384 * @param loc_data the location of the \c data pointer within your node struct |
489 * @param loc_data the location of the @c data pointer within your node struct |
385 * @param cmp_func the compare function defining the sort order |
490 * @param cmp_func the compare function defining the sort order |
386 */ |
491 */ |
|
492 cx_attr_nonnull_arg(1, 6) |
387 void cx_linked_list_sort( |
493 void cx_linked_list_sort( |
388 void **begin, |
494 void **begin, |
389 void **end, |
495 void **end, |
390 ptrdiff_t loc_prev, |
496 ptrdiff_t loc_prev, |
391 ptrdiff_t loc_next, |
497 ptrdiff_t loc_next, |
392 ptrdiff_t loc_data, |
498 ptrdiff_t loc_data, |
393 cx_compare_func cmp_func |
499 cx_compare_func cmp_func |
394 ) __attribute__((__nonnull__(1, 6))); |
500 ); |
395 |
501 |
396 |
502 |
397 /** |
503 /** |
398 * Compares two lists element wise. |
504 * Compares two lists element wise. |
399 * |
505 * |
400 * \note Both list must have the same structure. |
506 * @attention Both list must have the same structure. |
401 * |
507 * |
402 * @param begin_left the begin of the left list (\c NULL denotes an empty list) |
508 * @param begin_left the beginning of the left list (@c NULL denotes an empty list) |
403 * @param begin_right the begin of the right list (\c NULL denotes an empty list) |
509 * @param begin_right the beginning of the right list (@c NULL denotes an empty list) |
404 * @param loc_advance the location of the pointer to advance |
510 * @param loc_advance the location of the pointer to advance |
405 * @param loc_data the location of the \c data pointer within your node struct |
511 * @param loc_data the location of the @c data pointer within your node struct |
406 * @param cmp_func the function to compare the elements |
512 * @param cmp_func the function to compare the elements |
407 * @return the first non-zero result of invoking \p cmp_func or: negative if the left list is smaller than the |
513 * @return the first non-zero result of invoking @p cmp_func or: negative if the left list is smaller than the |
408 * right list, positive if the left list is larger than the right list, zero if both lists are equal. |
514 * right list, positive if the left list is larger than the right list, zero if both lists are equal. |
409 */ |
515 */ |
|
516 cx_attr_nonnull_arg(5) |
410 int cx_linked_list_compare( |
517 int cx_linked_list_compare( |
411 void const *begin_left, |
518 const void *begin_left, |
412 void const *begin_right, |
519 const void *begin_right, |
413 ptrdiff_t loc_advance, |
520 ptrdiff_t loc_advance, |
414 ptrdiff_t loc_data, |
521 ptrdiff_t loc_data, |
415 cx_compare_func cmp_func |
522 cx_compare_func cmp_func |
416 ) __attribute__((__nonnull__(5))); |
523 ); |
417 |
524 |
418 /** |
525 /** |
419 * Reverses the order of the nodes in a linked list. |
526 * Reverses the order of the nodes in a linked list. |
420 * |
527 * |
421 * @param begin a pointer to the begin node pointer (required) |
528 * @param begin a pointer to the beginning node pointer (required) |
422 * @param end a pointer to the end node pointer (optional) |
529 * @param end a pointer to the end node pointer (optional) |
423 * @param loc_prev the location of a \c prev pointer within your node struct (negative if your struct does not have one) |
530 * @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) |
531 * @param loc_next the location of a @c next pointer within your node struct (required) |
425 */ |
532 */ |
|
533 cx_attr_nonnull_arg(1) |
426 void cx_linked_list_reverse( |
534 void cx_linked_list_reverse( |
427 void **begin, |
535 void **begin, |
428 void **end, |
536 void **end, |
429 ptrdiff_t loc_prev, |
537 ptrdiff_t loc_prev, |
430 ptrdiff_t loc_next |
538 ptrdiff_t loc_next |
431 ) __attribute__((__nonnull__(1))); |
539 ); |
432 |
540 |
433 #ifdef __cplusplus |
541 #ifdef __cplusplus |
434 } // extern "C" |
542 } // extern "C" |
435 #endif |
543 #endif |
436 |
544 |