| 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 |
351 * @retval non-zero memory allocation failure |
| 374 * @see cxListAddArray() |
352 * @see cxListAddArray() |
| 375 * @see cxListEmplace() |
353 * @see cxListEmplace() |
| 376 */ |
354 */ |
| 377 cx_attr_nonnull |
355 cx_attr_nonnull |
| 378 static inline int cxListAdd( |
356 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 |
357 |
| 386 /** |
358 /** |
| 387 * Adds multiple items to the end of the list. |
359 * Adds multiple items to the end of the list. |
| 388 * |
360 * |
| 389 * This method is more efficient than invoking cxListAdd() multiple times. |
361 * This method is more efficient than invoking cxListAdd() multiple times. |
| 390 * |
362 * |
| 391 * If there is not enough memory to add all elements, the returned value is |
363 * If there is not enough memory to add all elements, the returned value is |
| 392 * less than @p n. |
364 * less than @p n. |
| 393 * |
365 * |
| 394 * If this list is storing pointers instead of objects @p array is expected to |
366 * If this list is storing pointers instead of objects, @p array is expected to |
| 395 * be an array of pointers. |
367 * be an array of pointers. |
| 396 * |
368 * |
| 397 * @param list the list |
369 * @param list the list |
| 398 * @param array a pointer to the elements to add |
370 * @param array a pointer to the elements to add |
| 399 * @param n the number of elements to add |
371 * @param n the number of elements to add |
| 400 * @return the number of added elements |
372 * @return the number of added elements |
| 401 */ |
373 * @see cxListEmplaceArray() |
| 402 cx_attr_nonnull |
374 */ |
| 403 static inline size_t cxListAddArray( |
375 cx_attr_nonnull |
| 404 CxList *list, |
376 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 |
377 |
| 412 /** |
378 /** |
| 413 * Inserts an item at the specified index. |
379 * Inserts an item at the specified index. |
| 414 * |
380 * |
| 415 * If @p index equals the list @c size, this is effectively cxListAdd(). |
381 * If the @p index equals the list @c size, this is effectively cxListAdd(). |
| 416 * |
382 * |
| 417 * @param list the list |
383 * @param list the list |
| 418 * @param index the index the element shall have |
384 * @param index the index the element shall have |
| 419 * @param elem a pointer to the element to add |
385 * @param elem a pointer to the element to add |
| 420 * @retval zero success |
386 * @retval zero success |
| 476 * @param elem a pointer to the element to add |
468 * @param elem a pointer to the element to add |
| 477 * @retval zero success |
469 * @retval zero success |
| 478 * @retval non-zero memory allocation failure |
470 * @retval non-zero memory allocation failure |
| 479 */ |
471 */ |
| 480 cx_attr_nonnull |
472 cx_attr_nonnull |
| 481 static inline int cxListInsertSorted( |
473 CX_EXPORT int cxListInsertSorted(CxList *list, const void *elem); |
| 482 CxList *list, |
474 |
| 483 const void *elem |
475 /** |
| 484 ) { |
476 * Inserts an item into a list if it does not exist. |
| 485 list->collection.sorted = true; // guaranteed by definition |
477 * |
| 486 const void *data = list->collection.store_pointer ? &elem : elem; |
478 * If the list is not sorted already, this function will check all elements |
| 487 return list->cl->insert_sorted(list, data, 1) == 0; |
479 * and append the new element when it was not found. |
| 488 } |
480 * It is strongly recommended to use this function only on sorted lists, where |
| |
481 * the element, if it is not contained, is inserted at the correct position. |
| |
482 * |
| |
483 * @param list the list |
| |
484 * @param elem a pointer to the element to add |
| |
485 * @retval zero success (also when the element was already in the list) |
| |
486 * @retval non-zero memory allocation failure |
| |
487 */ |
| |
488 cx_attr_nonnull |
| |
489 CX_EXPORT int cxListInsertUnique(CxList *list, const void *elem); |
| 489 |
490 |
| 490 /** |
491 /** |
| 491 * Inserts multiple items to the list at the specified index. |
492 * Inserts multiple items to the list at the specified index. |
| 492 * If @p index equals the list size, this is effectively cxListAddArray(). |
493 * If the @p index equals the list size, this is effectively cxListAddArray(). |
| 493 * |
494 * |
| 494 * This method is usually more efficient than invoking cxListInsert() |
495 * This method is usually more efficient than invoking cxListInsert() |
| 495 * multiple times. |
496 * multiple times. |
| 496 * |
497 * |
| 497 * If there is not enough memory to add all elements, the returned value is |
498 * If there is not enough memory to add all elements, the returned value is |
| 498 * less than @p n. |
499 * less than @p n. |
| 499 * |
500 * |
| 500 * If this list is storing pointers instead of objects @p array is expected to |
501 * If this list is storing pointers instead of objects, @p array is expected to |
| 501 * be an array of pointers. |
502 * be an array of pointers. |
| 502 * |
503 * |
| 503 * @param list the list |
504 * @param list the list |
| 504 * @param index the index where to add the elements |
505 * @param index the index where to add the elements |
| 505 * @param array a pointer to the elements to add |
506 * @param array a pointer to the elements to add |
| 506 * @param n the number of elements to add |
507 * @param n the number of elements to add |
| 507 * @return the number of added elements |
508 * @return the number of added elements |
| 508 */ |
509 * @see cxListEmplaceArrayAt() |
| 509 cx_attr_nonnull |
510 */ |
| 510 static inline size_t cxListInsertArray( |
511 cx_attr_nonnull |
| 511 CxList *list, |
512 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 |
513 |
| 520 /** |
514 /** |
| 521 * Inserts a sorted array into a sorted list. |
515 * Inserts a sorted array into a sorted list. |
| 522 * |
516 * |
| 523 * This method is usually more efficient than inserting each element separately, |
517 * This method is usually more efficient than inserting each element separately |
| 524 * because consecutive chunks of sorted data are inserted in one pass. |
518 * because consecutive chunks of sorted data are inserted in one pass. |
| 525 * |
519 * |
| 526 * If there is not enough memory to add all elements, the returned value is |
520 * If there is not enough memory to add all elements, the returned value is |
| 527 * less than @p n. |
521 * less than @p n. |
| 528 * |
522 * |
| 529 * If this list is storing pointers instead of objects @p array is expected to |
523 * If this list is storing pointers instead of objects, @p array is expected to |
| 530 * be an array of pointers. |
524 * be an array of pointers. |
| 531 * |
525 * |
| 532 * If the list is not sorted already, the behavior is undefined. |
526 * If the list is not sorted already, the behavior is undefined. |
| 533 * |
527 * |
| 534 * @param list the list |
528 * @param list the list |
| 535 * @param array a pointer to the elements to add |
529 * @param array a pointer to the elements to add |
| 536 * @param n the number of elements to add |
530 * @param n the number of elements to add |
| 537 * @return the number of added elements |
531 * @return the number of added elements |
| 538 */ |
532 */ |
| 539 cx_attr_nonnull |
533 cx_attr_nonnull |
| 540 static inline size_t cxListInsertSortedArray( |
534 CX_EXPORT size_t cxListInsertSortedArray(CxList *list, const void *array, size_t n); |
| 541 CxList *list, |
535 |
| 542 const void *array, |
536 /** |
| 543 size_t n |
537 * Inserts an array into a list, skipping duplicates. |
| 544 ) { |
538 * |
| 545 list->collection.sorted = true; // guaranteed by definition |
539 * The @p list does not need to be sorted (in contrast to cxListInsertSortedArray()). |
| 546 return list->cl->insert_sorted(list, array, n); |
540 * But it is strongly recommended to use this function only on sorted lists, |
| 547 } |
541 * because otherwise it will fall back to an inefficient algorithm which inserts |
| |
542 * all elements one by one. |
| |
543 * If the @p list is not sorted, the @p array also does not need to be sorted. |
| |
544 * But when the @p list is sorted, the @p array must also be sorted. |
| |
545 * |
| |
546 * This method is usually more efficient than inserting each element separately |
| |
547 * because consecutive chunks of sorted data are inserted in one pass. |
| |
548 * |
| |
549 * If there is not enough memory to add all elements, the returned value is |
| |
550 * less than @p n. |
| |
551 * |
| |
552 * @note The return value of this function denotes the number of elements |
| |
553 * from the @p sorted_data that are definitely contained in the list after |
| |
554 * completing the call. It is @em not the number of elements that were newly |
| |
555 * inserted. That means, when no error occurred, the return value should |
| |
556 * be @p n. |
| |
557 * |
| |
558 * If this list is storing pointers instead of objects @p array is expected to |
| |
559 * be an array of pointers. |
| |
560 * |
| |
561 * @param list the list |
| |
562 * @param array a pointer to the elements to add |
| |
563 * @param n the number of elements to add |
| |
564 * @return the number of added elements |
| |
565 * |
| |
566 * @return the number of elements from the @p sorted_data that are definitely present in the list after this call |
| |
567 */ |
| |
568 cx_attr_nonnull |
| |
569 CX_EXPORT size_t cxListInsertUniqueArray(CxList *list, const void *array, size_t n); |
| 548 |
570 |
| 549 /** |
571 /** |
| 550 * Inserts an element after the current location of the specified iterator. |
572 * Inserts an element after the current location of the specified iterator. |
| 551 * |
573 * |
| 552 * The used iterator remains operational, but all other active iterators should |
574 * The used iterator remains operational, but all other active iterators should |
| 815 * @param list the list |
774 * @param list the list |
| 816 * @param index the index of the element |
775 * @param index the index of the element |
| 817 * @return a pointer to the element or @c NULL if the index is out of bounds |
776 * @return a pointer to the element or @c NULL if the index is out of bounds |
| 818 */ |
777 */ |
| 819 cx_attr_nonnull |
778 cx_attr_nonnull |
| 820 static inline void *cxListAt( |
779 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 |
780 |
| 827 /** |
781 /** |
| 828 * Returns a pointer to the first element. |
782 * Returns a pointer to the first element. |
| 829 * |
783 * |
| 830 * If the list is storing pointers, returns the first pointer stored in the list. |
784 * If the list is storing pointers, returns the first pointer stored in the list. |
| 831 * |
785 * |
| 832 * @param list the list |
786 * @param list the list |
| 833 * @return a pointer to the first element or @c NULL if the list is empty |
787 * @return a pointer to the first element or @c NULL if the list is empty |
| 834 */ |
788 */ |
| 835 cx_attr_nonnull |
789 cx_attr_nonnull |
| 836 static inline void *cxListFirst(const CxList *list) { |
790 CX_EXPORT void *cxListFirst(const CxList *list); |
| 837 return list->cl->at(list, 0); |
|
| 838 } |
|
| 839 |
791 |
| 840 /** |
792 /** |
| 841 * Returns a pointer to the last element. |
793 * Returns a pointer to the last element. |
| 842 * |
794 * |
| 843 * If the list is storing pointers, returns the last pointer stored in the list. |
795 * If the list is storing pointers, returns the last pointer stored in the list. |
| 844 * |
796 * |
| 845 * @param list the list |
797 * @param list the list |
| 846 * @return a pointer to the last element or @c NULL if the list is empty |
798 * @return a pointer to the last element or @c NULL if the list is empty |
| 847 */ |
799 */ |
| 848 cx_attr_nonnull |
800 cx_attr_nonnull |
| 849 static inline void *cxListLast(const CxList *list) { |
801 CX_EXPORT void *cxListLast(const CxList *list); |
| 850 return list->cl->at(list, list->collection.size - 1); |
802 |
| 851 } |
803 /** |
| 852 |
804 * Sets the element at the specified index in the list. |
| 853 /** |
805 * |
| 854 * Sets the element at the specified index in the list |
806 * This overwrites the element in-place without calling any destructor |
| |
807 * on the overwritten element. |
| 855 * |
808 * |
| 856 * @param list the list to set the element in |
809 * @param list the list to set the element in |
| 857 * @param index the index to set the element at |
810 * @param index the index to set the element at |
| 858 * @param elem element to set |
811 * @param elem element to set |
| 859 * @retval zero on success |
812 * @retval zero on success |
| 860 * @retval non-zero when index is out of bounds |
813 * @retval non-zero when index is out of bounds |
| 861 */ |
814 */ |
| 862 cx_attr_nonnull |
815 cx_attr_nonnull |
| 863 cx_attr_export |
816 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 |
817 |
| 870 /** |
818 /** |
| 871 * Returns an iterator pointing to the item at the specified index. |
819 * Returns an iterator pointing to the item at the specified index. |
| 872 * |
820 * |
| 873 * The returned iterator is position-aware. |
821 * The returned iterator is position-aware. |
| 874 * |
822 * |
| 875 * If the index is out of range, a past-the-end iterator will be returned. |
823 * If the index is out of range or @p list is @c NULL, a past-the-end iterator will be returned. |
| 876 * |
824 * |
| 877 * @param list the list |
825 * @param list the list |
| 878 * @param index the index where the iterator shall point at |
826 * @param index the index where the iterator shall point at |
| 879 * @return a new iterator |
827 * @return a new iterator |
| 880 */ |
828 */ |
| 881 cx_attr_nonnull |
|
| 882 cx_attr_nodiscard |
829 cx_attr_nodiscard |
| 883 static inline CxIterator cxListIteratorAt( |
830 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 |
831 |
| 890 /** |
832 /** |
| 891 * Returns a backwards iterator pointing to the item at the specified index. |
833 * Returns a backwards iterator pointing to the item at the specified index. |
| 892 * |
834 * |
| 893 * The returned iterator is position-aware. |
835 * The returned iterator is position-aware. |
| 894 * |
836 * |
| 895 * If the index is out of range, a past-the-end iterator will be returned. |
837 * If the index is out of range or @p list is @c NULL, a past-the-end iterator will be returned. |
| 896 * |
838 * |
| 897 * @param list the list |
839 * @param list the list |
| 898 * @param index the index where the iterator shall point at |
840 * @param index the index where the iterator shall point at |
| 899 * @return a new iterator |
841 * @return a new iterator |
| 900 */ |
842 */ |
| 901 cx_attr_nonnull |
|
| 902 cx_attr_nodiscard |
843 cx_attr_nodiscard |
| 903 static inline CxIterator cxListBackwardsIteratorAt( |
844 CX_EXPORT CxIterator cxListBackwardsIteratorAt(const CxList *list, size_t index); |
| 904 const CxList *list, |
845 |
| 905 size_t index |
846 /** |
| 906 ) { |
847 * 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 * |
848 * |
| 913 * The returned iterator is position-aware. |
849 * The returned iterator is position-aware. |
| 914 * |
850 * |
| 915 * If the index is out of range, a past-the-end iterator will be returned. |
851 * If the list is empty or @c NULL, a past-the-end iterator will be returned. |
| 916 * |
852 * |
| 917 * @param list the list |
853 * @param list the list |
| 918 * @param index the index where the iterator shall point at |
|
| 919 * @return a new iterator |
854 * @return a new iterator |
| 920 */ |
855 */ |
| 921 cx_attr_nonnull |
|
| 922 cx_attr_nodiscard |
856 cx_attr_nodiscard |
| 923 cx_attr_export |
857 CX_EXPORT CxIterator cxListIterator(const CxList *list); |
| 924 CxIterator cxListMutIteratorAt( |
858 |
| 925 CxList *list, |
859 /** |
| 926 size_t index |
860 * 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 * |
861 * |
| 933 * The returned iterator is position-aware. |
862 * The returned iterator is position-aware. |
| 934 * |
863 * |
| 935 * If the index is out of range, a past-the-end iterator will be returned. |
864 * If the list is empty or @c NULL, a past-the-end iterator will be returned. |
| 936 * |
865 * |
| 937 * @param list the list |
866 * @param list the list |
| 938 * @param index the index where the iterator shall point at |
|
| 939 * @return a new iterator |
867 * @return a new iterator |
| 940 */ |
868 */ |
| 941 cx_attr_nonnull |
|
| 942 cx_attr_nodiscard |
869 cx_attr_nodiscard |
| 943 cx_attr_export |
870 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 |
871 |
| 1014 /** |
872 /** |
| 1015 * Returns the index of the first element that equals @p elem. |
873 * Returns the index of the first element that equals @p elem. |
| 1016 * |
874 * |
| 1017 * Determining equality is performed by the list's comparator function. |
875 * Determining equality is performed by the list's comparator function. |
| 1020 * @param elem the element to find |
878 * @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 |
879 * @return the index of the element or the size of the list when the element is not found |
| 1022 * @see cxListIndexValid() |
880 * @see cxListIndexValid() |
| 1023 * @see cxListContains() |
881 * @see cxListContains() |
| 1024 */ |
882 */ |
| 1025 cx_attr_nonnull |
883 cx_attr_nonnull cx_attr_nodiscard |
| 1026 cx_attr_nodiscard |
884 CX_EXPORT size_t cxListFind(const CxList *list, const void *elem); |
| 1027 static inline size_t cxListFind( |
885 |
| 1028 const CxList *list, |
886 /** |
| 1029 const void *elem |
887 * 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 * |
888 * |
| 1037 * The elements are compared with the list's comparator function. |
889 * The elements are compared with the list's comparator function. |
| 1038 * |
890 * |
| 1039 * @param list the list |
891 * @param list the list |
| 1040 * @param elem the element to find |
892 * @param elem the element to find |
| 1041 * @retval true if the element is contained |
893 * @retval true if the element is contained |
| 1042 * @retval false if the element is not contained |
894 * @retval false if the element is not contained |
| 1043 * @see cxListFind() |
895 * @see cxListFind() |
| 1044 */ |
896 */ |
| 1045 cx_attr_nonnull |
897 cx_attr_nonnull cx_attr_nodiscard |
| 1046 cx_attr_nodiscard |
898 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 |
899 |
| 1054 /** |
900 /** |
| 1055 * Checks if the specified index is within bounds. |
901 * Checks if the specified index is within bounds. |
| 1056 * |
902 * |
| 1057 * @param list the list |
903 * @param list the list |
| 1058 * @param index the index |
904 * @param index the index |
| 1059 * @retval true if the index is within bounds |
905 * @retval true if the index is within bounds |
| 1060 * @retval false if the index is out of bounds |
906 * @retval false if the index is out of bounds |
| 1061 */ |
907 */ |
| 1062 cx_attr_nonnull |
908 cx_attr_nonnull cx_attr_nodiscard |
| 1063 cx_attr_nodiscard |
909 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 |
910 |
| 1068 /** |
911 /** |
| 1069 * Removes and returns the index of the first element that equals @p elem. |
912 * Removes and returns the index of the first element that equals @p elem. |
| 1070 * |
913 * |
| 1071 * Determining equality is performed by the list's comparator function. |
914 * Determining equality is performed by the list's comparator function. |
| 1075 * @return the index of the now removed element or the list size |
918 * @return the index of the now removed element or the list size |
| 1076 * when the element is not found or could not be removed |
919 * when the element is not found or could not be removed |
| 1077 * @see cxListIndexValid() |
920 * @see cxListIndexValid() |
| 1078 */ |
921 */ |
| 1079 cx_attr_nonnull |
922 cx_attr_nonnull |
| 1080 static inline size_t cxListFindRemove( |
923 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 |
924 |
| 1087 /** |
925 /** |
| 1088 * Sorts the list. |
926 * Sorts the list. |
| 1089 * |
927 * |
| 1090 * @remark The underlying sort algorithm is implementation defined. |
928 * @remark The underlying sort algorithm is implementation defined. |
| 1091 * |
929 * |
| 1092 * @param list the list |
930 * @param list the list |
| 1093 */ |
931 */ |
| 1094 cx_attr_nonnull |
932 cx_attr_nonnull |
| 1095 static inline void cxListSort(CxList *list) { |
933 CX_EXPORT void cxListSort(CxList *list); |
| 1096 if (list->collection.sorted) return; |
|
| 1097 list->cl->sort(list); |
|
| 1098 list->collection.sorted = true; |
|
| 1099 } |
|
| 1100 |
934 |
| 1101 /** |
935 /** |
| 1102 * Reverses the order of the items. |
936 * Reverses the order of the items. |
| 1103 * |
937 * |
| 1104 * @param list the list |
938 * @param list the list |
| 1105 */ |
939 */ |
| 1106 cx_attr_nonnull |
940 cx_attr_nonnull |
| 1107 static inline void cxListReverse(CxList *list) { |
941 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 |
942 |
| 1113 /** |
943 /** |
| 1114 * Compares a list to another list of the same type. |
944 * Compares a list to another list of the same type. |
| 1115 * |
945 * |
| 1116 * First, the list sizes are compared. |
946 * First, the list sizes are compared. |
| 1117 * If they match, the lists are compared element-wise. |
947 * If they match, the lists are compared element-wise. |
| 1118 * |
948 * |
| 1119 * @param list the list |
949 * @param list the list |
| 1120 * @param other the list to compare to |
950 * @param other the list to compare to |
| 1121 * @retval zero both lists are equal element wise |
951 * @retval zero both lists are equal element wise |
| 1122 * @retval negative the first list is smaller |
952 * @retval negative the first list is smaller, |
| 1123 * or the first non-equal element in the first list is smaller |
953 * or the first non-equal element in the first list is smaller |
| 1124 * @retval positive the first list is larger |
954 * @retval positive the first list is larger |
| 1125 * or the first non-equal element in the first list is larger |
955 * or the first non-equal element in the first list is larger |
| 1126 */ |
956 */ |
| 1127 cx_attr_nonnull |
957 cx_attr_nonnull cx_attr_nodiscard |
| 1128 cx_attr_nodiscard |
958 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 |
959 |
| 1135 /** |
960 /** |
| 1136 * Deallocates the memory of the specified list structure. |
961 * Deallocates the memory of the specified list structure. |
| 1137 * |
962 * |
| 1138 * Also calls the content destructor functions for each element, if specified. |
963 * Also calls the content destructor functions for each element, if specified. |
| 1139 * |
964 * |
| 1140 * @param list the list which shall be freed |
965 * @param list the list that shall be freed |
| 1141 */ |
966 */ |
| 1142 cx_attr_export |
967 CX_EXPORT void cxListFree(CxList *list); |
| 1143 void cxListFree(CxList *list); |
968 |
| 1144 |
969 |
| |
970 /** |
| |
971 * Performs a deep clone of one list into another. |
| |
972 * |
| |
973 * If the destination list already contains elements, the cloned elements |
| |
974 * are appended to that list. |
| |
975 * |
| |
976 * @attention If the cloned elements need to be destroyed by a destructor |
| |
977 * function, you must make sure that the destination list also uses this |
| |
978 * destructor function. |
| |
979 * |
| |
980 * @param dst the destination list |
| |
981 * @param src the source list |
| |
982 * @param clone_func the clone function for the elements |
| |
983 * @param clone_allocator the allocator that is passed to the clone function |
| |
984 * @param data optional additional data that is passed to the clone function |
| |
985 * @retval zero when all elements were successfully cloned |
| |
986 * @retval non-zero when an allocation error occurred |
| |
987 * @see cxListCloneSimple() |
| |
988 */ |
| |
989 cx_attr_nonnull_arg(1, 2, 3) |
| |
990 CX_EXPORT int cxListClone(CxList *dst, const CxList *src, |
| |
991 cx_clone_func clone_func, const CxAllocator *clone_allocator, void *data); |
| |
992 |
| |
993 /** |
| |
994 * Clones elements from a list only if they are not present in another list. |
| |
995 * |
| |
996 * If the @p minuend does not contain duplicates, this is equivalent to adding |
| |
997 * the set difference to the destination list. |
| |
998 * |
| |
999 * This function is optimized for the case when both the @p minuend and the |
| |
1000 * @p subtrahend are sorted. |
| |
1001 * |
| |
1002 * @param dst the destination list |
| |
1003 * @param minuend the list to subtract elements from |
| |
1004 * @param subtrahend the elements that shall be subtracted |
| |
1005 * @param clone_func the clone function for the elements |
| |
1006 * @param clone_allocator the allocator that is passed to the clone function |
| |
1007 * @param data optional additional data that is passed to the clone function |
| |
1008 * @retval zero when the elements were successfully cloned |
| |
1009 * @retval non-zero when an allocation error occurred |
| |
1010 * @see cxListDifferenceSimple() |
| |
1011 */ |
| |
1012 cx_attr_nonnull_arg(1, 2, 3, 4) |
| |
1013 CX_EXPORT int cxListDifference(CxList *dst, |
| |
1014 const CxList *minuend, const CxList *subtrahend, |
| |
1015 cx_clone_func clone_func, const CxAllocator *clone_allocator, void *data); |
| |
1016 |
| |
1017 /** |
| |
1018 * Clones elements from a list only if they are also present in another list. |
| |
1019 * |
| |
1020 * This function is optimized for the case when both the @p src and the |
| |
1021 * @p other list are sorted. |
| |
1022 * |
| |
1023 * If the destination list already contains elements, the intersection is appended |
| |
1024 * to that list. |
| |
1025 * |
| |
1026 * @param dst the destination list |
| |
1027 * @param src the list to clone the elements from |
| |
1028 * @param other the list to check the elements for existence |
| |
1029 * @param clone_func the clone function for the elements |
| |
1030 * @param clone_allocator the allocator that is passed to the clone function |
| |
1031 * @param data optional additional data that is passed to the clone function |
| |
1032 * @retval zero when the elements were successfully cloned |
| |
1033 * @retval non-zero when an allocation error occurred |
| |
1034 * @see cxListIntersectionSimple() |
| |
1035 */ |
| |
1036 cx_attr_nonnull_arg(1, 2, 3, 4) |
| |
1037 CX_EXPORT int cxListIntersection(CxList *dst, const CxList *src, const CxList *other, |
| |
1038 cx_clone_func clone_func, const CxAllocator *clone_allocator, void *data); |
| |
1039 |
| |
1040 /** |
| |
1041 * Performs a deep clone of one list into another, skipping duplicates. |
| |
1042 * |
| |
1043 * This function is optimized for the case when both the @p src and the |
| |
1044 * @p other list are sorted. |
| |
1045 * In that case, the union will also be sorted. |
| |
1046 * |
| |
1047 * If the destination list already contains elements, the union is appended |
| |
1048 * to that list. In that case the destination is not necessarily sorted. |
| |
1049 * |
| |
1050 * @param dst the destination list |
| |
1051 * @param src the primary source list |
| |
1052 * @param other the other list, where elements are only cloned from |
| |
1053 * when they are not in @p src |
| |
1054 * @param clone_func the clone function for the elements |
| |
1055 * @param clone_allocator the allocator that is passed to the clone function |
| |
1056 * @param data optional additional data that is passed to the clone function |
| |
1057 * @retval zero when the elements were successfully cloned |
| |
1058 * @retval non-zero when an allocation error occurred |
| |
1059 * @see cxListUnionSimple() |
| |
1060 */ |
| |
1061 cx_attr_nonnull_arg(1, 2, 3, 4) |
| |
1062 CX_EXPORT int cxListUnion(CxList *dst, const CxList *src, const CxList *other, |
| |
1063 cx_clone_func clone_func, const CxAllocator *clone_allocator, void *data); |
| |
1064 |
| |
1065 /** |
| |
1066 * Performs a shallow clone of one list into another. |
| |
1067 * |
| |
1068 * This function uses the default allocator, if needed, and performs |
| |
1069 * shallow clones with @c memcpy(). |
| |
1070 * |
| |
1071 * If the destination list already contains elements, the cloned elements |
| |
1072 * are appended to that list. |
| |
1073 * |
| |
1074 * @attention If the cloned elements need to be destroyed by a destructor |
| |
1075 * function, you must make sure that the destination list also uses this |
| |
1076 * destructor function. |
| |
1077 * |
| |
1078 * @param dst the destination list |
| |
1079 * @param src the source list |
| |
1080 * @retval zero when all elements were successfully cloned |
| |
1081 * @retval non-zero when an allocation error occurred |
| |
1082 * @see cxListClone() |
| |
1083 */ |
| |
1084 cx_attr_nonnull |
| |
1085 CX_EXPORT int cxListCloneSimple(CxList *dst, const CxList *src); |
| |
1086 |
| |
1087 /** |
| |
1088 * Clones elements from a list only if they are not present in another list. |
| |
1089 * |
| |
1090 * This function uses the default allocator, if needed, and performs |
| |
1091 * shallow clones with @c memcpy(). |
| |
1092 * |
| |
1093 * If the @p minuend does not contain duplicates, this is equivalent to adding |
| |
1094 * the set difference to the destination list. |
| |
1095 * |
| |
1096 * This function is optimized for the case when both the @p minuend and the |
| |
1097 * @p subtrahend are sorted. |
| |
1098 * |
| |
1099 * @param dst the destination list |
| |
1100 * @param minuend the list to subtract elements from |
| |
1101 * @param subtrahend the elements that shall be subtracted |
| |
1102 * @retval zero when the elements were successfully cloned |
| |
1103 * @retval non-zero when an allocation error occurred |
| |
1104 * @see cxListDifference() |
| |
1105 */ |
| |
1106 cx_attr_nonnull |
| |
1107 CX_EXPORT int cxListDifferenceSimple(CxList *dst, |
| |
1108 const CxList *minuend, const CxList *subtrahend); |
| |
1109 |
| |
1110 /** |
| |
1111 * Clones elements from a list only if they are also present in another list. |
| |
1112 * |
| |
1113 * This function uses the default allocator, if needed, and performs |
| |
1114 * shallow clones with @c memcpy(). |
| |
1115 * |
| |
1116 * This function is optimized for the case when both the @p src and the |
| |
1117 * @p other list are sorted. |
| |
1118 * |
| |
1119 * If the destination list already contains elements, the intersection is appended |
| |
1120 * to that list. |
| |
1121 * |
| |
1122 * @param dst the destination list |
| |
1123 * @param src the list to clone the elements from |
| |
1124 * @param other the list to check the elements for existence |
| |
1125 * @retval zero when the elements were successfully cloned |
| |
1126 * @retval non-zero when an allocation error occurred |
| |
1127 * @see cxListIntersection() |
| |
1128 */ |
| |
1129 cx_attr_nonnull |
| |
1130 CX_EXPORT int cxListIntersectionSimple(CxList *dst, const CxList *src, const CxList *other); |
| |
1131 |
| |
1132 /** |
| |
1133 * Performs a deep clone of one list into another, skipping duplicates. |
| |
1134 * |
| |
1135 * This function uses the default allocator, if needed, and performs |
| |
1136 * shallow clones with @c memcpy(). |
| |
1137 * |
| |
1138 * This function is optimized for the case when both the @p src and the |
| |
1139 * @p other list are sorted. |
| |
1140 * In that case, the union will also be sorted. |
| |
1141 * |
| |
1142 * If the destination list already contains elements, the union is appended |
| |
1143 * to that list. In that case the destination is not necessarily sorted. |
| |
1144 * |
| |
1145 * @param dst the destination list |
| |
1146 * @param src the primary source list |
| |
1147 * @param other the other list, where elements are only cloned from |
| |
1148 * when they are not in @p src |
| |
1149 * @retval zero when the elements were successfully cloned |
| |
1150 * @retval non-zero when an allocation error occurred |
| |
1151 * @see cxListUnion() |
| |
1152 */ |
| |
1153 cx_attr_nonnull |
| |
1154 CX_EXPORT int cxListUnionSimple(CxList *dst, const CxList *src, const CxList *other); |
| |
1155 |
| |
1156 /** |
| |
1157 * Asks the list to reserve enough memory for a given total number of elements. |
| |
1158 * |
| |
1159 * List implementations are free to choose if reserving memory upfront makes |
| |
1160 * sense. |
| |
1161 * For example, array-based implementations usually do support reserving memory |
| |
1162 * for additional elements while linked lists usually don't. |
| |
1163 * |
| |
1164 * @note When the requested capacity is smaller than the current size, |
| |
1165 * this function returns zero without performing any action. |
| |
1166 * |
| |
1167 * @param list the list |
| |
1168 * @param capacity the expected total number of elements |
| |
1169 * @retval zero on success or when overallocation is not supported |
| |
1170 * @retval non-zero when an allocation error occurred |
| |
1171 * @see cxListShrink() |
| |
1172 */ |
| |
1173 cx_attr_nonnull |
| |
1174 CX_EXPORT int cxListReserve(CxList *list, size_t capacity); |
| |
1175 |
| |
1176 /** |
| |
1177 * Advises the list to free any overallocated memory. |
| |
1178 * |
| |
1179 * Lists that do not support overallocation simply return zero. |
| |
1180 * |
| |
1181 * This function usually returns zero, except for very special and custom |
| |
1182 * list and/or allocator implementations where freeing memory can fail. |
| |
1183 * |
| |
1184 * @param list the list |
| |
1185 * @return usually zero |
| |
1186 */ |
| |
1187 cx_attr_nonnull |
| |
1188 CX_EXPORT int cxListShrink(CxList *list); |
| 1145 |
1189 |
| 1146 #ifdef __cplusplus |
1190 #ifdef __cplusplus |
| 1147 } // extern "C" |
1191 } // extern "C" |
| 1148 #endif |
1192 #endif |
| 1149 |
1193 |