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 |