24 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) |
24 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) |
25 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE |
25 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE |
26 * POSSIBILITY OF SUCH DAMAGE. |
26 * POSSIBILITY OF SUCH DAMAGE. |
27 */ |
27 */ |
28 /** |
28 /** |
29 * \file list.h |
29 * @file list.h |
30 * \brief Interface for list implementations. |
30 * @brief Interface for list implementations. |
31 * \author Mike Becker |
31 * @author Mike Becker |
32 * \author Olaf Wintermann |
32 * @author Olaf Wintermann |
33 * \copyright 2-Clause BSD License |
33 * @copyright 2-Clause BSD License |
34 */ |
34 */ |
35 |
35 |
36 #ifndef UCX_LIST_H |
36 #ifndef UCX_LIST_H |
37 #define UCX_LIST_H |
37 #define UCX_LIST_H |
38 |
38 |
69 struct cx_list_class_s { |
72 struct cx_list_class_s { |
70 /** |
73 /** |
71 * Destructor function. |
74 * Destructor function. |
72 * |
75 * |
73 * Implementations SHALL invoke the content destructor functions if provided |
76 * Implementations SHALL invoke the content destructor functions if provided |
74 * and SHALL deallocate the list memory. |
77 * and SHALL deallocate the entire list memory. |
75 */ |
78 */ |
76 void (*destructor)(struct cx_list_s *list); |
79 void (*deallocate)(struct cx_list_s *list); |
77 |
80 |
78 /** |
81 /** |
79 * Member function for inserting a single element. |
82 * Member function for inserting a single element. |
80 * Implementors SHOULD see to performant implementations for corner cases. |
83 * Implementors SHOULD see to performant implementations for corner cases. |
81 */ |
84 */ |
116 const void *elem, |
120 const void *elem, |
117 int prepend |
121 int prepend |
118 ); |
122 ); |
119 |
123 |
120 /** |
124 /** |
121 * Member function for removing an element. |
125 * Member function for removing elements. |
122 */ |
126 * |
123 int (*remove)( |
127 * Implementations SHALL check if @p targetbuf is set and copy the elements |
|
128 * to the buffer without invoking any destructor. |
|
129 * When @p targetbuf is not set, the destructors SHALL be invoked. |
|
130 * |
|
131 * The function SHALL return the actual number of elements removed, which |
|
132 * might be lower than @p num when going out of bounds. |
|
133 */ |
|
134 size_t (*remove)( |
124 struct cx_list_s *list, |
135 struct cx_list_s *list, |
125 size_t index |
136 size_t index, |
|
137 size_t num, |
|
138 void *targetbuf |
126 ); |
139 ); |
127 |
140 |
128 /** |
141 /** |
129 * Member function for removing all elements. |
142 * Member function for removing all elements. |
130 */ |
143 */ |
131 void (*clear)(struct cx_list_s *list); |
144 void (*clear)(struct cx_list_s *list); |
132 |
145 |
133 /** |
146 /** |
134 * Member function for swapping two elements. |
147 * Member function for swapping two elements. |
|
148 * |
135 * @see cx_list_default_swap() |
149 * @see cx_list_default_swap() |
136 */ |
150 */ |
137 int (*swap)( |
151 int (*swap)( |
138 struct cx_list_s *list, |
152 struct cx_list_s *list, |
139 size_t i, |
153 size_t i, |
156 const void *elem, |
170 const void *elem, |
157 bool remove |
171 bool remove |
158 ); |
172 ); |
159 |
173 |
160 /** |
174 /** |
161 * Member function for sorting the list in-place. |
175 * Member function for sorting the list. |
|
176 * |
162 * @see cx_list_default_sort() |
177 * @see cx_list_default_sort() |
163 */ |
178 */ |
164 void (*sort)(struct cx_list_s *list); |
179 void (*sort)(struct cx_list_s *list); |
165 |
180 |
166 /** |
181 /** |
167 * Optional member function for comparing this list |
182 * Optional member function for comparing this list |
168 * to another list of the same type. |
183 * to another list of the same type. |
169 * If set to \c NULL, comparison won't be optimized. |
184 * If set to @c NULL, comparison won't be optimized. |
170 */ |
185 */ |
|
186 cx_attr_nonnull |
171 int (*compare)( |
187 int (*compare)( |
172 const struct cx_list_s *list, |
188 const struct cx_list_s *list, |
173 const struct cx_list_s *other |
189 const struct cx_list_s *other |
174 ); |
190 ); |
175 |
191 |
214 * Default implementation of a sorted insert. |
230 * Default implementation of a sorted insert. |
215 * |
231 * |
216 * This function uses the array insert function to insert consecutive groups |
232 * This function uses the array insert function to insert consecutive groups |
217 * of sorted data. |
233 * of sorted data. |
218 * |
234 * |
219 * The source data \em must already be sorted wrt. the list's compare function. |
235 * The source data @em must already be sorted wrt. the list's compare function. |
220 * |
236 * |
221 * Use this in your own list class if you do not want to implement an optimized |
237 * Use this in your own list class if you do not want to implement an optimized |
222 * version for your list. |
238 * version for your list. |
223 * |
239 * |
224 * @param list the list |
240 * @param list the list |
225 * @param sorted_data a pointer to the array of pre-sorted data to insert |
241 * @param sorted_data a pointer to the array of pre-sorted data to insert |
226 * @param n the number of elements to insert |
242 * @param n the number of elements to insert |
227 * @return the number of elements actually inserted |
243 * @return the number of elements actually inserted |
228 */ |
244 */ |
229 __attribute__((__nonnull__)) |
245 cx_attr_nonnull |
230 size_t cx_list_default_insert_sorted( |
246 size_t cx_list_default_insert_sorted( |
231 struct cx_list_s *list, |
247 struct cx_list_s *list, |
232 const void *sorted_data, |
248 const void *sorted_data, |
233 size_t n |
249 size_t n |
234 ); |
250 ); |
254 * version for your list. |
270 * version for your list. |
255 * |
271 * |
256 * @param list the list in which to swap |
272 * @param list the list in which to swap |
257 * @param i index of one element |
273 * @param i index of one element |
258 * @param j index of the other element |
274 * @param j index of the other element |
259 * @return zero on success, non-zero when indices are out of bounds or memory |
275 * @retval zero success |
|
276 * @retval non-zero when indices are out of bounds or memory |
260 * allocation for the temporary buffer fails |
277 * allocation for the temporary buffer fails |
261 */ |
278 */ |
262 __attribute__((__nonnull__)) |
279 cx_attr_nonnull |
263 int cx_list_default_swap(struct cx_list_s *list, size_t i, size_t j); |
280 int cx_list_default_swap(struct cx_list_s *list, size_t i, size_t j); |
264 |
281 |
265 /** |
282 /** |
266 * Common type for all list implementations. |
283 * Common type for all list implementations. |
267 */ |
284 */ |
289 * objects is undefined. |
306 * objects is undefined. |
290 * |
307 * |
291 * @param list the list |
308 * @param list the list |
292 * @see cxListStoreObjects() |
309 * @see cxListStoreObjects() |
293 */ |
310 */ |
294 __attribute__((__nonnull__)) |
311 cx_attr_nonnull |
295 void cxListStorePointers(CxList *list); |
312 void cxListStorePointers(CxList *list); |
296 |
313 |
297 /** |
314 /** |
298 * Returns true, if this list is storing pointers instead of the actual data. |
315 * Returns true, if this list is storing pointers instead of the actual data. |
299 * |
316 * |
300 * @param list |
317 * @param list |
301 * @return true, if this list is storing pointers |
318 * @return true, if this list is storing pointers |
302 * @see cxListStorePointers() |
319 * @see cxListStorePointers() |
303 */ |
320 */ |
304 __attribute__((__nonnull__)) |
321 cx_attr_nonnull |
305 static inline bool cxListIsStoringPointers(const CxList *list) { |
322 static inline bool cxListIsStoringPointers(const CxList *list) { |
306 return list->collection.store_pointer; |
323 return list->collection.store_pointer; |
307 } |
324 } |
308 |
325 |
309 /** |
326 /** |
310 * Returns the number of elements currently stored in the list. |
327 * Returns the number of elements currently stored in the list. |
311 * |
328 * |
312 * @param list the list |
329 * @param list the list |
313 * @return the number of currently stored elements |
330 * @return the number of currently stored elements |
314 */ |
331 */ |
315 __attribute__((__nonnull__)) |
332 cx_attr_nonnull |
316 static inline size_t cxListSize(const CxList *list) { |
333 static inline size_t cxListSize(const CxList *list) { |
317 return list->collection.size; |
334 return list->collection.size; |
318 } |
335 } |
319 |
336 |
320 /** |
337 /** |
321 * Adds an item to the end of the list. |
338 * Adds an item to the end of the list. |
322 * |
339 * |
323 * @param list the list |
340 * @param list the list |
324 * @param elem a pointer to the element to add |
341 * @param elem a pointer to the element to add |
325 * @return zero on success, non-zero on memory allocation failure |
342 * @retval zero success |
|
343 * @retval non-zero memory allocation failure |
326 * @see cxListAddArray() |
344 * @see cxListAddArray() |
327 */ |
345 */ |
328 __attribute__((__nonnull__)) |
346 cx_attr_nonnull |
329 static inline int cxListAdd( |
347 static inline int cxListAdd( |
330 CxList *list, |
348 CxList *list, |
331 const void *elem |
349 const void *elem |
332 ) { |
350 ) { |
333 return list->cl->insert_element(list, list->collection.size, elem); |
351 return list->cl->insert_element(list, list->collection.size, elem); |
337 * Adds multiple items to the end of the list. |
355 * Adds multiple items to the end of the list. |
338 * |
356 * |
339 * This method is more efficient than invoking cxListAdd() multiple times. |
357 * This method is more efficient than invoking cxListAdd() multiple times. |
340 * |
358 * |
341 * If there is not enough memory to add all elements, the returned value is |
359 * If there is not enough memory to add all elements, the returned value is |
342 * less than \p n. |
360 * less than @p n. |
343 * |
361 * |
344 * If this list is storing pointers instead of objects \p array is expected to |
362 * If this list is storing pointers instead of objects @p array is expected to |
345 * be an array of pointers. |
363 * be an array of pointers. |
346 * |
364 * |
347 * @param list the list |
365 * @param list the list |
348 * @param array a pointer to the elements to add |
366 * @param array a pointer to the elements to add |
349 * @param n the number of elements to add |
367 * @param n the number of elements to add |
350 * @return the number of added elements |
368 * @return the number of added elements |
351 */ |
369 */ |
352 __attribute__((__nonnull__)) |
370 cx_attr_nonnull |
353 static inline size_t cxListAddArray( |
371 static inline size_t cxListAddArray( |
354 CxList *list, |
372 CxList *list, |
355 const void *array, |
373 const void *array, |
356 size_t n |
374 size_t n |
357 ) { |
375 ) { |
359 } |
377 } |
360 |
378 |
361 /** |
379 /** |
362 * Inserts an item at the specified index. |
380 * Inserts an item at the specified index. |
363 * |
381 * |
364 * If \p index equals the list \c size, this is effectively cxListAdd(). |
382 * If @p index equals the list @c size, this is effectively cxListAdd(). |
365 * |
383 * |
366 * @param list the list |
384 * @param list the list |
367 * @param index the index the element shall have |
385 * @param index the index the element shall have |
368 * @param elem a pointer to the element to add |
386 * @param elem a pointer to the element to add |
369 * @return zero on success, non-zero on memory allocation failure |
387 * @retval zero success |
370 * or when the index is out of bounds |
388 * @retval non-zero memory allocation failure or the index is out of bounds |
371 * @see cxListInsertAfter() |
389 * @see cxListInsertAfter() |
372 * @see cxListInsertBefore() |
390 * @see cxListInsertBefore() |
373 */ |
391 */ |
374 __attribute__((__nonnull__)) |
392 cx_attr_nonnull |
375 static inline int cxListInsert( |
393 static inline int cxListInsert( |
376 CxList *list, |
394 CxList *list, |
377 size_t index, |
395 size_t index, |
378 const void *elem |
396 const void *elem |
379 ) { |
397 ) { |
383 /** |
401 /** |
384 * Inserts an item into a sorted list. |
402 * Inserts an item into a sorted list. |
385 * |
403 * |
386 * @param list the list |
404 * @param list the list |
387 * @param elem a pointer to the element to add |
405 * @param elem a pointer to the element to add |
388 * @return zero on success, non-zero on memory allocation failure |
406 * @retval zero success |
389 */ |
407 * @retval non-zero memory allocation failure |
390 __attribute__((__nonnull__)) |
408 */ |
|
409 cx_attr_nonnull |
391 static inline int cxListInsertSorted( |
410 static inline int cxListInsertSorted( |
392 CxList *list, |
411 CxList *list, |
393 const void *elem |
412 const void *elem |
394 ) { |
413 ) { |
395 const void *data = list->collection.store_pointer ? &elem : elem; |
414 const void *data = list->collection.store_pointer ? &elem : elem; |
396 return list->cl->insert_sorted(list, data, 1) == 0; |
415 return list->cl->insert_sorted(list, data, 1) == 0; |
397 } |
416 } |
398 |
417 |
399 /** |
418 /** |
400 * Inserts multiple items to the list at the specified index. |
419 * Inserts multiple items to the list at the specified index. |
401 * If \p index equals the list size, this is effectively cxListAddArray(). |
420 * If @p index equals the list size, this is effectively cxListAddArray(). |
402 * |
421 * |
403 * This method is usually more efficient than invoking cxListInsert() |
422 * This method is usually more efficient than invoking cxListInsert() |
404 * multiple times. |
423 * multiple times. |
405 * |
424 * |
406 * If there is not enough memory to add all elements, the returned value is |
425 * If there is not enough memory to add all elements, the returned value is |
407 * less than \p n. |
426 * less than @p n. |
408 * |
427 * |
409 * If this list is storing pointers instead of objects \p array is expected to |
428 * If this list is storing pointers instead of objects @p array is expected to |
410 * be an array of pointers. |
429 * be an array of pointers. |
411 * |
430 * |
412 * @param list the list |
431 * @param list the list |
413 * @param index the index where to add the elements |
432 * @param index the index where to add the elements |
414 * @param array a pointer to the elements to add |
433 * @param array a pointer to the elements to add |
415 * @param n the number of elements to add |
434 * @param n the number of elements to add |
416 * @return the number of added elements |
435 * @return the number of added elements |
417 */ |
436 */ |
418 __attribute__((__nonnull__)) |
437 cx_attr_nonnull |
419 static inline size_t cxListInsertArray( |
438 static inline size_t cxListInsertArray( |
420 CxList *list, |
439 CxList *list, |
421 size_t index, |
440 size_t index, |
422 const void *array, |
441 const void *array, |
423 size_t n |
442 size_t n |
430 * |
449 * |
431 * This method is usually more efficient than inserting each element separately, |
450 * This method is usually more efficient than inserting each element separately, |
432 * because consecutive chunks of sorted data are inserted in one pass. |
451 * because consecutive chunks of sorted data are inserted in one pass. |
433 * |
452 * |
434 * If there is not enough memory to add all elements, the returned value is |
453 * If there is not enough memory to add all elements, the returned value is |
435 * less than \p n. |
454 * less than @p n. |
436 * |
455 * |
437 * If this list is storing pointers instead of objects \p array is expected to |
456 * If this list is storing pointers instead of objects @p array is expected to |
438 * be an array of pointers. |
457 * be an array of pointers. |
439 * |
458 * |
440 * @param list the list |
459 * @param list the list |
441 * @param array a pointer to the elements to add |
460 * @param array a pointer to the elements to add |
442 * @param n the number of elements to add |
461 * @param n the number of elements to add |
443 * @return the number of added elements |
462 * @return the number of added elements |
444 */ |
463 */ |
445 __attribute__((__nonnull__)) |
464 cx_attr_nonnull |
446 static inline size_t cxListInsertSortedArray( |
465 static inline size_t cxListInsertSortedArray( |
447 CxList *list, |
466 CxList *list, |
448 const void *array, |
467 const void *array, |
449 size_t n |
468 size_t n |
450 ) { |
469 ) { |
455 * Inserts an element after the current location of the specified iterator. |
474 * Inserts an element after the current location of the specified iterator. |
456 * |
475 * |
457 * The used iterator remains operational, but all other active iterators should |
476 * The used iterator remains operational, but all other active iterators should |
458 * be considered invalidated. |
477 * be considered invalidated. |
459 * |
478 * |
460 * If \p iter is not a list iterator, the behavior is undefined. |
479 * If @p iter is not a list iterator, the behavior is undefined. |
461 * If \p iter is a past-the-end iterator, the new element gets appended to the list. |
480 * If @p iter is a past-the-end iterator, the new element gets appended to the list. |
462 * |
481 * |
463 * @param iter an iterator |
482 * @param iter an iterator |
464 * @param elem the element to insert |
483 * @param elem the element to insert |
465 * @return zero on success, non-zero on memory allocation failure |
484 * @retval zero success |
|
485 * @retval non-zero memory allocation failure |
466 * @see cxListInsert() |
486 * @see cxListInsert() |
467 * @see cxListInsertBefore() |
487 * @see cxListInsertBefore() |
468 */ |
488 */ |
469 __attribute__((__nonnull__)) |
489 cx_attr_nonnull |
470 static inline int cxListInsertAfter( |
490 static inline int cxListInsertAfter( |
471 CxIterator *iter, |
491 CxIterator *iter, |
472 const void *elem |
492 const void *elem |
473 ) { |
493 ) { |
474 return ((struct cx_list_s *) iter->src_handle.m)->cl->insert_iter(iter, elem, 0); |
494 return ((struct cx_list_s *) iter->src_handle.m)->cl->insert_iter(iter, elem, 0); |
478 * Inserts an element before the current location of the specified iterator. |
498 * Inserts an element before the current location of the specified iterator. |
479 * |
499 * |
480 * The used iterator remains operational, but all other active iterators should |
500 * The used iterator remains operational, but all other active iterators should |
481 * be considered invalidated. |
501 * be considered invalidated. |
482 * |
502 * |
483 * If \p iter is not a list iterator, the behavior is undefined. |
503 * If @p iter is not a list iterator, the behavior is undefined. |
484 * If \p iter is a past-the-end iterator, the new element gets appended to the list. |
504 * If @p iter is a past-the-end iterator, the new element gets appended to the list. |
485 * |
505 * |
486 * @param iter an iterator |
506 * @param iter an iterator |
487 * @param elem the element to insert |
507 * @param elem the element to insert |
488 * @return zero on success, non-zero on memory allocation failure |
508 * @retval zero success |
|
509 * @retval non-zero memory allocation failure |
489 * @see cxListInsert() |
510 * @see cxListInsert() |
490 * @see cxListInsertAfter() |
511 * @see cxListInsertAfter() |
491 */ |
512 */ |
492 __attribute__((__nonnull__)) |
513 cx_attr_nonnull |
493 static inline int cxListInsertBefore( |
514 static inline int cxListInsertBefore( |
494 CxIterator *iter, |
515 CxIterator *iter, |
495 const void *elem |
516 const void *elem |
496 ) { |
517 ) { |
497 return ((struct cx_list_s *) iter->src_handle.m)->cl->insert_iter(iter, elem, 1); |
518 return ((struct cx_list_s *) iter->src_handle.m)->cl->insert_iter(iter, elem, 1); |
503 * If an element destructor function is specified, it is called before |
524 * If an element destructor function is specified, it is called before |
504 * removing the element. |
525 * removing the element. |
505 * |
526 * |
506 * @param list the list |
527 * @param list the list |
507 * @param index the index of the element |
528 * @param index the index of the element |
508 * @return zero on success, non-zero if the index is out of bounds |
529 * @retval zero success |
509 */ |
530 * @retval non-zero index out of bounds |
510 __attribute__((__nonnull__)) |
531 */ |
|
532 cx_attr_nonnull |
511 static inline int cxListRemove( |
533 static inline int cxListRemove( |
512 CxList *list, |
534 CxList *list, |
513 size_t index |
535 size_t index |
514 ) { |
536 ) { |
515 return list->cl->remove(list, index); |
537 return list->cl->remove(list, index, 1, NULL) == 0; |
|
538 } |
|
539 |
|
540 /** |
|
541 * Removes and returns the element at the specified index. |
|
542 * |
|
543 * No destructor is called and instead the element is copied to the |
|
544 * @p targetbuf which MUST be large enough to hold the removed element. |
|
545 * |
|
546 * @param list the list |
|
547 * @param index the index of the element |
|
548 * @param targetbuf a buffer where to copy the element |
|
549 * @retval zero success |
|
550 * @retval non-zero index out of bounds |
|
551 */ |
|
552 cx_attr_nonnull |
|
553 cx_attr_access_w(3) |
|
554 static inline int cxListRemoveAndGet( |
|
555 CxList *list, |
|
556 size_t index, |
|
557 void *targetbuf |
|
558 ) { |
|
559 return list->cl->remove(list, index, 1, targetbuf) == 0; |
|
560 } |
|
561 |
|
562 /** |
|
563 * Removes multiple element starting at the specified index. |
|
564 * |
|
565 * If an element destructor function is specified, it is called for each |
|
566 * element. It is guaranteed that the destructor is called before removing |
|
567 * the element, however, due to possible optimizations it is neither guaranteed |
|
568 * that the destructors are invoked for all elements before starting to remove |
|
569 * them, nor that the element is removed immediately after the destructor call |
|
570 * before proceeding to the next element. |
|
571 * |
|
572 * @param list the list |
|
573 * @param index the index of the element |
|
574 * @param num the number of elements to remove |
|
575 * @return the actual number of removed elements |
|
576 */ |
|
577 cx_attr_nonnull |
|
578 static inline size_t cxListRemoveArray( |
|
579 CxList *list, |
|
580 size_t index, |
|
581 size_t num |
|
582 ) { |
|
583 return list->cl->remove(list, index, num, NULL); |
|
584 } |
|
585 |
|
586 /** |
|
587 * Removes and returns multiple element starting at the specified index. |
|
588 * |
|
589 * No destructor is called and instead the elements are copied to the |
|
590 * @p targetbuf which MUST be large enough to hold all removed elements. |
|
591 * |
|
592 * @param list the list |
|
593 * @param index the index of the element |
|
594 * @param num the number of elements to remove |
|
595 * @param targetbuf a buffer where to copy the elements |
|
596 * @return the actual number of removed elements |
|
597 */ |
|
598 cx_attr_nonnull |
|
599 cx_attr_access_w(4) |
|
600 static inline size_t cxListRemoveArrayAndGet( |
|
601 CxList *list, |
|
602 size_t index, |
|
603 size_t num, |
|
604 void *targetbuf |
|
605 ) { |
|
606 return list->cl->remove(list, index, num, targetbuf); |
516 } |
607 } |
517 |
608 |
518 /** |
609 /** |
519 * Removes all elements from this list. |
610 * Removes all elements from this list. |
520 * |
611 * |
521 * If an element destructor function is specified, it is called for each |
612 * If element destructor functions are specified, they are called for each |
522 * element before removing them. |
613 * element before removing them. |
523 * |
614 * |
524 * @param list the list |
615 * @param list the list |
525 */ |
616 */ |
526 __attribute__((__nonnull__)) |
617 cx_attr_nonnull |
527 static inline void cxListClear(CxList *list) { |
618 static inline void cxListClear(CxList *list) { |
528 list->cl->clear(list); |
619 list->cl->clear(list); |
529 } |
620 } |
530 |
621 |
531 /** |
622 /** |
690 * If the list is empty, a past-the-end iterator will be returned. |
790 * If the list is empty, a past-the-end iterator will be returned. |
691 * |
791 * |
692 * @param list the list |
792 * @param list the list |
693 * @return a new iterator |
793 * @return a new iterator |
694 */ |
794 */ |
695 __attribute__((__nonnull__, __warn_unused_result__)) |
795 cx_attr_nonnull |
|
796 cx_attr_nodiscard |
696 static inline CxIterator cxListMutBackwardsIterator(CxList *list) { |
797 static inline CxIterator cxListMutBackwardsIterator(CxList *list) { |
697 return cxListMutBackwardsIteratorAt(list, list->collection.size - 1); |
798 return cxListMutBackwardsIteratorAt(list, list->collection.size - 1); |
698 } |
799 } |
699 |
800 |
700 /** |
801 /** |
701 * Returns the index of the first element that equals \p elem. |
802 * Returns the index of the first element that equals @p elem. |
702 * |
803 * |
703 * Determining equality is performed by the list's comparator function. |
804 * Determining equality is performed by the list's comparator function. |
704 * |
805 * |
705 * @param list the list |
806 * @param list the list |
706 * @param elem the element to find |
807 * @param elem the element to find |
707 * @return the index of the element or a negative |
808 * @return the index of the element or a negative |
708 * value when the element is not found |
809 * value when the element is not found |
709 */ |
810 */ |
710 __attribute__((__nonnull__)) |
811 cx_attr_nonnull |
|
812 cx_attr_nodiscard |
711 static inline ssize_t cxListFind( |
813 static inline ssize_t cxListFind( |
712 const CxList *list, |
814 const CxList *list, |
713 const void *elem |
815 const void *elem |
714 ) { |
816 ) { |
715 return list->cl->find_remove((CxList*)list, elem, false); |
817 return list->cl->find_remove((CxList*)list, elem, false); |
716 } |
818 } |
717 |
819 |
718 /** |
820 /** |
719 * Removes and returns the index of the first element that equals \p elem. |
821 * Removes and returns the index of the first element that equals @p elem. |
720 * |
822 * |
721 * Determining equality is performed by the list's comparator function. |
823 * Determining equality is performed by the list's comparator function. |
722 * |
824 * |
723 * @param list the list |
825 * @param list the list |
724 * @param elem the element to find and remove |
826 * @param elem the element to find and remove |
725 * @return the index of the now removed element or a negative |
827 * @return the index of the now removed element or a negative |
726 * value when the element is not found or could not be removed |
828 * value when the element is not found or could not be removed |
727 */ |
829 */ |
728 __attribute__((__nonnull__)) |
830 cx_attr_nonnull |
729 static inline ssize_t cxListFindRemove( |
831 static inline ssize_t cxListFindRemove( |
730 CxList *list, |
832 CxList *list, |
731 const void *elem |
833 const void *elem |
732 ) { |
834 ) { |
733 return list->cl->find_remove(list, elem, true); |
835 return list->cl->find_remove(list, elem, true); |
734 } |
836 } |
735 |
837 |
736 /** |
838 /** |
737 * Sorts the list in-place. |
839 * Sorts the list. |
738 * |
840 * |
739 * \remark The underlying sort algorithm is implementation defined. |
841 * @remark The underlying sort algorithm is implementation defined. |
740 * |
842 * |
741 * @param list the list |
843 * @param list the list |
742 */ |
844 */ |
743 __attribute__((__nonnull__)) |
845 cx_attr_nonnull |
744 static inline void cxListSort(CxList *list) { |
846 static inline void cxListSort(CxList *list) { |
745 list->cl->sort(list); |
847 list->cl->sort(list); |
746 } |
848 } |
747 |
849 |
748 /** |
850 /** |
749 * Reverses the order of the items. |
851 * Reverses the order of the items. |
750 * |
852 * |
751 * @param list the list |
853 * @param list the list |
752 */ |
854 */ |
753 __attribute__((__nonnull__)) |
855 cx_attr_nonnull |
754 static inline void cxListReverse(CxList *list) { |
856 static inline void cxListReverse(CxList *list) { |
755 list->cl->reverse(list); |
857 list->cl->reverse(list); |
756 } |
858 } |
757 |
859 |
758 /** |
860 /** |
761 * First, the list sizes are compared. |
863 * First, the list sizes are compared. |
762 * If they match, the lists are compared element-wise. |
864 * If they match, the lists are compared element-wise. |
763 * |
865 * |
764 * @param list the list |
866 * @param list the list |
765 * @param other the list to compare to |
867 * @param other the list to compare to |
766 * @return zero, if both lists are equal element wise, |
868 * @retval zero both lists are equal element wise |
767 * negative if the first list is smaller, positive if the first list is larger |
869 * @retval negative the first list is smaller |
768 */ |
870 * or the first non-equal element in the first list is smaller |
769 __attribute__((__nonnull__)) |
871 * @retval positive the first list is larger |
|
872 * or the first non-equal element in the first list is larger |
|
873 */ |
|
874 cx_attr_nonnull |
|
875 cx_attr_nodiscard |
770 int cxListCompare( |
876 int cxListCompare( |
771 const CxList *list, |
877 const CxList *list, |
772 const CxList *other |
878 const CxList *other |
773 ); |
879 ); |
774 |
880 |
775 /** |
881 /** |
776 * Deallocates the memory of the specified list structure. |
882 * Deallocates the memory of the specified list structure. |
777 * |
883 * |
778 * Also calls content a destructor function, depending on the configuration |
884 * Also calls the content destructor functions for each element, if specified. |
779 * in CxList.content_destructor_type. |
885 * |
780 * |
886 * @param list the list which shall be freed |
781 * This function itself is a destructor function for the CxList. |
887 */ |
782 * |
888 void cxListFree(CxList *list); |
783 * @param list the list which shall be destroyed |
|
784 */ |
|
785 __attribute__((__nonnull__)) |
|
786 void cxListDestroy(CxList *list); |
|
787 |
889 |
788 /** |
890 /** |
789 * A shared instance of an empty list. |
891 * A shared instance of an empty list. |
790 * |
892 * |
791 * Writing to that list is undefined. |
893 * Writing to that list is not allowed. |
792 */ |
894 * |
793 extern CxList * const cxEmptyList; |
895 * You can use this is a placeholder for initializing CxList pointers |
|
896 * for which you do not want to reserve memory right from the beginning. |
|
897 */ |
|
898 extern CxList *const cxEmptyList; |
794 |
899 |
795 |
900 |
796 #ifdef __cplusplus |
901 #ifdef __cplusplus |
797 } // extern "C" |
902 } // extern "C" |
798 #endif |
903 #endif |