| 78 */ |
78 */ |
| 79 void (*deallocate)(struct cx_list_s *list); |
79 void (*deallocate)(struct cx_list_s *list); |
| 80 |
80 |
| 81 /** |
81 /** |
| 82 * Member function for inserting a single element. |
82 * Member function for inserting a single element. |
| 83 * The data pointer may be @c NULL in which case the function shall only allocate memory. |
83 * The data pointer may be @c NULL, in which case the function shall only allocate memory. |
| 84 * Returns a pointer to the data of the inserted element. |
84 * Returns a pointer to the allocated memory or @c NULL if allocation fails. |
| 85 */ |
85 */ |
| 86 void *(*insert_element)( |
86 void *(*insert_element)(struct cx_list_s *list, size_t index, const void *data); |
| 87 struct cx_list_s *list, |
|
| 88 size_t index, |
|
| 89 const void *data |
|
| 90 ); |
|
| 91 |
87 |
| 92 /** |
88 /** |
| 93 * Member function for inserting multiple elements. |
89 * Member function for inserting multiple elements. |
| 94 * |
90 * |
| |
91 * The data pointer may be @c NULL, in which case the function shall only allocate memory. |
| |
92 * Returns the number of successfully inserted or allocated elements. |
| |
93 * |
| 95 * @see cx_list_default_insert_array() |
94 * @see cx_list_default_insert_array() |
| 96 */ |
95 */ |
| 97 size_t (*insert_array)( |
96 size_t (*insert_array)(struct cx_list_s *list, size_t index, const void *data, size_t n); |
| 98 struct cx_list_s *list, |
|
| 99 size_t index, |
|
| 100 const void *data, |
|
| 101 size_t n |
|
| 102 ); |
|
| 103 |
97 |
| 104 /** |
98 /** |
| 105 * Member function for inserting sorted elements into a sorted list. |
99 * Member function for inserting sorted elements into a sorted list. |
| |
100 * Returns the number of successfully inserted elements. |
| 106 * |
101 * |
| 107 * @see cx_list_default_insert_sorted() |
102 * @see cx_list_default_insert_sorted() |
| 108 */ |
103 */ |
| 109 size_t (*insert_sorted)( |
104 size_t (*insert_sorted)(struct cx_list_s *list, const void *sorted_data, size_t n); |
| 110 struct cx_list_s *list, |
105 |
| 111 const void *sorted_data, |
106 /** |
| 112 size_t n |
107 * Member function for inserting multiple elements if they do not exist. |
| 113 ); |
108 * Implementations shall return the number of successfully processed elements |
| |
109 * (including those which were not added because they are already contained). |
| |
110 * @see cx_list_default_insert_unique() |
| |
111 */ |
| |
112 size_t (*insert_unique)(struct cx_list_s *list, const void *sorted_data, size_t n); |
| 114 |
113 |
| 115 /** |
114 /** |
| 116 * Member function for inserting an element relative to an iterator position. |
115 * Member function for inserting an element relative to an iterator position. |
| 117 */ |
116 */ |
| 118 int (*insert_iter)( |
117 int (*insert_iter)(struct cx_iterator_s *iter, const void *elem, int prepend); |
| 119 struct cx_iterator_s *iter, |
|
| 120 const void *elem, |
|
| 121 int prepend |
|
| 122 ); |
|
| 123 |
118 |
| 124 /** |
119 /** |
| 125 * Member function for removing elements. |
120 * Member function for removing elements. |
| 126 * |
121 * |
| 127 * Implementations SHALL check if @p targetbuf is set and copy the elements |
122 * Implementations SHALL check if @p targetbuf is set and copy the elements |
| 373 * @retval non-zero memory allocation failure |
345 * @retval non-zero memory allocation failure |
| 374 * @see cxListAddArray() |
346 * @see cxListAddArray() |
| 375 * @see cxListEmplace() |
347 * @see cxListEmplace() |
| 376 */ |
348 */ |
| 377 cx_attr_nonnull |
349 cx_attr_nonnull |
| 378 static inline int cxListAdd( |
350 CX_EXPORT int cxListAdd(CxList *list, const void *elem); |
| 379 CxList *list, |
|
| 380 const void *elem |
|
| 381 ) { |
|
| 382 list->collection.sorted = false; |
|
| 383 return list->cl->insert_element(list, list->collection.size, elem) == NULL; |
|
| 384 } |
|
| 385 |
351 |
| 386 /** |
352 /** |
| 387 * Adds multiple items to the end of the list. |
353 * Adds multiple items to the end of the list. |
| 388 * |
354 * |
| 389 * This method is more efficient than invoking cxListAdd() multiple times. |
355 * This method is more efficient than invoking cxListAdd() multiple times. |
| 390 * |
356 * |
| 391 * If there is not enough memory to add all elements, the returned value is |
357 * If there is not enough memory to add all elements, the returned value is |
| 392 * less than @p n. |
358 * less than @p n. |
| 393 * |
359 * |
| 394 * If this list is storing pointers instead of objects @p array is expected to |
360 * If this list is storing pointers instead of objects, @p array is expected to |
| 395 * be an array of pointers. |
361 * be an array of pointers. |
| 396 * |
362 * |
| 397 * @param list the list |
363 * @param list the list |
| 398 * @param array a pointer to the elements to add |
364 * @param array a pointer to the elements to add |
| 399 * @param n the number of elements to add |
365 * @param n the number of elements to add |
| 400 * @return the number of added elements |
366 * @return the number of added elements |
| 401 */ |
367 * @see cxListEmplaceArray() |
| 402 cx_attr_nonnull |
368 */ |
| 403 static inline size_t cxListAddArray( |
369 cx_attr_nonnull |
| 404 CxList *list, |
370 CX_EXPORT size_t cxListAddArray(CxList *list, const void *array, size_t n); |
| 405 const void *array, |
|
| 406 size_t n |
|
| 407 ) { |
|
| 408 list->collection.sorted = false; |
|
| 409 return list->cl->insert_array(list, list->collection.size, array, n); |
|
| 410 } |
|
| 411 |
371 |
| 412 /** |
372 /** |
| 413 * Inserts an item at the specified index. |
373 * Inserts an item at the specified index. |
| 414 * |
374 * |
| 415 * If @p index equals the list @c size, this is effectively cxListAdd(). |
375 * If the @p index equals the list @c size, this is effectively cxListAdd(). |
| 416 * |
376 * |
| 417 * @param list the list |
377 * @param list the list |
| 418 * @param index the index the element shall have |
378 * @param index the index the element shall have |
| 419 * @param elem a pointer to the element to add |
379 * @param elem a pointer to the element to add |
| 420 * @retval zero success |
380 * @retval zero success |
| 460 * @return a pointer to the allocated memory; @c NULL when the operation fails, or the index is out-of-bounds |
410 * @return a pointer to the allocated memory; @c NULL when the operation fails, or the index is out-of-bounds |
| 461 * @see cxListEmplaceAt() |
411 * @see cxListEmplaceAt() |
| 462 * @see cxListAdd() |
412 * @see cxListAdd() |
| 463 */ |
413 */ |
| 464 cx_attr_nonnull |
414 cx_attr_nonnull |
| 465 static inline void *cxListEmplace(CxList *list) { |
415 CX_EXPORT void *cxListEmplace(CxList *list); |
| 466 list->collection.sorted = false; |
416 |
| 467 return list->cl->insert_element(list, list->collection.size, NULL); |
417 /** |
| 468 } |
418 * Allocates memory for multiple elements and returns an iterator. |
| |
419 * |
| |
420 * The iterator will only iterate over the successfully allocated elements. |
| |
421 * The @c elem_count attribute is set to that number, and the @c index attribute |
| |
422 * will range from zero to @c elem_count minus one. |
| |
423 * |
| |
424 * @remark When the list is storing pointers, the iterator will iterate over |
| |
425 * the @c void** elements. |
| |
426 * |
| |
427 * @param list the list |
| |
428 * @param index the index where to insert the new data |
| |
429 * @param n the number of elements for which to allocate the memory |
| |
430 * @return an iterator, iterating over the new memory |
| |
431 * @see cxListEmplaceAt() |
| |
432 * @see cxListInsertArray() |
| |
433 */ |
| |
434 cx_attr_nonnull |
| |
435 CX_EXPORT CxIterator cxListEmplaceArrayAt(CxList *list, size_t index, size_t n); |
| |
436 |
| |
437 /** |
| |
438 * Allocates memory for multiple elements and returns an iterator. |
| |
439 * |
| |
440 * The iterator will only iterate over the successfully allocated elements. |
| |
441 * The @c elem_count attribute is set to that number, and the @c index attribute |
| |
442 * will range from zero to @c elem_count minus one. |
| |
443 * |
| |
444 * @remark When the list is storing pointers, the iterator will iterate over |
| |
445 * the @c void** elements. |
| |
446 * |
| |
447 * @param list the list |
| |
448 * @param n the number of elements for which to allocate the memory |
| |
449 * @return an iterator, iterating over the new memory |
| |
450 * @see cxListEmplace() |
| |
451 * @see cxListAddArray() |
| |
452 */ |
| |
453 cx_attr_nonnull |
| |
454 CX_EXPORT CxIterator cxListEmplaceArray(CxList *list, size_t n); |
| 469 |
455 |
| 470 /** |
456 /** |
| 471 * Inserts an item into a sorted list. |
457 * Inserts an item into a sorted list. |
| 472 * |
458 * |
| 473 * If the list is not sorted already, the behavior is undefined. |
459 * If the list is not sorted already, the behavior is undefined. |
| 476 * @param elem a pointer to the element to add |
462 * @param elem a pointer to the element to add |
| 477 * @retval zero success |
463 * @retval zero success |
| 478 * @retval non-zero memory allocation failure |
464 * @retval non-zero memory allocation failure |
| 479 */ |
465 */ |
| 480 cx_attr_nonnull |
466 cx_attr_nonnull |
| 481 static inline int cxListInsertSorted( |
467 CX_EXPORT int cxListInsertSorted(CxList *list, const void *elem); |
| 482 CxList *list, |
468 |
| 483 const void *elem |
469 /** |
| 484 ) { |
470 * Inserts an item into a list if it does not exist. |
| 485 list->collection.sorted = true; // guaranteed by definition |
471 * |
| 486 const void *data = list->collection.store_pointer ? &elem : elem; |
472 * If the list is not sorted already, this function will check all elements |
| 487 return list->cl->insert_sorted(list, data, 1) == 0; |
473 * and append the new element when it was not found. |
| 488 } |
474 * It is strongly recommended to use this function only on sorted lists, where |
| |
475 * the element, if it is not contained, is inserted at the correct position. |
| |
476 * |
| |
477 * @param list the list |
| |
478 * @param elem a pointer to the element to add |
| |
479 * @retval zero success (also when the element was already in the list) |
| |
480 * @retval non-zero memory allocation failure |
| |
481 */ |
| |
482 cx_attr_nonnull |
| |
483 CX_EXPORT int cxListInsertUnique(CxList *list, const void *elem); |
| 489 |
484 |
| 490 /** |
485 /** |
| 491 * Inserts multiple items to the list at the specified index. |
486 * Inserts multiple items to the list at the specified index. |
| 492 * If @p index equals the list size, this is effectively cxListAddArray(). |
487 * If the @p index equals the list size, this is effectively cxListAddArray(). |
| 493 * |
488 * |
| 494 * This method is usually more efficient than invoking cxListInsert() |
489 * This method is usually more efficient than invoking cxListInsert() |
| 495 * multiple times. |
490 * multiple times. |
| 496 * |
491 * |
| 497 * If there is not enough memory to add all elements, the returned value is |
492 * If there is not enough memory to add all elements, the returned value is |
| 498 * less than @p n. |
493 * less than @p n. |
| 499 * |
494 * |
| 500 * If this list is storing pointers instead of objects @p array is expected to |
495 * If this list is storing pointers instead of objects, @p array is expected to |
| 501 * be an array of pointers. |
496 * be an array of pointers. |
| 502 * |
497 * |
| 503 * @param list the list |
498 * @param list the list |
| 504 * @param index the index where to add the elements |
499 * @param index the index where to add the elements |
| 505 * @param array a pointer to the elements to add |
500 * @param array a pointer to the elements to add |
| 506 * @param n the number of elements to add |
501 * @param n the number of elements to add |
| 507 * @return the number of added elements |
502 * @return the number of added elements |
| 508 */ |
503 * @see cxListEmplaceArrayAt() |
| 509 cx_attr_nonnull |
504 */ |
| 510 static inline size_t cxListInsertArray( |
505 cx_attr_nonnull |
| 511 CxList *list, |
506 CX_EXPORT size_t cxListInsertArray(CxList *list, size_t index, const void *array, size_t n); |
| 512 size_t index, |
|
| 513 const void *array, |
|
| 514 size_t n |
|
| 515 ) { |
|
| 516 list->collection.sorted = false; |
|
| 517 return list->cl->insert_array(list, index, array, n); |
|
| 518 } |
|
| 519 |
507 |
| 520 /** |
508 /** |
| 521 * Inserts a sorted array into a sorted list. |
509 * Inserts a sorted array into a sorted list. |
| 522 * |
510 * |
| 523 * This method is usually more efficient than inserting each element separately, |
511 * This method is usually more efficient than inserting each element separately |
| 524 * because consecutive chunks of sorted data are inserted in one pass. |
512 * because consecutive chunks of sorted data are inserted in one pass. |
| 525 * |
513 * |
| 526 * If there is not enough memory to add all elements, the returned value is |
514 * If there is not enough memory to add all elements, the returned value is |
| 527 * less than @p n. |
515 * less than @p n. |
| 528 * |
516 * |
| 529 * If this list is storing pointers instead of objects @p array is expected to |
517 * If this list is storing pointers instead of objects, @p array is expected to |
| 530 * be an array of pointers. |
518 * be an array of pointers. |
| 531 * |
519 * |
| 532 * If the list is not sorted already, the behavior is undefined. |
520 * If the list is not sorted already, the behavior is undefined. |
| 533 * |
521 * |
| 534 * @param list the list |
522 * @param list the list |
| 535 * @param array a pointer to the elements to add |
523 * @param array a pointer to the elements to add |
| 536 * @param n the number of elements to add |
524 * @param n the number of elements to add |
| 537 * @return the number of added elements |
525 * @return the number of added elements |
| 538 */ |
526 */ |
| 539 cx_attr_nonnull |
527 cx_attr_nonnull |
| 540 static inline size_t cxListInsertSortedArray( |
528 CX_EXPORT size_t cxListInsertSortedArray(CxList *list, const void *array, size_t n); |
| 541 CxList *list, |
529 |
| 542 const void *array, |
530 /** |
| 543 size_t n |
531 * Inserts an array into a list, skipping duplicates. |
| 544 ) { |
532 * |
| 545 list->collection.sorted = true; // guaranteed by definition |
533 * The @p list does not need to be sorted (in contrast to cxListInsertSortedArray()). |
| 546 return list->cl->insert_sorted(list, array, n); |
534 * But it is strongly recommended to use this function only on sorted lists, |
| 547 } |
535 * because otherwise it will fall back to an inefficient algorithm which inserts |
| |
536 * all elements one by one. |
| |
537 * If the @p list is not sorted, the @p array also does not need to be sorted. |
| |
538 * But when the @p list is sorted, the @p array must also be sorted. |
| |
539 * |
| |
540 * This method is usually more efficient than inserting each element separately |
| |
541 * because consecutive chunks of sorted data are inserted in one pass. |
| |
542 * |
| |
543 * If there is not enough memory to add all elements, the returned value is |
| |
544 * less than @p n. |
| |
545 * |
| |
546 * @note The return value of this function denotes the number of elements |
| |
547 * from the @p sorted_data that are definitely contained in the list after |
| |
548 * completing the call. It is @em not the number of elements that were newly |
| |
549 * inserted. That means, when no error occurred, the return value should |
| |
550 * be @p n. |
| |
551 * |
| |
552 * If this list is storing pointers instead of objects @p array is expected to |
| |
553 * be an array of pointers. |
| |
554 * |
| |
555 * @param list the list |
| |
556 * @param array a pointer to the elements to add |
| |
557 * @param n the number of elements to add |
| |
558 * @return the number of added elements |
| |
559 * |
| |
560 * @return the number of elements from the @p sorted_data that are definitely present in the list after this call |
| |
561 */ |
| |
562 cx_attr_nonnull |
| |
563 CX_EXPORT size_t cxListInsertUniqueArray(CxList *list, const void *array, size_t n); |
| 548 |
564 |
| 549 /** |
565 /** |
| 550 * Inserts an element after the current location of the specified iterator. |
566 * Inserts an element after the current location of the specified iterator. |
| 551 * |
567 * |
| 552 * The used iterator remains operational, but all other active iterators should |
568 * The used iterator remains operational, but all other active iterators should |
| 815 * @param list the list |
768 * @param list the list |
| 816 * @param index the index of the element |
769 * @param index the index of the element |
| 817 * @return a pointer to the element or @c NULL if the index is out of bounds |
770 * @return a pointer to the element or @c NULL if the index is out of bounds |
| 818 */ |
771 */ |
| 819 cx_attr_nonnull |
772 cx_attr_nonnull |
| 820 static inline void *cxListAt( |
773 CX_EXPORT void *cxListAt(const CxList *list, size_t index); |
| 821 const CxList *list, |
|
| 822 size_t index |
|
| 823 ) { |
|
| 824 return list->cl->at(list, index); |
|
| 825 } |
|
| 826 |
774 |
| 827 /** |
775 /** |
| 828 * Returns a pointer to the first element. |
776 * Returns a pointer to the first element. |
| 829 * |
777 * |
| 830 * If the list is storing pointers, returns the first pointer stored in the list. |
778 * If the list is storing pointers, returns the first pointer stored in the list. |
| 831 * |
779 * |
| 832 * @param list the list |
780 * @param list the list |
| 833 * @return a pointer to the first element or @c NULL if the list is empty |
781 * @return a pointer to the first element or @c NULL if the list is empty |
| 834 */ |
782 */ |
| 835 cx_attr_nonnull |
783 cx_attr_nonnull |
| 836 static inline void *cxListFirst(const CxList *list) { |
784 CX_EXPORT void *cxListFirst(const CxList *list); |
| 837 return list->cl->at(list, 0); |
|
| 838 } |
|
| 839 |
785 |
| 840 /** |
786 /** |
| 841 * Returns a pointer to the last element. |
787 * Returns a pointer to the last element. |
| 842 * |
788 * |
| 843 * If the list is storing pointers, returns the last pointer stored in the list. |
789 * If the list is storing pointers, returns the last pointer stored in the list. |
| 844 * |
790 * |
| 845 * @param list the list |
791 * @param list the list |
| 846 * @return a pointer to the last element or @c NULL if the list is empty |
792 * @return a pointer to the last element or @c NULL if the list is empty |
| 847 */ |
793 */ |
| 848 cx_attr_nonnull |
794 cx_attr_nonnull |
| 849 static inline void *cxListLast(const CxList *list) { |
795 CX_EXPORT void *cxListLast(const CxList *list); |
| 850 return list->cl->at(list, list->collection.size - 1); |
796 |
| 851 } |
797 /** |
| 852 |
798 * Sets the element at the specified index in the list. |
| 853 /** |
799 * |
| 854 * Sets the element at the specified index in the list |
800 * This overwrites the element in-place without calling any destructor |
| |
801 * on the overwritten element. |
| 855 * |
802 * |
| 856 * @param list the list to set the element in |
803 * @param list the list to set the element in |
| 857 * @param index the index to set the element at |
804 * @param index the index to set the element at |
| 858 * @param elem element to set |
805 * @param elem element to set |
| 859 * @retval zero on success |
806 * @retval zero on success |
| 860 * @retval non-zero when index is out of bounds |
807 * @retval non-zero when index is out of bounds |
| 861 */ |
808 */ |
| 862 cx_attr_nonnull |
809 cx_attr_nonnull |
| 863 cx_attr_export |
810 CX_EXPORT int cxListSet(CxList *list, size_t index, const void *elem); |
| 864 int cxListSet( |
|
| 865 CxList *list, |
|
| 866 size_t index, |
|
| 867 const void *elem |
|
| 868 ); |
|
| 869 |
811 |
| 870 /** |
812 /** |
| 871 * Returns an iterator pointing to the item at the specified index. |
813 * Returns an iterator pointing to the item at the specified index. |
| 872 * |
814 * |
| 873 * The returned iterator is position-aware. |
815 * The returned iterator is position-aware. |
| 874 * |
816 * |
| 875 * If the index is out of range, a past-the-end iterator will be returned. |
817 * If the index is out of range or @p list is @c NULL, a past-the-end iterator will be returned. |
| 876 * |
818 * |
| 877 * @param list the list |
819 * @param list the list |
| 878 * @param index the index where the iterator shall point at |
820 * @param index the index where the iterator shall point at |
| 879 * @return a new iterator |
821 * @return a new iterator |
| 880 */ |
822 */ |
| 881 cx_attr_nonnull |
|
| 882 cx_attr_nodiscard |
823 cx_attr_nodiscard |
| 883 static inline CxIterator cxListIteratorAt( |
824 CX_EXPORT CxIterator cxListIteratorAt(const CxList *list, size_t index); |
| 884 const CxList *list, |
|
| 885 size_t index |
|
| 886 ) { |
|
| 887 return list->cl->iterator(list, index, false); |
|
| 888 } |
|
| 889 |
825 |
| 890 /** |
826 /** |
| 891 * Returns a backwards iterator pointing to the item at the specified index. |
827 * Returns a backwards iterator pointing to the item at the specified index. |
| 892 * |
828 * |
| 893 * The returned iterator is position-aware. |
829 * The returned iterator is position-aware. |
| 894 * |
830 * |
| 895 * If the index is out of range, a past-the-end iterator will be returned. |
831 * If the index is out of range or @p list is @c NULL, a past-the-end iterator will be returned. |
| 896 * |
832 * |
| 897 * @param list the list |
833 * @param list the list |
| 898 * @param index the index where the iterator shall point at |
834 * @param index the index where the iterator shall point at |
| 899 * @return a new iterator |
835 * @return a new iterator |
| 900 */ |
836 */ |
| 901 cx_attr_nonnull |
|
| 902 cx_attr_nodiscard |
837 cx_attr_nodiscard |
| 903 static inline CxIterator cxListBackwardsIteratorAt( |
838 CX_EXPORT CxIterator cxListBackwardsIteratorAt(const CxList *list, size_t index); |
| 904 const CxList *list, |
839 |
| 905 size_t index |
840 /** |
| 906 ) { |
841 * Returns an iterator pointing to the first item of the list. |
| 907 return list->cl->iterator(list, index, true); |
|
| 908 } |
|
| 909 |
|
| 910 /** |
|
| 911 * Returns a mutating iterator pointing to the item at the specified index. |
|
| 912 * |
842 * |
| 913 * The returned iterator is position-aware. |
843 * The returned iterator is position-aware. |
| 914 * |
844 * |
| 915 * If the index is out of range, a past-the-end iterator will be returned. |
845 * If the list is empty or @c NULL, a past-the-end iterator will be returned. |
| 916 * |
846 * |
| 917 * @param list the list |
847 * @param list the list |
| 918 * @param index the index where the iterator shall point at |
|
| 919 * @return a new iterator |
848 * @return a new iterator |
| 920 */ |
849 */ |
| 921 cx_attr_nonnull |
|
| 922 cx_attr_nodiscard |
850 cx_attr_nodiscard |
| 923 cx_attr_export |
851 CX_EXPORT CxIterator cxListIterator(const CxList *list); |
| 924 CxIterator cxListMutIteratorAt( |
852 |
| 925 CxList *list, |
853 /** |
| 926 size_t index |
854 * Returns a backwards iterator pointing to the last item of the list. |
| 927 ); |
|
| 928 |
|
| 929 /** |
|
| 930 * Returns a mutating backwards iterator pointing to the item at the |
|
| 931 * specified index. |
|
| 932 * |
855 * |
| 933 * The returned iterator is position-aware. |
856 * The returned iterator is position-aware. |
| 934 * |
857 * |
| 935 * If the index is out of range, a past-the-end iterator will be returned. |
858 * If the list is empty or @c NULL, a past-the-end iterator will be returned. |
| 936 * |
859 * |
| 937 * @param list the list |
860 * @param list the list |
| 938 * @param index the index where the iterator shall point at |
|
| 939 * @return a new iterator |
861 * @return a new iterator |
| 940 */ |
862 */ |
| 941 cx_attr_nonnull |
|
| 942 cx_attr_nodiscard |
863 cx_attr_nodiscard |
| 943 cx_attr_export |
864 CX_EXPORT CxIterator cxListBackwardsIterator(const CxList *list); |
| 944 CxIterator cxListMutBackwardsIteratorAt( |
|
| 945 CxList *list, |
|
| 946 size_t index |
|
| 947 ); |
|
| 948 |
|
| 949 /** |
|
| 950 * Returns an iterator pointing to the first item of the list. |
|
| 951 * |
|
| 952 * The returned iterator is position-aware. |
|
| 953 * |
|
| 954 * If the list is empty or @c NULL, a past-the-end iterator will be returned. |
|
| 955 * |
|
| 956 * @param list the list |
|
| 957 * @return a new iterator |
|
| 958 */ |
|
| 959 cx_attr_nodiscard |
|
| 960 static inline CxIterator cxListIterator(const CxList *list) { |
|
| 961 if (list == NULL) list = cxEmptyList; |
|
| 962 return list->cl->iterator(list, 0, false); |
|
| 963 } |
|
| 964 |
|
| 965 /** |
|
| 966 * Returns a mutating iterator pointing to the first item of the list. |
|
| 967 * |
|
| 968 * The returned iterator is position-aware. |
|
| 969 * |
|
| 970 * If the list is empty or @c NULL, a past-the-end iterator will be returned. |
|
| 971 * |
|
| 972 * @param list the list |
|
| 973 * @return a new iterator |
|
| 974 */ |
|
| 975 cx_attr_nodiscard |
|
| 976 static inline CxIterator cxListMutIterator(CxList *list) { |
|
| 977 if (list == NULL) list = cxEmptyList; |
|
| 978 return cxListMutIteratorAt(list, 0); |
|
| 979 } |
|
| 980 |
|
| 981 |
|
| 982 /** |
|
| 983 * Returns a backwards iterator pointing to the last item of the list. |
|
| 984 * |
|
| 985 * The returned iterator is position-aware. |
|
| 986 * |
|
| 987 * If the list is empty or @c NULL, a past-the-end iterator will be returned. |
|
| 988 * |
|
| 989 * @param list the list |
|
| 990 * @return a new iterator |
|
| 991 */ |
|
| 992 cx_attr_nodiscard |
|
| 993 static inline CxIterator cxListBackwardsIterator(const CxList *list) { |
|
| 994 if (list == NULL) list = cxEmptyList; |
|
| 995 return list->cl->iterator(list, list->collection.size - 1, true); |
|
| 996 } |
|
| 997 |
|
| 998 /** |
|
| 999 * Returns a mutating backwards iterator pointing to the last item of the list. |
|
| 1000 * |
|
| 1001 * The returned iterator is position-aware. |
|
| 1002 * |
|
| 1003 * If the list is empty or @c NULL, a past-the-end iterator will be returned. |
|
| 1004 * |
|
| 1005 * @param list the list |
|
| 1006 * @return a new iterator |
|
| 1007 */ |
|
| 1008 cx_attr_nodiscard |
|
| 1009 static inline CxIterator cxListMutBackwardsIterator(CxList *list) { |
|
| 1010 if (list == NULL) list = cxEmptyList; |
|
| 1011 return cxListMutBackwardsIteratorAt(list, list->collection.size - 1); |
|
| 1012 } |
|
| 1013 |
865 |
| 1014 /** |
866 /** |
| 1015 * Returns the index of the first element that equals @p elem. |
867 * Returns the index of the first element that equals @p elem. |
| 1016 * |
868 * |
| 1017 * Determining equality is performed by the list's comparator function. |
869 * Determining equality is performed by the list's comparator function. |
| 1020 * @param elem the element to find |
872 * @param elem the element to find |
| 1021 * @return the index of the element or the size of the list when the element is not found |
873 * @return the index of the element or the size of the list when the element is not found |
| 1022 * @see cxListIndexValid() |
874 * @see cxListIndexValid() |
| 1023 * @see cxListContains() |
875 * @see cxListContains() |
| 1024 */ |
876 */ |
| 1025 cx_attr_nonnull |
877 cx_attr_nonnull cx_attr_nodiscard |
| 1026 cx_attr_nodiscard |
878 CX_EXPORT size_t cxListFind(const CxList *list, const void *elem); |
| 1027 static inline size_t cxListFind( |
879 |
| 1028 const CxList *list, |
880 /** |
| 1029 const void *elem |
881 * Checks if the list contains the specified element. |
| 1030 ) { |
|
| 1031 return list->cl->find_remove((CxList*)list, elem, false); |
|
| 1032 } |
|
| 1033 |
|
| 1034 /** |
|
| 1035 * Checks, if the list contains the specified element. |
|
| 1036 * |
882 * |
| 1037 * The elements are compared with the list's comparator function. |
883 * The elements are compared with the list's comparator function. |
| 1038 * |
884 * |
| 1039 * @param list the list |
885 * @param list the list |
| 1040 * @param elem the element to find |
886 * @param elem the element to find |
| 1041 * @retval true if the element is contained |
887 * @retval true if the element is contained |
| 1042 * @retval false if the element is not contained |
888 * @retval false if the element is not contained |
| 1043 * @see cxListFind() |
889 * @see cxListFind() |
| 1044 */ |
890 */ |
| 1045 cx_attr_nonnull |
891 cx_attr_nonnull cx_attr_nodiscard |
| 1046 cx_attr_nodiscard |
892 CX_EXPORT bool cxListContains(const CxList* list, const void* elem); |
| 1047 static inline bool cxListContains( |
|
| 1048 const CxList* list, |
|
| 1049 const void* elem |
|
| 1050 ) { |
|
| 1051 return list->cl->find_remove((CxList*)list, elem, false) < list->collection.size; |
|
| 1052 } |
|
| 1053 |
893 |
| 1054 /** |
894 /** |
| 1055 * Checks if the specified index is within bounds. |
895 * Checks if the specified index is within bounds. |
| 1056 * |
896 * |
| 1057 * @param list the list |
897 * @param list the list |
| 1058 * @param index the index |
898 * @param index the index |
| 1059 * @retval true if the index is within bounds |
899 * @retval true if the index is within bounds |
| 1060 * @retval false if the index is out of bounds |
900 * @retval false if the index is out of bounds |
| 1061 */ |
901 */ |
| 1062 cx_attr_nonnull |
902 cx_attr_nonnull cx_attr_nodiscard |
| 1063 cx_attr_nodiscard |
903 CX_EXPORT bool cxListIndexValid(const CxList *list, size_t index); |
| 1064 static inline bool cxListIndexValid(const CxList *list, size_t index) { |
|
| 1065 return index < list->collection.size; |
|
| 1066 } |
|
| 1067 |
904 |
| 1068 /** |
905 /** |
| 1069 * Removes and returns the index of the first element that equals @p elem. |
906 * Removes and returns the index of the first element that equals @p elem. |
| 1070 * |
907 * |
| 1071 * Determining equality is performed by the list's comparator function. |
908 * Determining equality is performed by the list's comparator function. |
| 1075 * @return the index of the now removed element or the list size |
912 * @return the index of the now removed element or the list size |
| 1076 * when the element is not found or could not be removed |
913 * when the element is not found or could not be removed |
| 1077 * @see cxListIndexValid() |
914 * @see cxListIndexValid() |
| 1078 */ |
915 */ |
| 1079 cx_attr_nonnull |
916 cx_attr_nonnull |
| 1080 static inline size_t cxListFindRemove( |
917 CX_EXPORT size_t cxListFindRemove(CxList *list, const void *elem); |
| 1081 CxList *list, |
|
| 1082 const void *elem |
|
| 1083 ) { |
|
| 1084 return list->cl->find_remove(list, elem, true); |
|
| 1085 } |
|
| 1086 |
918 |
| 1087 /** |
919 /** |
| 1088 * Sorts the list. |
920 * Sorts the list. |
| 1089 * |
921 * |
| 1090 * @remark The underlying sort algorithm is implementation defined. |
922 * @remark The underlying sort algorithm is implementation defined. |
| 1091 * |
923 * |
| 1092 * @param list the list |
924 * @param list the list |
| 1093 */ |
925 */ |
| 1094 cx_attr_nonnull |
926 cx_attr_nonnull |
| 1095 static inline void cxListSort(CxList *list) { |
927 CX_EXPORT void cxListSort(CxList *list); |
| 1096 if (list->collection.sorted) return; |
|
| 1097 list->cl->sort(list); |
|
| 1098 list->collection.sorted = true; |
|
| 1099 } |
|
| 1100 |
928 |
| 1101 /** |
929 /** |
| 1102 * Reverses the order of the items. |
930 * Reverses the order of the items. |
| 1103 * |
931 * |
| 1104 * @param list the list |
932 * @param list the list |
| 1105 */ |
933 */ |
| 1106 cx_attr_nonnull |
934 cx_attr_nonnull |
| 1107 static inline void cxListReverse(CxList *list) { |
935 CX_EXPORT void cxListReverse(CxList *list); |
| 1108 // still sorted, but not according to the cmp_func |
|
| 1109 list->collection.sorted = false; |
|
| 1110 list->cl->reverse(list); |
|
| 1111 } |
|
| 1112 |
936 |
| 1113 /** |
937 /** |
| 1114 * Compares a list to another list of the same type. |
938 * Compares a list to another list of the same type. |
| 1115 * |
939 * |
| 1116 * First, the list sizes are compared. |
940 * First, the list sizes are compared. |
| 1117 * If they match, the lists are compared element-wise. |
941 * If they match, the lists are compared element-wise. |
| 1118 * |
942 * |
| 1119 * @param list the list |
943 * @param list the list |
| 1120 * @param other the list to compare to |
944 * @param other the list to compare to |
| 1121 * @retval zero both lists are equal element wise |
945 * @retval zero both lists are equal element wise |
| 1122 * @retval negative the first list is smaller |
946 * @retval negative the first list is smaller, |
| 1123 * or the first non-equal element in the first list is smaller |
947 * or the first non-equal element in the first list is smaller |
| 1124 * @retval positive the first list is larger |
948 * @retval positive the first list is larger |
| 1125 * or the first non-equal element in the first list is larger |
949 * or the first non-equal element in the first list is larger |
| 1126 */ |
950 */ |
| 1127 cx_attr_nonnull |
951 cx_attr_nonnull cx_attr_nodiscard |
| 1128 cx_attr_nodiscard |
952 CX_EXPORT int cxListCompare(const CxList *list, const CxList *other); |
| 1129 cx_attr_export |
|
| 1130 int cxListCompare( |
|
| 1131 const CxList *list, |
|
| 1132 const CxList *other |
|
| 1133 ); |
|
| 1134 |
953 |
| 1135 /** |
954 /** |
| 1136 * Deallocates the memory of the specified list structure. |
955 * Deallocates the memory of the specified list structure. |
| 1137 * |
956 * |
| 1138 * Also calls the content destructor functions for each element, if specified. |
957 * Also calls the content destructor functions for each element, if specified. |
| 1139 * |
958 * |
| 1140 * @param list the list which shall be freed |
959 * @param list the list that shall be freed |
| 1141 */ |
960 */ |
| 1142 cx_attr_export |
961 CX_EXPORT void cxListFree(CxList *list); |
| 1143 void cxListFree(CxList *list); |
962 |
| 1144 |
963 |
| |
964 /** |
| |
965 * Performs a deep clone of one list into another. |
| |
966 * |
| |
967 * If the destination list already contains elements, the cloned elements |
| |
968 * are appended to that list. |
| |
969 * |
| |
970 * @attention If the cloned elements need to be destroyed by a destructor |
| |
971 * function, you must make sure that the destination list also uses this |
| |
972 * destructor function. |
| |
973 * |
| |
974 * @param dst the destination list |
| |
975 * @param src the source list |
| |
976 * @param clone_func the clone function for the elements |
| |
977 * @param clone_allocator the allocator that is passed to the clone function |
| |
978 * @param data optional additional data that is passed to the clone function |
| |
979 * @retval zero when all elements were successfully cloned |
| |
980 * @retval non-zero when an allocation error occurred |
| |
981 * @see cxListCloneSimple() |
| |
982 */ |
| |
983 cx_attr_nonnull_arg(1, 2, 3) |
| |
984 CX_EXPORT int cxListClone(CxList *dst, const CxList *src, |
| |
985 cx_clone_func clone_func, const CxAllocator *clone_allocator, void *data); |
| |
986 |
| |
987 /** |
| |
988 * Clones elements from a list only if they are not present in another list. |
| |
989 * |
| |
990 * If the @p minuend does not contain duplicates, this is equivalent to adding |
| |
991 * the set difference to the destination list. |
| |
992 * |
| |
993 * This function is optimized for the case when both the @p minuend and the |
| |
994 * @p subtrahend are sorted. |
| |
995 * |
| |
996 * @param dst the destination list |
| |
997 * @param minuend the list to subtract elements from |
| |
998 * @param subtrahend the elements that shall be subtracted |
| |
999 * @param clone_func the clone function for the elements |
| |
1000 * @param clone_allocator the allocator that is passed to the clone function |
| |
1001 * @param data optional additional data that is passed to the clone function |
| |
1002 * @retval zero when the elements were successfully cloned |
| |
1003 * @retval non-zero when an allocation error occurred |
| |
1004 * @see cxListDifferenceSimple() |
| |
1005 */ |
| |
1006 cx_attr_nonnull_arg(1, 2, 3, 4) |
| |
1007 CX_EXPORT int cxListDifference(CxList *dst, |
| |
1008 const CxList *minuend, const CxList *subtrahend, |
| |
1009 cx_clone_func clone_func, const CxAllocator *clone_allocator, void *data); |
| |
1010 |
| |
1011 /** |
| |
1012 * Clones elements from a list only if they are also present in another list. |
| |
1013 * |
| |
1014 * This function is optimized for the case when both the @p src and the |
| |
1015 * @p other list are sorted. |
| |
1016 * |
| |
1017 * If the destination list already contains elements, the intersection is appended |
| |
1018 * to that list. |
| |
1019 * |
| |
1020 * @param dst the destination list |
| |
1021 * @param src the list to clone the elements from |
| |
1022 * @param other the list to check the elements for existence |
| |
1023 * @param clone_func the clone function for the elements |
| |
1024 * @param clone_allocator the allocator that is passed to the clone function |
| |
1025 * @param data optional additional data that is passed to the clone function |
| |
1026 * @retval zero when the elements were successfully cloned |
| |
1027 * @retval non-zero when an allocation error occurred |
| |
1028 * @see cxListIntersectionSimple() |
| |
1029 */ |
| |
1030 cx_attr_nonnull_arg(1, 2, 3, 4) |
| |
1031 CX_EXPORT int cxListIntersection(CxList *dst, const CxList *src, const CxList *other, |
| |
1032 cx_clone_func clone_func, const CxAllocator *clone_allocator, void *data); |
| |
1033 |
| |
1034 /** |
| |
1035 * Performs a deep clone of one list into another, skipping duplicates. |
| |
1036 * |
| |
1037 * This function is optimized for the case when both the @p src and the |
| |
1038 * @p other list are sorted. |
| |
1039 * In that case, the union will also be sorted. |
| |
1040 * |
| |
1041 * If the destination list already contains elements, the union is appended |
| |
1042 * to that list. In that case the destination is not necessarily sorted. |
| |
1043 * |
| |
1044 * @param dst the destination list |
| |
1045 * @param src the primary source list |
| |
1046 * @param other the other list, where elements are only cloned from |
| |
1047 * when they are not in @p src |
| |
1048 * @param clone_func the clone function for the elements |
| |
1049 * @param clone_allocator the allocator that is passed to the clone function |
| |
1050 * @param data optional additional data that is passed to the clone function |
| |
1051 * @retval zero when the elements were successfully cloned |
| |
1052 * @retval non-zero when an allocation error occurred |
| |
1053 * @see cxListUnionSimple() |
| |
1054 */ |
| |
1055 cx_attr_nonnull_arg(1, 2, 3, 4) |
| |
1056 CX_EXPORT int cxListUnion(CxList *dst, const CxList *src, const CxList *other, |
| |
1057 cx_clone_func clone_func, const CxAllocator *clone_allocator, void *data); |
| |
1058 |
| |
1059 /** |
| |
1060 * Performs a shallow clone of one list into another. |
| |
1061 * |
| |
1062 * This function uses the default allocator, if needed, and performs |
| |
1063 * shallow clones with @c memcpy(). |
| |
1064 * |
| |
1065 * If the destination list already contains elements, the cloned elements |
| |
1066 * are appended to that list. |
| |
1067 * |
| |
1068 * @attention If the cloned elements need to be destroyed by a destructor |
| |
1069 * function, you must make sure that the destination list also uses this |
| |
1070 * destructor function. |
| |
1071 * |
| |
1072 * @param dst the destination list |
| |
1073 * @param src the source list |
| |
1074 * @retval zero when all elements were successfully cloned |
| |
1075 * @retval non-zero when an allocation error occurred |
| |
1076 * @see cxListClone() |
| |
1077 */ |
| |
1078 cx_attr_nonnull |
| |
1079 CX_EXPORT int cxListCloneSimple(CxList *dst, const CxList *src); |
| |
1080 |
| |
1081 /** |
| |
1082 * Clones elements from a list only if they are not present in another list. |
| |
1083 * |
| |
1084 * This function uses the default allocator, if needed, and performs |
| |
1085 * shallow clones with @c memcpy(). |
| |
1086 * |
| |
1087 * If the @p minuend does not contain duplicates, this is equivalent to adding |
| |
1088 * the set difference to the destination list. |
| |
1089 * |
| |
1090 * This function is optimized for the case when both the @p minuend and the |
| |
1091 * @p subtrahend are sorted. |
| |
1092 * |
| |
1093 * @param dst the destination list |
| |
1094 * @param minuend the list to subtract elements from |
| |
1095 * @param subtrahend the elements that shall be subtracted |
| |
1096 * @retval zero when the elements were successfully cloned |
| |
1097 * @retval non-zero when an allocation error occurred |
| |
1098 * @see cxListDifference() |
| |
1099 */ |
| |
1100 cx_attr_nonnull |
| |
1101 CX_EXPORT int cxListDifferenceSimple(CxList *dst, |
| |
1102 const CxList *minuend, const CxList *subtrahend); |
| |
1103 |
| |
1104 /** |
| |
1105 * Clones elements from a list only if they are also present in another list. |
| |
1106 * |
| |
1107 * This function uses the default allocator, if needed, and performs |
| |
1108 * shallow clones with @c memcpy(). |
| |
1109 * |
| |
1110 * This function is optimized for the case when both the @p src and the |
| |
1111 * @p other list are sorted. |
| |
1112 * |
| |
1113 * If the destination list already contains elements, the intersection is appended |
| |
1114 * to that list. |
| |
1115 * |
| |
1116 * @param dst the destination list |
| |
1117 * @param src the list to clone the elements from |
| |
1118 * @param other the list to check the elements for existence |
| |
1119 * @retval zero when the elements were successfully cloned |
| |
1120 * @retval non-zero when an allocation error occurred |
| |
1121 * @see cxListIntersection() |
| |
1122 */ |
| |
1123 cx_attr_nonnull |
| |
1124 CX_EXPORT int cxListIntersectionSimple(CxList *dst, const CxList *src, const CxList *other); |
| |
1125 |
| |
1126 /** |
| |
1127 * Performs a deep clone of one list into another, skipping duplicates. |
| |
1128 * |
| |
1129 * This function uses the default allocator, if needed, and performs |
| |
1130 * shallow clones with @c memcpy(). |
| |
1131 * |
| |
1132 * This function is optimized for the case when both the @p src and the |
| |
1133 * @p other list are sorted. |
| |
1134 * In that case, the union will also be sorted. |
| |
1135 * |
| |
1136 * If the destination list already contains elements, the union is appended |
| |
1137 * to that list. In that case the destination is not necessarily sorted. |
| |
1138 * |
| |
1139 * @param dst the destination list |
| |
1140 * @param src the primary source list |
| |
1141 * @param other the other list, where elements are only cloned from |
| |
1142 * when they are not in @p src |
| |
1143 * @retval zero when the elements were successfully cloned |
| |
1144 * @retval non-zero when an allocation error occurred |
| |
1145 * @see cxListUnion() |
| |
1146 */ |
| |
1147 cx_attr_nonnull |
| |
1148 CX_EXPORT int cxListUnionSimple(CxList *dst, const CxList *src, const CxList *other); |
| 1145 |
1149 |
| 1146 #ifdef __cplusplus |
1150 #ifdef __cplusplus |
| 1147 } // extern "C" |
1151 } // extern "C" |
| 1148 #endif |
1152 #endif |
| 1149 |
1153 |