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 * Implementors SHOULD see to performant implementations for corner cases. |
|
84 */ |
83 */ |
85 int (*insert_element)( |
84 int (*insert_element)( |
86 struct cx_list_s *list, |
85 struct cx_list_s *list, |
87 size_t index, |
86 size_t index, |
88 const void *data |
87 const void *data |
89 ); |
88 ); |
90 |
89 |
91 /** |
90 /** |
92 * Member function for inserting multiple elements. |
91 * Member function for inserting multiple elements. |
93 * Implementors SHOULD see to performant implementations for corner cases. |
|
94 * |
92 * |
95 * @see cx_list_default_insert_array() |
93 * @see cx_list_default_insert_array() |
96 */ |
94 */ |
97 size_t (*insert_array)( |
95 size_t (*insert_array)( |
98 struct cx_list_s *list, |
96 struct cx_list_s *list, |
275 * @retval zero success |
276 * @retval zero success |
276 * @retval non-zero when indices are out of bounds or memory |
277 * @retval non-zero when indices are out of bounds or memory |
277 * allocation for the temporary buffer fails |
278 * allocation for the temporary buffer fails |
278 */ |
279 */ |
279 cx_attr_nonnull |
280 cx_attr_nonnull |
|
281 cx_attr_export |
280 int cx_list_default_swap(struct cx_list_s *list, size_t i, size_t j); |
282 int cx_list_default_swap(struct cx_list_s *list, size_t i, size_t j); |
281 |
283 |
282 /** |
284 /** |
|
285 * Initializes a list struct. |
|
286 * |
|
287 * Only use this function if you are creating your own list implementation. |
|
288 * The purpose of this function is to be called in the initialization code |
|
289 * of your list, to set certain members correctly. |
|
290 * |
|
291 * This is particularly important when you want your list to support |
|
292 * #CX_STORE_POINTERS as @p elem_size. This function will wrap the list |
|
293 * class accordingly and make sure that you can implement your list as if |
|
294 * it was only storing objects and the wrapper will automatically enable |
|
295 * the feature of storing pointers. |
|
296 * |
|
297 * @par Example |
|
298 * |
|
299 * @code |
|
300 * CxList *myCustomListCreate( |
|
301 * const CxAllocator *allocator, |
|
302 * cx_compare_func comparator, |
|
303 * size_t elem_size |
|
304 * ) { |
|
305 * if (allocator == NULL) { |
|
306 * allocator = cxDefaultAllocator; |
|
307 * } |
|
308 * |
|
309 * MyCustomList *list = cxCalloc(allocator, 1, sizeof(MyCustomList)); |
|
310 * if (list == NULL) return NULL; |
|
311 * |
|
312 * // initialize |
|
313 * cx_list_init((CxList*)list, &my_custom_list_class, |
|
314 * allocator, comparator, elem_size); |
|
315 * |
|
316 * // ... some more custom stuff ... |
|
317 * |
|
318 * return (CxList *) list; |
|
319 * } |
|
320 * @endcode |
|
321 * |
|
322 * @param list the list to initialize |
|
323 * @param cl the list class |
|
324 * @param allocator the allocator for the elements |
|
325 * @param comparator a compare function for the elements |
|
326 * @param elem_size the size of one element |
|
327 */ |
|
328 cx_attr_nonnull_arg(1, 2, 3) |
|
329 cx_attr_export |
|
330 void cx_list_init( |
|
331 struct cx_list_s *list, |
|
332 struct cx_list_class_s *cl, |
|
333 const struct cx_allocator_s *allocator, |
|
334 cx_compare_func comparator, |
|
335 size_t elem_size |
|
336 ); |
|
337 |
|
338 /** |
283 * Common type for all list implementations. |
339 * Common type for all list implementations. |
284 */ |
340 */ |
285 typedef struct cx_list_s CxList; |
341 typedef struct cx_list_s CxList; |
286 |
|
287 /** |
|
288 * Advises the list to store copies of the objects (default mode of operation). |
|
289 * |
|
290 * Retrieving objects from this list will yield pointers to the copies stored |
|
291 * within this list. |
|
292 * |
|
293 * @param list the list |
|
294 * @see cxListStorePointers() |
|
295 */ |
|
296 cx_attr_nonnull |
|
297 void cxListStoreObjects(CxList *list); |
|
298 |
|
299 /** |
|
300 * Advises the list to only store pointers to the objects. |
|
301 * |
|
302 * Retrieving objects from this list will yield the original pointers stored. |
|
303 * |
|
304 * @note This function forcibly sets the element size to the size of a pointer. |
|
305 * Invoking this function on a non-empty list that already stores copies of |
|
306 * objects is undefined. |
|
307 * |
|
308 * @param list the list |
|
309 * @see cxListStoreObjects() |
|
310 */ |
|
311 cx_attr_nonnull |
|
312 void cxListStorePointers(CxList *list); |
|
313 |
|
314 /** |
|
315 * Returns true, if this list is storing pointers instead of the actual data. |
|
316 * |
|
317 * @param list |
|
318 * @return true, if this list is storing pointers |
|
319 * @see cxListStorePointers() |
|
320 */ |
|
321 cx_attr_nonnull |
|
322 static inline bool cxListIsStoringPointers(const CxList *list) { |
|
323 return list->collection.store_pointer; |
|
324 } |
|
325 |
342 |
326 /** |
343 /** |
327 * Returns the number of elements currently stored in the list. |
344 * Returns the number of elements currently stored in the list. |
328 * |
345 * |
329 * @param list the list |
346 * @param list the list |
393 static inline int cxListInsert( |
412 static inline int cxListInsert( |
394 CxList *list, |
413 CxList *list, |
395 size_t index, |
414 size_t index, |
396 const void *elem |
415 const void *elem |
397 ) { |
416 ) { |
|
417 list->collection.sorted = false; |
398 return list->cl->insert_element(list, index, elem); |
418 return list->cl->insert_element(list, index, elem); |
399 } |
419 } |
400 |
420 |
401 /** |
421 /** |
402 * Inserts an item into a sorted list. |
422 * Inserts an item into a sorted list. |
|
423 * |
|
424 * If the list is not sorted already, the behavior is undefined. |
403 * |
425 * |
404 * @param list the list |
426 * @param list the list |
405 * @param elem a pointer to the element to add |
427 * @param elem a pointer to the element to add |
406 * @retval zero success |
428 * @retval zero success |
407 * @retval non-zero memory allocation failure |
429 * @retval non-zero memory allocation failure |
453 * If there is not enough memory to add all elements, the returned value is |
477 * If there is not enough memory to add all elements, the returned value is |
454 * less than @p n. |
478 * less than @p n. |
455 * |
479 * |
456 * If this list is storing pointers instead of objects @p array is expected to |
480 * If this list is storing pointers instead of objects @p array is expected to |
457 * be an array of pointers. |
481 * be an array of pointers. |
|
482 * |
|
483 * If the list is not sorted already, the behavior is undefined. |
458 * |
484 * |
459 * @param list the list |
485 * @param list the list |
460 * @param array a pointer to the elements to add |
486 * @param array a pointer to the elements to add |
461 * @param n the number of elements to add |
487 * @param n the number of elements to add |
462 * @return the number of added elements |
488 * @return the number of added elements |
803 * |
838 * |
804 * Determining equality is performed by the list's comparator function. |
839 * Determining equality is performed by the list's comparator function. |
805 * |
840 * |
806 * @param list the list |
841 * @param list the list |
807 * @param elem the element to find |
842 * @param elem the element to find |
808 * @return the index of the element or a negative |
843 * @return the index of the element or the size of the list when the element is not found |
809 * value when the element is not found |
844 * @see cxListIndexValid() |
810 */ |
845 */ |
811 cx_attr_nonnull |
846 cx_attr_nonnull |
812 cx_attr_nodiscard |
847 cx_attr_nodiscard |
813 static inline ssize_t cxListFind( |
848 static inline size_t cxListFind( |
814 const CxList *list, |
849 const CxList *list, |
815 const void *elem |
850 const void *elem |
816 ) { |
851 ) { |
817 return list->cl->find_remove((CxList*)list, elem, false); |
852 return list->cl->find_remove((CxList*)list, elem, false); |
818 } |
853 } |
819 |
854 |
820 /** |
855 /** |
|
856 * Checks if the specified index is within bounds. |
|
857 * |
|
858 * @param list the list |
|
859 * @param index the index |
|
860 * @retval true if the index is within bounds |
|
861 * @retval false if the index is out of bounds |
|
862 */ |
|
863 cx_attr_nonnull |
|
864 cx_attr_nodiscard |
|
865 static inline bool cxListIndexValid(const CxList *list, size_t index) { |
|
866 return index < list->collection.size; |
|
867 } |
|
868 |
|
869 /** |
821 * Removes and returns the index of the first element that equals @p elem. |
870 * Removes and returns the index of the first element that equals @p elem. |
822 * |
871 * |
823 * Determining equality is performed by the list's comparator function. |
872 * Determining equality is performed by the list's comparator function. |
824 * |
873 * |
825 * @param list the list |
874 * @param list the list |
826 * @param elem the element to find and remove |
875 * @param elem the element to find and remove |
827 * @return the index of the now removed element or a negative |
876 * @return the index of the now removed element or the list size |
828 * value when the element is not found or could not be removed |
877 * when the element is not found or could not be removed |
829 */ |
878 * @see cxListIndexValid() |
830 cx_attr_nonnull |
879 */ |
831 static inline ssize_t cxListFindRemove( |
880 cx_attr_nonnull |
|
881 static inline size_t cxListFindRemove( |
832 CxList *list, |
882 CxList *list, |
833 const void *elem |
883 const void *elem |
834 ) { |
884 ) { |
835 return list->cl->find_remove(list, elem, true); |
885 return list->cl->find_remove(list, elem, true); |
836 } |
886 } |
843 * @param list the list |
893 * @param list the list |
844 */ |
894 */ |
845 cx_attr_nonnull |
895 cx_attr_nonnull |
846 static inline void cxListSort(CxList *list) { |
896 static inline void cxListSort(CxList *list) { |
847 list->cl->sort(list); |
897 list->cl->sort(list); |
|
898 list->collection.sorted = true; |
848 } |
899 } |
849 |
900 |
850 /** |
901 /** |
851 * Reverses the order of the items. |
902 * Reverses the order of the items. |
852 * |
903 * |
853 * @param list the list |
904 * @param list the list |
854 */ |
905 */ |
855 cx_attr_nonnull |
906 cx_attr_nonnull |
856 static inline void cxListReverse(CxList *list) { |
907 static inline void cxListReverse(CxList *list) { |
|
908 // still sorted, but not according to the cmp_func |
|
909 list->collection.sorted = false; |
857 list->cl->reverse(list); |
910 list->cl->reverse(list); |
858 } |
911 } |
859 |
912 |
860 /** |
913 /** |
861 * Compares a list to another list of the same type. |
914 * Compares a list to another list of the same type. |
883 * |
937 * |
884 * Also calls the content destructor functions for each element, if specified. |
938 * Also calls the content destructor functions for each element, if specified. |
885 * |
939 * |
886 * @param list the list which shall be freed |
940 * @param list the list which shall be freed |
887 */ |
941 */ |
|
942 cx_attr_export |
888 void cxListFree(CxList *list); |
943 void cxListFree(CxList *list); |
889 |
944 |
890 /** |
945 /** |
891 * A shared instance of an empty list. |
946 * A shared instance of an empty list. |
892 * |
947 * |
893 * Writing to that list is not allowed. |
948 * Writing to that list is not allowed. |
894 * |
949 * |
895 * You can use this is a placeholder for initializing CxList pointers |
950 * You can use this is a placeholder for initializing CxList pointers |
896 * for which you do not want to reserve memory right from the beginning. |
951 * for which you do not want to reserve memory right from the beginning. |
897 */ |
952 */ |
|
953 cx_attr_export |
898 extern CxList *const cxEmptyList; |
954 extern CxList *const cxEmptyList; |
899 |
955 |
900 |
956 |
901 #ifdef __cplusplus |
957 #ifdef __cplusplus |
902 } // extern "C" |
958 } // extern "C" |