| 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 list memory. |
| 75 */ |
78 */ |
| |
79 cx_attr_nonnull |
| 76 void (*destructor)(struct cx_list_s *list); |
80 void (*destructor)(struct cx_list_s *list); |
| 77 |
81 |
| 78 /** |
82 /** |
| 79 * Member function for inserting a single element. |
83 * Member function for inserting a single element. |
| 80 * Implementors SHOULD see to performant implementations for corner cases. |
84 * Implementors SHOULD see to performant implementations for corner cases. |
| 81 */ |
85 */ |
| |
86 cx_attr_nonnull |
| 82 int (*insert_element)( |
87 int (*insert_element)( |
| 83 struct cx_list_s *list, |
88 struct cx_list_s *list, |
| 84 size_t index, |
89 size_t index, |
| 85 const void *data |
90 const void *data |
| 86 ); |
91 ); |
| 100 /** |
106 /** |
| 101 * Member function for inserting sorted elements into a sorted list. |
107 * Member function for inserting sorted elements into a sorted list. |
| 102 * |
108 * |
| 103 * @see cx_list_default_insert_sorted() |
109 * @see cx_list_default_insert_sorted() |
| 104 */ |
110 */ |
| |
111 cx_attr_nonnull |
| 105 size_t (*insert_sorted)( |
112 size_t (*insert_sorted)( |
| 106 struct cx_list_s *list, |
113 struct cx_list_s *list, |
| 107 const void *sorted_data, |
114 const void *sorted_data, |
| 108 size_t n |
115 size_t n |
| 109 ); |
116 ); |
| 110 |
117 |
| 111 /** |
118 /** |
| 112 * Member function for inserting an element relative to an iterator position. |
119 * Member function for inserting an element relative to an iterator position. |
| 113 */ |
120 */ |
| |
121 cx_attr_nonnull |
| 114 int (*insert_iter)( |
122 int (*insert_iter)( |
| 115 struct cx_iterator_s *iter, |
123 struct cx_iterator_s *iter, |
| 116 const void *elem, |
124 const void *elem, |
| 117 int prepend |
125 int prepend |
| 118 ); |
126 ); |
| 125 * When \p targetbuf is not set, the destructors SHALL be invoked. |
133 * When \p targetbuf is not set, the destructors SHALL be invoked. |
| 126 * |
134 * |
| 127 * The function SHALL return the actual number of elements removed, which |
135 * The function SHALL return the actual number of elements removed, which |
| 128 * might be lower than \p num when going out of bounds. |
136 * might be lower than \p num when going out of bounds. |
| 129 */ |
137 */ |
| |
138 cx_attr_nonnull_arg(1) |
| |
139 cx_attr_access_w(4) |
| 130 size_t (*remove)( |
140 size_t (*remove)( |
| 131 struct cx_list_s *list, |
141 struct cx_list_s *list, |
| 132 size_t index, |
142 size_t index, |
| 133 size_t num, |
143 size_t num, |
| 134 void *targetbuf |
144 void *targetbuf |
| 135 ); |
145 ); |
| 136 |
146 |
| 137 /** |
147 /** |
| 138 * Member function for removing all elements. |
148 * Member function for removing all elements. |
| 139 */ |
149 */ |
| |
150 cx_attr_nonnull |
| 140 void (*clear)(struct cx_list_s *list); |
151 void (*clear)(struct cx_list_s *list); |
| 141 |
152 |
| 142 /** |
153 /** |
| 143 * Member function for swapping two elements. |
154 * Member function for swapping two elements. |
| 144 * @see cx_list_default_swap() |
155 * @see cx_list_default_swap() |
| 145 */ |
156 */ |
| |
157 cx_attr_nonnull |
| 146 int (*swap)( |
158 int (*swap)( |
| 147 struct cx_list_s *list, |
159 struct cx_list_s *list, |
| 148 size_t i, |
160 size_t i, |
| 149 size_t j |
161 size_t j |
| 150 ); |
162 ); |
| 151 |
163 |
| 152 /** |
164 /** |
| 153 * Member function for element lookup. |
165 * Member function for element lookup. |
| 154 */ |
166 */ |
| |
167 cx_attr_nonnull |
| |
168 cx_attr_nodiscard |
| 155 void *(*at)( |
169 void *(*at)( |
| 156 const struct cx_list_s *list, |
170 const struct cx_list_s *list, |
| 157 size_t index |
171 size_t index |
| 158 ); |
172 ); |
| 159 |
173 |
| 160 /** |
174 /** |
| 161 * Member function for finding and optionally removing an element. |
175 * Member function for finding and optionally removing an element. |
| 162 */ |
176 */ |
| |
177 cx_attr_nonnull |
| |
178 cx_attr_nodiscard |
| 163 ssize_t (*find_remove)( |
179 ssize_t (*find_remove)( |
| 164 struct cx_list_s *list, |
180 struct cx_list_s *list, |
| 165 const void *elem, |
181 const void *elem, |
| 166 bool remove |
182 bool remove |
| 167 ); |
183 ); |
| 168 |
184 |
| 169 /** |
185 /** |
| 170 * Member function for sorting the list in-place. |
186 * Member function for sorting the list in-place. |
| 171 * @see cx_list_default_sort() |
187 * @see cx_list_default_sort() |
| 172 */ |
188 */ |
| |
189 cx_attr_nonnull |
| 173 void (*sort)(struct cx_list_s *list); |
190 void (*sort)(struct cx_list_s *list); |
| 174 |
191 |
| 175 /** |
192 /** |
| 176 * Optional member function for comparing this list |
193 * Optional member function for comparing this list |
| 177 * to another list of the same type. |
194 * to another list of the same type. |
| 178 * If set to \c NULL, comparison won't be optimized. |
195 * If set to \c NULL, comparison won't be optimized. |
| 179 */ |
196 */ |
| |
197 cx_attr_nonnull |
| 180 int (*compare)( |
198 int (*compare)( |
| 181 const struct cx_list_s *list, |
199 const struct cx_list_s *list, |
| 182 const struct cx_list_s *other |
200 const struct cx_list_s *other |
| 183 ); |
201 ); |
| 184 |
202 |
| 185 /** |
203 /** |
| 186 * Member function for reversing the order of the items. |
204 * Member function for reversing the order of the items. |
| 187 */ |
205 */ |
| |
206 cx_attr_nonnull |
| 188 void (*reverse)(struct cx_list_s *list); |
207 void (*reverse)(struct cx_list_s *list); |
| 189 |
208 |
| 190 /** |
209 /** |
| 191 * Member function for returning an iterator pointing to the specified index. |
210 * Member function for returning an iterator pointing to the specified index. |
| 192 */ |
211 */ |
| |
212 cx_attr_nonnull |
| 193 struct cx_iterator_s (*iterator)( |
213 struct cx_iterator_s (*iterator)( |
| 194 const struct cx_list_s *list, |
214 const struct cx_list_s *list, |
| 195 size_t index, |
215 size_t index, |
| 196 bool backward |
216 bool backward |
| 197 ); |
217 ); |
| 209 * @param index the index where to insert the data |
229 * @param index the index where to insert the data |
| 210 * @param data a pointer to the array of data to insert |
230 * @param data a pointer to the array of data to insert |
| 211 * @param n the number of elements to insert |
231 * @param n the number of elements to insert |
| 212 * @return the number of elements actually inserted |
232 * @return the number of elements actually inserted |
| 213 */ |
233 */ |
| 214 __attribute__((__nonnull__)) |
234 cx_attr_nonnull |
| 215 size_t cx_list_default_insert_array( |
235 size_t cx_list_default_insert_array( |
| 216 struct cx_list_s *list, |
236 struct cx_list_s *list, |
| 217 size_t index, |
237 size_t index, |
| 218 const void *data, |
238 const void *data, |
| 219 size_t n |
239 size_t n |
| 233 * @param list the list |
253 * @param list the list |
| 234 * @param sorted_data a pointer to the array of pre-sorted data to insert |
254 * @param sorted_data a pointer to the array of pre-sorted data to insert |
| 235 * @param n the number of elements to insert |
255 * @param n the number of elements to insert |
| 236 * @return the number of elements actually inserted |
256 * @return the number of elements actually inserted |
| 237 */ |
257 */ |
| 238 __attribute__((__nonnull__)) |
258 cx_attr_nonnull |
| 239 size_t cx_list_default_insert_sorted( |
259 size_t cx_list_default_insert_sorted( |
| 240 struct cx_list_s *list, |
260 struct cx_list_s *list, |
| 241 const void *sorted_data, |
261 const void *sorted_data, |
| 242 size_t n |
262 size_t n |
| 243 ); |
263 ); |
| 266 * @param i index of one element |
286 * @param i index of one element |
| 267 * @param j index of the other element |
287 * @param j index of the other element |
| 268 * @return zero on success, non-zero when indices are out of bounds or memory |
288 * @return zero on success, non-zero when indices are out of bounds or memory |
| 269 * allocation for the temporary buffer fails |
289 * allocation for the temporary buffer fails |
| 270 */ |
290 */ |
| 271 __attribute__((__nonnull__)) |
291 cx_attr_nonnull |
| 272 int cx_list_default_swap(struct cx_list_s *list, size_t i, size_t j); |
292 int cx_list_default_swap(struct cx_list_s *list, size_t i, size_t j); |
| 273 |
293 |
| 274 /** |
294 /** |
| 275 * Common type for all list implementations. |
295 * Common type for all list implementations. |
| 276 */ |
296 */ |
| 298 * objects is undefined. |
318 * objects is undefined. |
| 299 * |
319 * |
| 300 * @param list the list |
320 * @param list the list |
| 301 * @see cxListStoreObjects() |
321 * @see cxListStoreObjects() |
| 302 */ |
322 */ |
| 303 __attribute__((__nonnull__)) |
323 cx_attr_nonnull |
| 304 void cxListStorePointers(CxList *list); |
324 void cxListStorePointers(CxList *list); |
| 305 |
325 |
| 306 /** |
326 /** |
| 307 * Returns true, if this list is storing pointers instead of the actual data. |
327 * Returns true, if this list is storing pointers instead of the actual data. |
| 308 * |
328 * |
| 309 * @param list |
329 * @param list |
| 310 * @return true, if this list is storing pointers |
330 * @return true, if this list is storing pointers |
| 311 * @see cxListStorePointers() |
331 * @see cxListStorePointers() |
| 312 */ |
332 */ |
| 313 __attribute__((__nonnull__)) |
333 cx_attr_nonnull |
| 314 static inline bool cxListIsStoringPointers(const CxList *list) { |
334 static inline bool cxListIsStoringPointers(const CxList *list) { |
| 315 return list->collection.store_pointer; |
335 return list->collection.store_pointer; |
| 316 } |
336 } |
| 317 |
337 |
| 318 /** |
338 /** |
| 319 * Returns the number of elements currently stored in the list. |
339 * Returns the number of elements currently stored in the list. |
| 320 * |
340 * |
| 321 * @param list the list |
341 * @param list the list |
| 322 * @return the number of currently stored elements |
342 * @return the number of currently stored elements |
| 323 */ |
343 */ |
| 324 __attribute__((__nonnull__)) |
344 cx_attr_nonnull |
| 325 static inline size_t cxListSize(const CxList *list) { |
345 static inline size_t cxListSize(const CxList *list) { |
| 326 return list->collection.size; |
346 return list->collection.size; |
| 327 } |
347 } |
| 328 |
348 |
| 329 /** |
349 /** |
| 332 * @param list the list |
352 * @param list the list |
| 333 * @param elem a pointer to the element to add |
353 * @param elem a pointer to the element to add |
| 334 * @return zero on success, non-zero on memory allocation failure |
354 * @return zero on success, non-zero on memory allocation failure |
| 335 * @see cxListAddArray() |
355 * @see cxListAddArray() |
| 336 */ |
356 */ |
| 337 __attribute__((__nonnull__)) |
357 cx_attr_nonnull |
| 338 static inline int cxListAdd( |
358 static inline int cxListAdd( |
| 339 CxList *list, |
359 CxList *list, |
| 340 const void *elem |
360 const void *elem |
| 341 ) { |
361 ) { |
| 342 return list->cl->insert_element(list, list->collection.size, elem); |
362 return list->cl->insert_element(list, list->collection.size, elem); |
| 473 * @param elem the element to insert |
493 * @param elem the element to insert |
| 474 * @return zero on success, non-zero on memory allocation failure |
494 * @return zero on success, non-zero on memory allocation failure |
| 475 * @see cxListInsert() |
495 * @see cxListInsert() |
| 476 * @see cxListInsertBefore() |
496 * @see cxListInsertBefore() |
| 477 */ |
497 */ |
| 478 __attribute__((__nonnull__)) |
498 cx_attr_nonnull |
| 479 static inline int cxListInsertAfter( |
499 static inline int cxListInsertAfter( |
| 480 CxIterator *iter, |
500 CxIterator *iter, |
| 481 const void *elem |
501 const void *elem |
| 482 ) { |
502 ) { |
| 483 return ((struct cx_list_s *) iter->src_handle.m)->cl->insert_iter(iter, elem, 0); |
503 return ((struct cx_list_s *) iter->src_handle.m)->cl->insert_iter(iter, elem, 0); |
| 496 * @param elem the element to insert |
516 * @param elem the element to insert |
| 497 * @return zero on success, non-zero on memory allocation failure |
517 * @return zero on success, non-zero on memory allocation failure |
| 498 * @see cxListInsert() |
518 * @see cxListInsert() |
| 499 * @see cxListInsertAfter() |
519 * @see cxListInsertAfter() |
| 500 */ |
520 */ |
| 501 __attribute__((__nonnull__)) |
521 cx_attr_nonnull |
| 502 static inline int cxListInsertBefore( |
522 static inline int cxListInsertBefore( |
| 503 CxIterator *iter, |
523 CxIterator *iter, |
| 504 const void *elem |
524 const void *elem |
| 505 ) { |
525 ) { |
| 506 return ((struct cx_list_s *) iter->src_handle.m)->cl->insert_iter(iter, elem, 1); |
526 return ((struct cx_list_s *) iter->src_handle.m)->cl->insert_iter(iter, elem, 1); |
| 514 * |
534 * |
| 515 * @param list the list |
535 * @param list the list |
| 516 * @param index the index of the element |
536 * @param index the index of the element |
| 517 * @return zero on success, non-zero if the index is out of bounds |
537 * @return zero on success, non-zero if the index is out of bounds |
| 518 */ |
538 */ |
| 519 __attribute__((__nonnull__)) |
539 cx_attr_nonnull |
| 520 static inline int cxListRemove( |
540 static inline int cxListRemove( |
| 521 CxList *list, |
541 CxList *list, |
| 522 size_t index |
542 size_t index |
| 523 ) { |
543 ) { |
| 524 return list->cl->remove(list, index, 1, NULL) == 0; |
544 return list->cl->remove(list, index, 1, NULL) == 0; |
| 647 * |
669 * |
| 648 * @param list the list |
670 * @param list the list |
| 649 * @param index the index where the iterator shall point at |
671 * @param index the index where the iterator shall point at |
| 650 * @return a new iterator |
672 * @return a new iterator |
| 651 */ |
673 */ |
| 652 __attribute__((__nonnull__, __warn_unused_result__)) |
674 cx_attr_nonnull |
| |
675 cx_attr_nodiscard |
| 653 static inline CxIterator cxListIteratorAt( |
676 static inline CxIterator cxListIteratorAt( |
| 654 const CxList *list, |
677 const CxList *list, |
| 655 size_t index |
678 size_t index |
| 656 ) { |
679 ) { |
| 657 return list->cl->iterator(list, index, false); |
680 return list->cl->iterator(list, index, false); |
| 666 * |
689 * |
| 667 * @param list the list |
690 * @param list the list |
| 668 * @param index the index where the iterator shall point at |
691 * @param index the index where the iterator shall point at |
| 669 * @return a new iterator |
692 * @return a new iterator |
| 670 */ |
693 */ |
| 671 __attribute__((__nonnull__, __warn_unused_result__)) |
694 cx_attr_nonnull |
| |
695 cx_attr_nodiscard |
| 672 static inline CxIterator cxListBackwardsIteratorAt( |
696 static inline CxIterator cxListBackwardsIteratorAt( |
| 673 const CxList *list, |
697 const CxList *list, |
| 674 size_t index |
698 size_t index |
| 675 ) { |
699 ) { |
| 676 return list->cl->iterator(list, index, true); |
700 return list->cl->iterator(list, index, true); |
| 719 * If the list is empty, a past-the-end iterator will be returned. |
745 * If the list is empty, a past-the-end iterator will be returned. |
| 720 * |
746 * |
| 721 * @param list the list |
747 * @param list the list |
| 722 * @return a new iterator |
748 * @return a new iterator |
| 723 */ |
749 */ |
| 724 __attribute__((__nonnull__, __warn_unused_result__)) |
750 cx_attr_nonnull |
| |
751 cx_attr_nodiscard |
| 725 static inline CxIterator cxListIterator(const CxList *list) { |
752 static inline CxIterator cxListIterator(const CxList *list) { |
| 726 return list->cl->iterator(list, 0, false); |
753 return list->cl->iterator(list, 0, false); |
| 727 } |
754 } |
| 728 |
755 |
| 729 /** |
756 /** |
| 734 * If the list is empty, a past-the-end iterator will be returned. |
761 * If the list is empty, a past-the-end iterator will be returned. |
| 735 * |
762 * |
| 736 * @param list the list |
763 * @param list the list |
| 737 * @return a new iterator |
764 * @return a new iterator |
| 738 */ |
765 */ |
| 739 __attribute__((__nonnull__, __warn_unused_result__)) |
766 cx_attr_nonnull |
| |
767 cx_attr_nodiscard |
| 740 static inline CxIterator cxListMutIterator(CxList *list) { |
768 static inline CxIterator cxListMutIterator(CxList *list) { |
| 741 return cxListMutIteratorAt(list, 0); |
769 return cxListMutIteratorAt(list, 0); |
| 742 } |
770 } |
| 743 |
771 |
| 744 |
772 |
| 750 * If the list is empty, a past-the-end iterator will be returned. |
778 * If the list is empty, a past-the-end iterator will be returned. |
| 751 * |
779 * |
| 752 * @param list the list |
780 * @param list the list |
| 753 * @return a new iterator |
781 * @return a new iterator |
| 754 */ |
782 */ |
| 755 __attribute__((__nonnull__, __warn_unused_result__)) |
783 cx_attr_nonnull |
| |
784 cx_attr_nodiscard |
| 756 static inline CxIterator cxListBackwardsIterator(const CxList *list) { |
785 static inline CxIterator cxListBackwardsIterator(const CxList *list) { |
| 757 return list->cl->iterator(list, list->collection.size - 1, true); |
786 return list->cl->iterator(list, list->collection.size - 1, true); |
| 758 } |
787 } |
| 759 |
788 |
| 760 /** |
789 /** |
| 765 * If the list is empty, a past-the-end iterator will be returned. |
794 * If the list is empty, a past-the-end iterator will be returned. |
| 766 * |
795 * |
| 767 * @param list the list |
796 * @param list the list |
| 768 * @return a new iterator |
797 * @return a new iterator |
| 769 */ |
798 */ |
| 770 __attribute__((__nonnull__, __warn_unused_result__)) |
799 cx_attr_nonnull |
| |
800 cx_attr_nodiscard |
| 771 static inline CxIterator cxListMutBackwardsIterator(CxList *list) { |
801 static inline CxIterator cxListMutBackwardsIterator(CxList *list) { |
| 772 return cxListMutBackwardsIteratorAt(list, list->collection.size - 1); |
802 return cxListMutBackwardsIteratorAt(list, list->collection.size - 1); |
| 773 } |
803 } |
| 774 |
804 |
| 775 /** |
805 /** |
| 780 * @param list the list |
810 * @param list the list |
| 781 * @param elem the element to find |
811 * @param elem the element to find |
| 782 * @return the index of the element or a negative |
812 * @return the index of the element or a negative |
| 783 * value when the element is not found |
813 * value when the element is not found |
| 784 */ |
814 */ |
| 785 __attribute__((__nonnull__)) |
815 cx_attr_nonnull |
| |
816 cx_attr_nodiscard |
| 786 static inline ssize_t cxListFind( |
817 static inline ssize_t cxListFind( |
| 787 const CxList *list, |
818 const CxList *list, |
| 788 const void *elem |
819 const void *elem |
| 789 ) { |
820 ) { |
| 790 return list->cl->find_remove((CxList*)list, elem, false); |
821 return list->cl->find_remove((CxList*)list, elem, false); |
| 798 * @param list the list |
829 * @param list the list |
| 799 * @param elem the element to find and remove |
830 * @param elem the element to find and remove |
| 800 * @return the index of the now removed element or a negative |
831 * @return the index of the now removed element or a negative |
| 801 * value when the element is not found or could not be removed |
832 * value when the element is not found or could not be removed |
| 802 */ |
833 */ |
| 803 __attribute__((__nonnull__)) |
834 cx_attr_nonnull |
| 804 static inline ssize_t cxListFindRemove( |
835 static inline ssize_t cxListFindRemove( |
| 805 CxList *list, |
836 CxList *list, |
| 806 const void *elem |
837 const void *elem |
| 807 ) { |
838 ) { |
| 808 return list->cl->find_remove(list, elem, true); |
839 return list->cl->find_remove(list, elem, true); |
| 813 * |
844 * |
| 814 * \remark The underlying sort algorithm is implementation defined. |
845 * \remark The underlying sort algorithm is implementation defined. |
| 815 * |
846 * |
| 816 * @param list the list |
847 * @param list the list |
| 817 */ |
848 */ |
| 818 __attribute__((__nonnull__)) |
849 cx_attr_nonnull |
| 819 static inline void cxListSort(CxList *list) { |
850 static inline void cxListSort(CxList *list) { |
| 820 list->cl->sort(list); |
851 list->cl->sort(list); |
| 821 } |
852 } |
| 822 |
853 |
| 823 /** |
854 /** |
| 824 * Reverses the order of the items. |
855 * Reverses the order of the items. |
| 825 * |
856 * |
| 826 * @param list the list |
857 * @param list the list |
| 827 */ |
858 */ |
| 828 __attribute__((__nonnull__)) |
859 cx_attr_nonnull |
| 829 static inline void cxListReverse(CxList *list) { |
860 static inline void cxListReverse(CxList *list) { |
| 830 list->cl->reverse(list); |
861 list->cl->reverse(list); |
| 831 } |
862 } |
| 832 |
863 |
| 833 /** |
864 /** |
| 855 * |
887 * |
| 856 * This function itself is a destructor function for the CxList. |
888 * This function itself is a destructor function for the CxList. |
| 857 * |
889 * |
| 858 * @param list the list which shall be destroyed |
890 * @param list the list which shall be destroyed |
| 859 */ |
891 */ |
| 860 __attribute__((__nonnull__)) |
892 static inline void cxListDestroy(CxList *list) { |
| 861 void cxListDestroy(CxList *list); |
893 if (list == NULL) return; |
| |
894 list->cl->destructor(list); |
| |
895 } |
| 862 |
896 |
| 863 /** |
897 /** |
| 864 * A shared instance of an empty list. |
898 * A shared instance of an empty list. |
| 865 * |
899 * |
| 866 * Writing to that list is undefined. |
900 * Writing to that list is not allowed. |
| 867 */ |
901 */ |
| 868 extern CxList * const cxEmptyList; |
902 extern CxList *const cxEmptyList; |
| 869 |
903 |
| 870 |
904 |
| 871 #ifdef __cplusplus |
905 #ifdef __cplusplus |
| 872 } // extern "C" |
906 } // extern "C" |
| 873 #endif |
907 #endif |