| 83 /** |
81 /** |
| 84 * Member function for inserting a single element. |
82 * Member function for inserting a single element. |
| 85 * 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. |
| 86 * Returns a pointer to the allocated memory or @c NULL if allocation fails. |
84 * Returns a pointer to the allocated memory or @c NULL if allocation fails. |
| 87 */ |
85 */ |
| 88 void *(*insert_element)( |
86 void *(*insert_element)(struct cx_list_s *list, size_t index, const void *data); |
| 89 struct cx_list_s *list, |
|
| 90 size_t index, |
|
| 91 const void *data |
|
| 92 ); |
|
| 93 |
87 |
| 94 /** |
88 /** |
| 95 * Member function for inserting multiple elements. |
89 * Member function for inserting multiple elements. |
| 96 * |
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 * |
| 97 * @see cx_list_default_insert_array() |
94 * @see cx_list_default_insert_array() |
| 98 */ |
95 */ |
| 99 size_t (*insert_array)( |
96 size_t (*insert_array)(struct cx_list_s *list, size_t index, const void *data, size_t n); |
| 100 struct cx_list_s *list, |
|
| 101 size_t index, |
|
| 102 const void *data, |
|
| 103 size_t n |
|
| 104 ); |
|
| 105 |
97 |
| 106 /** |
98 /** |
| 107 * 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. |
| 108 * |
101 * |
| 109 * @see cx_list_default_insert_sorted() |
102 * @see cx_list_default_insert_sorted() |
| 110 */ |
103 */ |
| 111 size_t (*insert_sorted)( |
104 size_t (*insert_sorted)(struct cx_list_s *list, const void *sorted_data, size_t n); |
| 112 struct cx_list_s *list, |
|
| 113 const void *sorted_data, |
|
| 114 size_t n |
|
| 115 ); |
|
| 116 |
105 |
| 117 /** |
106 /** |
| 118 * Member function for inserting multiple elements if they do not exist. |
107 * Member function for inserting multiple elements if they do not exist. |
| 119 * |
108 * Implementations shall return the number of successfully processed elements |
| |
109 * (including those which were not added because they are already contained). |
| 120 * @see cx_list_default_insert_unique() |
110 * @see cx_list_default_insert_unique() |
| 121 */ |
111 */ |
| 122 size_t (*insert_unique)( |
112 size_t (*insert_unique)(struct cx_list_s *list, const void *sorted_data, size_t n); |
| 123 struct cx_list_s *list, |
|
| 124 const void *sorted_data, |
|
| 125 size_t n |
|
| 126 ); |
|
| 127 |
113 |
| 128 /** |
114 /** |
| 129 * Member function for inserting an element relative to an iterator position. |
115 * Member function for inserting an element relative to an iterator position. |
| 130 */ |
116 */ |
| 131 int (*insert_iter)( |
117 int (*insert_iter)(struct cx_iterator_s *iter, const void *elem, int prepend); |
| 132 struct cx_iterator_s *iter, |
|
| 133 const void *elem, |
|
| 134 int prepend |
|
| 135 ); |
|
| 136 |
118 |
| 137 /** |
119 /** |
| 138 * Member function for removing elements. |
120 * Member function for removing elements. |
| 139 * |
121 * |
| 140 * 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 |
| 142 * When @p targetbuf is not set, the destructors SHALL be invoked. |
124 * When @p targetbuf is not set, the destructors SHALL be invoked. |
| 143 * |
125 * |
| 144 * The function SHALL return the actual number of elements removed, which |
126 * The function SHALL return the actual number of elements removed, which |
| 145 * might be lower than @p num when going out of bounds. |
127 * might be lower than @p num when going out of bounds. |
| 146 */ |
128 */ |
| 147 size_t (*remove)( |
129 size_t (*remove)(struct cx_list_s *list, size_t index, size_t num, void *targetbuf); |
| 148 struct cx_list_s *list, |
|
| 149 size_t index, |
|
| 150 size_t num, |
|
| 151 void *targetbuf |
|
| 152 ); |
|
| 153 |
130 |
| 154 /** |
131 /** |
| 155 * Member function for removing all elements. |
132 * Member function for removing all elements. |
| 156 */ |
133 */ |
| 157 void (*clear)(struct cx_list_s *list); |
134 void (*clear)(struct cx_list_s *list); |
| 159 /** |
136 /** |
| 160 * Member function for swapping two elements. |
137 * Member function for swapping two elements. |
| 161 * |
138 * |
| 162 * @see cx_list_default_swap() |
139 * @see cx_list_default_swap() |
| 163 */ |
140 */ |
| 164 int (*swap)( |
141 int (*swap)(struct cx_list_s *list, size_t i, size_t j); |
| 165 struct cx_list_s *list, |
|
| 166 size_t i, |
|
| 167 size_t j |
|
| 168 ); |
|
| 169 |
142 |
| 170 /** |
143 /** |
| 171 * Member function for element lookup. |
144 * Member function for element lookup. |
| 172 */ |
145 */ |
| 173 void *(*at)( |
146 void *(*at)(const struct cx_list_s *list, size_t index); |
| 174 const struct cx_list_s *list, |
|
| 175 size_t index |
|
| 176 ); |
|
| 177 |
147 |
| 178 /** |
148 /** |
| 179 * Member function for finding and optionally removing an element. |
149 * Member function for finding and optionally removing an element. |
| 180 */ |
150 */ |
| 181 size_t (*find_remove)( |
151 size_t (*find_remove)(struct cx_list_s *list, const void *elem, bool remove); |
| 182 struct cx_list_s *list, |
|
| 183 const void *elem, |
|
| 184 bool remove |
|
| 185 ); |
|
| 186 |
152 |
| 187 /** |
153 /** |
| 188 * Member function for sorting the list. |
154 * Member function for sorting the list. |
| 189 * |
155 * |
| 190 * @see cx_list_default_sort() |
156 * @see cx_list_default_sort() |
| 194 /** |
160 /** |
| 195 * Optional member function for comparing this list |
161 * Optional member function for comparing this list |
| 196 * to another list of the same type. |
162 * to another list of the same type. |
| 197 * If set to @c NULL, the comparison won't be optimized. |
163 * If set to @c NULL, the comparison won't be optimized. |
| 198 */ |
164 */ |
| 199 int (*compare)( |
165 int (*compare)(const struct cx_list_s *list, const struct cx_list_s *other); |
| 200 const struct cx_list_s *list, |
|
| 201 const struct cx_list_s *other |
|
| 202 ); |
|
| 203 |
166 |
| 204 /** |
167 /** |
| 205 * Member function for reversing the order of the items. |
168 * Member function for reversing the order of the items. |
| 206 */ |
169 */ |
| 207 void (*reverse)(struct cx_list_s *list); |
170 void (*reverse)(struct cx_list_s *list); |
| 208 |
171 |
| 209 /** |
172 /** |
| 210 * Member function for returning an iterator pointing to the specified index. |
173 * Member function for returning an iterator pointing to the specified index. |
| 211 */ |
174 */ |
| 212 struct cx_iterator_s (*iterator)( |
175 struct cx_iterator_s (*iterator)(const struct cx_list_s *list, size_t index, bool backward); |
| 213 const struct cx_list_s *list, |
|
| 214 size_t index, |
|
| 215 bool backward |
|
| 216 ); |
|
| 217 }; |
176 }; |
| 218 |
177 |
| 219 /** |
178 /** |
| 220 * Common type for all list implementations. |
179 * Common type for all list implementations. |
| 221 */ |
180 */ |
| 245 * @param data a pointer to the array of data to insert |
203 * @param data a pointer to the array of data to insert |
| 246 * @param n the number of elements to insert |
204 * @param n the number of elements to insert |
| 247 * @return the number of elements actually inserted |
205 * @return the number of elements actually inserted |
| 248 */ |
206 */ |
| 249 cx_attr_nonnull |
207 cx_attr_nonnull |
| 250 cx_attr_export |
208 CX_EXPORT size_t cx_list_default_insert_array(struct cx_list_s *list, |
| 251 size_t cx_list_default_insert_array( |
209 size_t index, const void *data, size_t n); |
| 252 struct cx_list_s *list, |
|
| 253 size_t index, |
|
| 254 const void *data, |
|
| 255 size_t n |
|
| 256 ); |
|
| 257 |
210 |
| 258 /** |
211 /** |
| 259 * Default implementation of a sorted insert. |
212 * Default implementation of a sorted insert. |
| 260 * |
213 * |
| 261 * This function uses the array insert function to insert consecutive groups |
214 * This function uses the array insert function to insert consecutive groups |
| 270 * @param sorted_data a pointer to the array of pre-sorted data to insert |
223 * @param sorted_data a pointer to the array of pre-sorted data to insert |
| 271 * @param n the number of elements to insert |
224 * @param n the number of elements to insert |
| 272 * @return the number of elements actually inserted |
225 * @return the number of elements actually inserted |
| 273 */ |
226 */ |
| 274 cx_attr_nonnull |
227 cx_attr_nonnull |
| 275 cx_attr_export |
228 CX_EXPORT size_t cx_list_default_insert_sorted(struct cx_list_s *list, |
| 276 size_t cx_list_default_insert_sorted( |
229 const void *sorted_data, size_t n); |
| 277 struct cx_list_s *list, |
|
| 278 const void *sorted_data, |
|
| 279 size_t n |
|
| 280 ); |
|
| 281 |
230 |
| 282 /** |
231 /** |
| 283 * Default implementation of an array insert where only elements are inserted when they don't exist in the list. |
232 * Default implementation of an array insert where only elements are inserted when they don't exist in the list. |
| 284 * |
233 * |
| 285 * This function is similar to cx_list_default_insert_sorted(), except it skips elements that are already in the list. |
234 * This function is similar to cx_list_default_insert_sorted(), except it skips elements that are already in the list. |
| 294 * @param sorted_data a pointer to the array of pre-sorted data to insert |
243 * @param sorted_data a pointer to the array of pre-sorted data to insert |
| 295 * @param n the number of elements to insert |
244 * @param n the number of elements to insert |
| 296 * @return the number of elements from the @p sorted_data that are definitely present in the list after this call |
245 * @return the number of elements from the @p sorted_data that are definitely present in the list after this call |
| 297 */ |
246 */ |
| 298 cx_attr_nonnull |
247 cx_attr_nonnull |
| 299 cx_attr_export |
248 CX_EXPORT size_t cx_list_default_insert_unique(struct cx_list_s *list, |
| 300 size_t cx_list_default_insert_unique( |
249 const void *sorted_data, size_t n); |
| 301 struct cx_list_s *list, |
|
| 302 const void *sorted_data, |
|
| 303 size_t n |
|
| 304 ); |
|
| 305 |
250 |
| 306 /** |
251 /** |
| 307 * Default unoptimized sort implementation. |
252 * Default unoptimized sort implementation. |
| 308 * |
253 * |
| 309 * This function will copy all data to an array, sort the array with standard |
254 * This function will copy all data to an array, sort the array with standard |
| 378 * @param allocator the allocator for the elements |
321 * @param allocator the allocator for the elements |
| 379 * @param comparator a compare function for the elements |
322 * @param comparator a compare function for the elements |
| 380 * @param elem_size the size of one element |
323 * @param elem_size the size of one element |
| 381 */ |
324 */ |
| 382 cx_attr_nonnull_arg(1, 2, 3) |
325 cx_attr_nonnull_arg(1, 2, 3) |
| 383 cx_attr_export |
326 CX_EXPORT void cx_list_init(struct cx_list_s *list, |
| 384 void cx_list_init( |
327 struct cx_list_class_s *cl, const struct cx_allocator_s *allocator, |
| 385 struct cx_list_s *list, |
328 cx_compare_func comparator, size_t elem_size); |
| 386 struct cx_list_class_s *cl, |
|
| 387 const struct cx_allocator_s *allocator, |
|
| 388 cx_compare_func comparator, |
|
| 389 size_t elem_size |
|
| 390 ); |
|
| 391 |
329 |
| 392 /** |
330 /** |
| 393 * Returns the number of elements currently stored in the list. |
331 * Returns the number of elements currently stored in the list. |
| 394 * |
332 * |
| 395 * @param list the list |
333 * @param list the list |
| 396 * @return the number of currently stored elements |
334 * @return the number of currently stored elements |
| 397 */ |
335 */ |
| 398 cx_attr_nonnull |
336 cx_attr_nonnull |
| 399 static inline size_t cxListSize(const CxList *list) { |
337 CX_EXPORT size_t cxListSize(const CxList *list); |
| 400 return list->collection.size; |
|
| 401 } |
|
| 402 |
338 |
| 403 /** |
339 /** |
| 404 * Adds an item to the end of the list. |
340 * Adds an item to the end of the list. |
| 405 * |
341 * |
| 406 * @param list the list |
342 * @param list the list |
| 432 * |
362 * |
| 433 * @param list the list |
363 * @param list the list |
| 434 * @param array a pointer to the elements to add |
364 * @param array a pointer to the elements to add |
| 435 * @param n the number of elements to add |
365 * @param n the number of elements to add |
| 436 * @return the number of added elements |
366 * @return the number of added elements |
| 437 */ |
367 * @see cxListEmplaceArray() |
| 438 cx_attr_nonnull |
368 */ |
| 439 static inline size_t cxListAddArray( |
369 cx_attr_nonnull |
| 440 CxList *list, |
370 CX_EXPORT size_t cxListAddArray(CxList *list, const void *array, size_t n); |
| 441 const void *array, |
|
| 442 size_t n |
|
| 443 ) { |
|
| 444 list->collection.sorted = false; |
|
| 445 return list->cl->insert_array(list, list->collection.size, array, n); |
|
| 446 } |
|
| 447 |
371 |
| 448 /** |
372 /** |
| 449 * Inserts an item at the specified index. |
373 * Inserts an item at the specified index. |
| 450 * |
374 * |
| 451 * If the @p index equals the list @c size, this is effectively cxListAdd(). |
375 * If the @p index equals the list @c size, this is effectively cxListAdd(). |
| 458 * @see cxListInsertAfter() |
382 * @see cxListInsertAfter() |
| 459 * @see cxListInsertBefore() |
383 * @see cxListInsertBefore() |
| 460 * @see cxListEmplaceAt() |
384 * @see cxListEmplaceAt() |
| 461 */ |
385 */ |
| 462 cx_attr_nonnull |
386 cx_attr_nonnull |
| 463 static inline int cxListInsert( |
387 CX_EXPORT int cxListInsert(CxList *list, size_t index, const void *elem); |
| 464 CxList *list, |
|
| 465 size_t index, |
|
| 466 const void *elem |
|
| 467 ) { |
|
| 468 list->collection.sorted = false; |
|
| 469 return list->cl->insert_element(list, index, elem) == NULL; |
|
| 470 } |
|
| 471 |
388 |
| 472 /** |
389 /** |
| 473 * Allocates memory for an element at the specified index and returns a pointer to that memory. |
390 * Allocates memory for an element at the specified index and returns a pointer to that memory. |
| 474 * |
391 * |
| 475 * @remark When the list is storing pointers, this will return a @c void**. |
392 * @remark When the list is storing pointers, this will return a @c void**. |
| 476 * |
393 * |
| 477 * @param list the list |
394 * @param list the list |
| 478 * @param index the index where to emplace the element |
395 * @param index the index where to emplace the element |
| 479 * @return a pointer to the allocated memory; @c NULL when the operation fails, or the index is out-of-bounds |
396 * @return a pointer to the allocated memory; @c NULL when the operation fails, or the index is out-of-bounds |
| 480 * @see cxListEmplace() |
397 * @see cxListEmplace() |
| |
398 * @see cxListEmplaceArrayAt() |
| 481 * @see cxListInsert() |
399 * @see cxListInsert() |
| 482 */ |
400 */ |
| 483 cx_attr_nonnull |
401 cx_attr_nonnull |
| 484 static inline void *cxListEmplaceAt(CxList *list, size_t index) { |
402 CX_EXPORT void *cxListEmplaceAt(CxList *list, size_t index); |
| 485 list->collection.sorted = false; |
|
| 486 return list->cl->insert_element(list, index, NULL); |
|
| 487 } |
|
| 488 |
|
| 489 |
403 |
| 490 /** |
404 /** |
| 491 * Allocates memory for an element at the end of the list and returns a pointer to that memory. |
405 * Allocates memory for an element at the end of the list and returns a pointer to that memory. |
| 492 * |
406 * |
| 493 * @remark When the list is storing pointers, this will return a @c void**. |
407 * @remark When the list is storing pointers, this will return a @c void**. |
| 496 * @return a pointer to the allocated memory; @c NULL when the operation fails, or the index is out-of-bounds |
410 * @return a pointer to the allocated memory; @c NULL when the operation fails, or the index is out-of-bounds |
| 497 * @see cxListEmplaceAt() |
411 * @see cxListEmplaceAt() |
| 498 * @see cxListAdd() |
412 * @see cxListAdd() |
| 499 */ |
413 */ |
| 500 cx_attr_nonnull |
414 cx_attr_nonnull |
| 501 static inline void *cxListEmplace(CxList *list) { |
415 CX_EXPORT void *cxListEmplace(CxList *list); |
| 502 list->collection.sorted = false; |
416 |
| 503 return list->cl->insert_element(list, list->collection.size, NULL); |
417 /** |
| 504 } |
418 * Allocates memory for multiple elements and returns an iterator. |
| |
419 * |
| |
420 * The iterator will only iterate over the successfully allocated elements. |
| |
421 * The @c elem_count attribute is set to that number, and the @c index attribute |
| |
422 * will range from zero to @c elem_count minus one. |
| |
423 * |
| |
424 * @remark When the list is storing pointers, the iterator will iterate over |
| |
425 * the @c void** elements. |
| |
426 * |
| |
427 * @param list the list |
| |
428 * @param index the index where to insert the new data |
| |
429 * @param n the number of elements for which to allocate the memory |
| |
430 * @return an iterator, iterating over the new memory |
| |
431 * @see cxListEmplaceAt() |
| |
432 * @see cxListInsertArray() |
| |
433 */ |
| |
434 cx_attr_nonnull |
| |
435 CX_EXPORT CxIterator cxListEmplaceArrayAt(CxList *list, size_t index, size_t n); |
| |
436 |
| |
437 /** |
| |
438 * Allocates memory for multiple elements and returns an iterator. |
| |
439 * |
| |
440 * The iterator will only iterate over the successfully allocated elements. |
| |
441 * The @c elem_count attribute is set to that number, and the @c index attribute |
| |
442 * will range from zero to @c elem_count minus one. |
| |
443 * |
| |
444 * @remark When the list is storing pointers, the iterator will iterate over |
| |
445 * the @c void** elements. |
| |
446 * |
| |
447 * @param list the list |
| |
448 * @param n the number of elements for which to allocate the memory |
| |
449 * @return an iterator, iterating over the new memory |
| |
450 * @see cxListEmplace() |
| |
451 * @see cxListAddArray() |
| |
452 */ |
| |
453 cx_attr_nonnull |
| |
454 CX_EXPORT CxIterator cxListEmplaceArray(CxList *list, size_t n); |
| 505 |
455 |
| 506 /** |
456 /** |
| 507 * Inserts an item into a sorted list. |
457 * Inserts an item into a sorted list. |
| 508 * |
458 * |
| 509 * If the list is not sorted already, the behavior is undefined. |
459 * If the list is not sorted already, the behavior is undefined. |
| 512 * @param elem a pointer to the element to add |
462 * @param elem a pointer to the element to add |
| 513 * @retval zero success |
463 * @retval zero success |
| 514 * @retval non-zero memory allocation failure |
464 * @retval non-zero memory allocation failure |
| 515 */ |
465 */ |
| 516 cx_attr_nonnull |
466 cx_attr_nonnull |
| 517 static inline int cxListInsertSorted( |
467 CX_EXPORT int cxListInsertSorted(CxList *list, const void *elem); |
| 518 CxList *list, |
468 |
| 519 const void *elem |
469 /** |
| 520 ) { |
470 * Inserts an item into a list if it does not exist. |
| 521 assert(list->collection.sorted || list->collection.size == 0); |
471 * |
| 522 list->collection.sorted = true; |
472 * If the list is not sorted already, this function will check all elements |
| 523 const void *data = list->collection.store_pointer ? &elem : elem; |
473 * and append the new element when it was not found. |
| 524 return list->cl->insert_sorted(list, data, 1) == 0; |
474 * It is strongly recommended to use this function only on sorted lists, where |
| 525 } |
475 * the element, if it is not contained, is inserted at the correct position. |
| 526 |
|
| 527 /** |
|
| 528 * Inserts an item into a sorted list if it does not exist. |
|
| 529 * |
|
| 530 * If the list is not sorted already, the behavior is undefined. |
|
| 531 * |
476 * |
| 532 * @param list the list |
477 * @param list the list |
| 533 * @param elem a pointer to the element to add |
478 * @param elem a pointer to the element to add |
| 534 * @retval zero success (also when the element was already in the list) |
479 * @retval zero success (also when the element was already in the list) |
| 535 * @retval non-zero memory allocation failure |
480 * @retval non-zero memory allocation failure |
| 536 */ |
481 */ |
| 537 cx_attr_nonnull |
482 cx_attr_nonnull |
| 538 static inline int cxListInsertUnique( |
483 CX_EXPORT int cxListInsertUnique(CxList *list, const void *elem); |
| 539 CxList *list, |
|
| 540 const void *elem |
|
| 541 ) { |
|
| 542 assert(list->collection.sorted || list->collection.size == 0); |
|
| 543 list->collection.sorted = true; |
|
| 544 const void *data = list->collection.store_pointer ? &elem : elem; |
|
| 545 return list->cl->insert_unique(list, data, 1) == 0; |
|
| 546 } |
|
| 547 |
484 |
| 548 /** |
485 /** |
| 549 * Inserts multiple items to the list at the specified index. |
486 * Inserts multiple items to the list at the specified index. |
| 550 * If the @p index equals the list size, this is effectively cxListAddArray(). |
487 * If the @p index equals the list size, this is effectively cxListAddArray(). |
| 551 * |
488 * |
| 561 * @param list the list |
498 * @param list the list |
| 562 * @param index the index where to add the elements |
499 * @param index the index where to add the elements |
| 563 * @param array a pointer to the elements to add |
500 * @param array a pointer to the elements to add |
| 564 * @param n the number of elements to add |
501 * @param n the number of elements to add |
| 565 * @return the number of added elements |
502 * @return the number of added elements |
| 566 */ |
503 * @see cxListEmplaceArrayAt() |
| 567 cx_attr_nonnull |
504 */ |
| 568 static inline size_t cxListInsertArray( |
505 cx_attr_nonnull |
| 569 CxList *list, |
506 CX_EXPORT size_t cxListInsertArray(CxList *list, size_t index, const void *array, size_t n); |
| 570 size_t index, |
|
| 571 const void *array, |
|
| 572 size_t n |
|
| 573 ) { |
|
| 574 list->collection.sorted = false; |
|
| 575 return list->cl->insert_array(list, index, array, n); |
|
| 576 } |
|
| 577 |
507 |
| 578 /** |
508 /** |
| 579 * Inserts a sorted array into a sorted list. |
509 * Inserts a sorted array into a sorted list. |
| 580 * |
510 * |
| 581 * This method is usually more efficient than inserting each element separately |
511 * This method is usually more efficient than inserting each element separately |
| 593 * @param array a pointer to the elements to add |
523 * @param array a pointer to the elements to add |
| 594 * @param n the number of elements to add |
524 * @param n the number of elements to add |
| 595 * @return the number of added elements |
525 * @return the number of added elements |
| 596 */ |
526 */ |
| 597 cx_attr_nonnull |
527 cx_attr_nonnull |
| 598 static inline size_t cxListInsertSortedArray( |
528 CX_EXPORT size_t cxListInsertSortedArray(CxList *list, const void *array, size_t n); |
| 599 CxList *list, |
529 |
| 600 const void *array, |
530 /** |
| 601 size_t n |
531 * Inserts an array into a list, skipping duplicates. |
| 602 ) { |
532 * |
| 603 assert(list->collection.sorted || list->collection.size == 0); |
533 * The @p list does not need to be sorted (in contrast to cxListInsertSortedArray()). |
| 604 list->collection.sorted = true; |
534 * But it is strongly recommended to use this function only on sorted lists, |
| 605 return list->cl->insert_sorted(list, array, n); |
535 * because otherwise it will fall back to an inefficient algorithm which inserts |
| 606 } |
536 * all elements one by one. |
| 607 |
537 * If the @p list is not sorted, the @p array also does not need to be sorted. |
| 608 /** |
538 * But when the @p list is sorted, the @p array must also be sorted. |
| 609 * Inserts a sorted array into a sorted list, skipping duplicates. |
|
| 610 * |
539 * |
| 611 * This method is usually more efficient than inserting each element separately |
540 * This method is usually more efficient than inserting each element separately |
| 612 * because consecutive chunks of sorted data are inserted in one pass. |
541 * because consecutive chunks of sorted data are inserted in one pass. |
| 613 * |
542 * |
| 614 * If there is not enough memory to add all elements, the returned value is |
543 * If there is not enough memory to add all elements, the returned value is |
| 621 * be @p n. |
550 * be @p n. |
| 622 * |
551 * |
| 623 * If this list is storing pointers instead of objects @p array is expected to |
552 * If this list is storing pointers instead of objects @p array is expected to |
| 624 * be an array of pointers. |
553 * be an array of pointers. |
| 625 * |
554 * |
| 626 * If the list is not sorted already, the behavior is undefined. |
|
| 627 * This is also the case when the @p array is not sorted. |
|
| 628 * |
|
| 629 * @param list the list |
555 * @param list the list |
| 630 * @param array a pointer to the elements to add |
556 * @param array a pointer to the elements to add |
| 631 * @param n the number of elements to add |
557 * @param n the number of elements to add |
| 632 * @return the number of added elements |
558 * @return the number of added elements |
| 633 * |
559 * |
| 634 * @return the number of elements from the @p sorted_data that are definitely present in the list after this call |
560 * @return the number of elements from the @p sorted_data that are definitely present in the list after this call |
| 635 */ |
561 */ |
| 636 cx_attr_nonnull |
562 cx_attr_nonnull |
| 637 static inline size_t cxListInsertUniqueArray( |
563 CX_EXPORT size_t cxListInsertUniqueArray(CxList *list, const void *array, size_t n); |
| 638 CxList *list, |
|
| 639 const void *array, |
|
| 640 size_t n |
|
| 641 ) { |
|
| 642 assert(list->collection.sorted || list->collection.size == 0); |
|
| 643 list->collection.sorted = true; |
|
| 644 return list->cl->insert_unique(list, array, n); |
|
| 645 } |
|
| 646 |
564 |
| 647 /** |
565 /** |
| 648 * Inserts an element after the current location of the specified iterator. |
566 * Inserts an element after the current location of the specified iterator. |
| 649 * |
567 * |
| 650 * The used iterator remains operational, but all other active iterators should |
568 * The used iterator remains operational, but all other active iterators should |
| 659 * @retval non-zero memory allocation failure |
577 * @retval non-zero memory allocation failure |
| 660 * @see cxListInsert() |
578 * @see cxListInsert() |
| 661 * @see cxListInsertBefore() |
579 * @see cxListInsertBefore() |
| 662 */ |
580 */ |
| 663 cx_attr_nonnull |
581 cx_attr_nonnull |
| 664 static inline int cxListInsertAfter( |
582 CX_EXPORT int cxListInsertAfter(CxIterator *iter, const void *elem); |
| 665 CxIterator *iter, |
|
| 666 const void *elem |
|
| 667 ) { |
|
| 668 CxList* list = (CxList*)iter->src_handle.m; |
|
| 669 list->collection.sorted = false; |
|
| 670 return list->cl->insert_iter(iter, elem, 0); |
|
| 671 } |
|
| 672 |
583 |
| 673 /** |
584 /** |
| 674 * Inserts an element before the current location of the specified iterator. |
585 * Inserts an element before the current location of the specified iterator. |
| 675 * |
586 * |
| 676 * The used iterator remains operational, but all other active iterators should |
587 * The used iterator remains operational, but all other active iterators should |
| 685 * @retval non-zero memory allocation failure |
596 * @retval non-zero memory allocation failure |
| 686 * @see cxListInsert() |
597 * @see cxListInsert() |
| 687 * @see cxListInsertAfter() |
598 * @see cxListInsertAfter() |
| 688 */ |
599 */ |
| 689 cx_attr_nonnull |
600 cx_attr_nonnull |
| 690 static inline int cxListInsertBefore( |
601 CX_EXPORT int cxListInsertBefore(CxIterator *iter, const void *elem); |
| 691 CxIterator *iter, |
|
| 692 const void *elem |
|
| 693 ) { |
|
| 694 CxList* list = (CxList*)iter->src_handle.m; |
|
| 695 list->collection.sorted = false; |
|
| 696 return list->cl->insert_iter(iter, elem, 1); |
|
| 697 } |
|
| 698 |
602 |
| 699 /** |
603 /** |
| 700 * Removes the element at the specified index. |
604 * Removes the element at the specified index. |
| 701 * |
605 * |
| 702 * If an element destructor function is specified, it is called before |
606 * If an element destructor function is specified, it is called before |
| 726 * @param index the index of the element |
625 * @param index the index of the element |
| 727 * @param targetbuf a buffer where to copy the element |
626 * @param targetbuf a buffer where to copy the element |
| 728 * @retval zero success |
627 * @retval zero success |
| 729 * @retval non-zero index out of bounds |
628 * @retval non-zero index out of bounds |
| 730 */ |
629 */ |
| 731 cx_attr_nonnull |
630 cx_attr_nonnull cx_attr_access_w(3) |
| 732 cx_attr_access_w(3) |
631 CX_EXPORT int cxListRemoveAndGet(CxList *list, size_t index, void *targetbuf); |
| 733 static inline int cxListRemoveAndGet( |
|
| 734 CxList *list, |
|
| 735 size_t index, |
|
| 736 void *targetbuf |
|
| 737 ) { |
|
| 738 return list->cl->remove(list, index, 1, targetbuf) == 0; |
|
| 739 } |
|
| 740 |
632 |
| 741 /** |
633 /** |
| 742 * Removes and returns the first element of the list. |
634 * Removes and returns the first element of the list. |
| 743 * |
635 * |
| 744 * No destructor is called, and instead the element is copied to the |
636 * No destructor is called, and instead the element is copied to the |
| 750 * @retval zero success |
642 * @retval zero success |
| 751 * @retval non-zero the list is empty |
643 * @retval non-zero the list is empty |
| 752 * @see cxListPopFront() |
644 * @see cxListPopFront() |
| 753 * @see cxListRemoveAndGetLast() |
645 * @see cxListRemoveAndGetLast() |
| 754 */ |
646 */ |
| 755 cx_attr_nonnull |
647 cx_attr_nonnull cx_attr_access_w(2) |
| 756 cx_attr_access_w(2) |
648 CX_EXPORT int cxListRemoveAndGetFirst(CxList *list, void *targetbuf); |
| 757 static inline int cxListRemoveAndGetFirst( |
|
| 758 CxList *list, |
|
| 759 void *targetbuf |
|
| 760 ) { |
|
| 761 return list->cl->remove(list, 0, 1, targetbuf) == 0; |
|
| 762 } |
|
| 763 |
649 |
| 764 /** |
650 /** |
| 765 * Removes and returns the first element of the list. |
651 * Removes and returns the first element of the list. |
| 766 * |
652 * |
| 767 * Alias for cxListRemoveAndGetFirst(). |
653 * Alias for cxListRemoveAndGetFirst(). |
| 790 * @param list the list |
676 * @param list the list |
| 791 * @param targetbuf a buffer where to copy the element |
677 * @param targetbuf a buffer where to copy the element |
| 792 * @retval zero success |
678 * @retval zero success |
| 793 * @retval non-zero the list is empty |
679 * @retval non-zero the list is empty |
| 794 */ |
680 */ |
| 795 cx_attr_nonnull |
681 cx_attr_nonnull cx_attr_access_w(2) |
| 796 cx_attr_access_w(2) |
682 CX_EXPORT int cxListRemoveAndGetLast(CxList *list, void *targetbuf); |
| 797 static inline int cxListRemoveAndGetLast( |
|
| 798 CxList *list, |
|
| 799 void *targetbuf |
|
| 800 ) { |
|
| 801 // note: index may wrap - member function will catch that |
|
| 802 return list->cl->remove(list, list->collection.size - 1, 1, targetbuf) == 0; |
|
| 803 } |
|
| 804 |
683 |
| 805 /** |
684 /** |
| 806 * Removes and returns the last element of the list. |
685 * Removes and returns the last element of the list. |
| 807 * |
686 * |
| 808 * Alias for cxListRemoveAndGetLast(). |
687 * Alias for cxListRemoveAndGetLast(). |
| 834 * @param index the index of the element |
713 * @param index the index of the element |
| 835 * @param num the number of elements to remove |
714 * @param num the number of elements to remove |
| 836 * @return the actual number of removed elements |
715 * @return the actual number of removed elements |
| 837 */ |
716 */ |
| 838 cx_attr_nonnull |
717 cx_attr_nonnull |
| 839 static inline size_t cxListRemoveArray( |
718 CX_EXPORT size_t cxListRemoveArray(CxList *list, size_t index, size_t num); |
| 840 CxList *list, |
|
| 841 size_t index, |
|
| 842 size_t num |
|
| 843 ) { |
|
| 844 return list->cl->remove(list, index, num, NULL); |
|
| 845 } |
|
| 846 |
719 |
| 847 /** |
720 /** |
| 848 * Removes and returns multiple elements starting at the specified index. |
721 * Removes and returns multiple elements starting at the specified index. |
| 849 * |
722 * |
| 850 * No destructor is called, and instead the elements are copied to the |
723 * No destructor is called, and instead the elements are copied to the |
| 855 * @param index the index of the element |
728 * @param index the index of the element |
| 856 * @param num the number of elements to remove |
729 * @param num the number of elements to remove |
| 857 * @param targetbuf a buffer where to copy the elements |
730 * @param targetbuf a buffer where to copy the elements |
| 858 * @return the actual number of removed elements |
731 * @return the actual number of removed elements |
| 859 */ |
732 */ |
| 860 cx_attr_nonnull |
733 cx_attr_nonnull cx_attr_access_w(4) |
| 861 cx_attr_access_w(4) |
734 CX_EXPORT size_t cxListRemoveArrayAndGet(CxList *list, size_t index, size_t num, void *targetbuf); |
| 862 static inline size_t cxListRemoveArrayAndGet( |
|
| 863 CxList *list, |
|
| 864 size_t index, |
|
| 865 size_t num, |
|
| 866 void *targetbuf |
|
| 867 ) { |
|
| 868 return list->cl->remove(list, index, num, targetbuf); |
|
| 869 } |
|
| 870 |
735 |
| 871 /** |
736 /** |
| 872 * Removes all elements from this list. |
737 * Removes all elements from this list. |
| 873 * |
738 * |
| 874 * If element destructor functions are specified, they are called for each |
739 * If element destructor functions are specified, they are called for each |
| 875 * element before removing them. |
740 * element before removing them. |
| 876 * |
741 * |
| 877 * @param list the list |
742 * @param list the list |
| 878 */ |
743 */ |
| 879 cx_attr_nonnull |
744 cx_attr_nonnull |
| 880 static inline void cxListClear(CxList *list) { |
745 CX_EXPORT void cxListClear(CxList *list); |
| 881 list->cl->clear(list); |
|
| 882 list->collection.sorted = true; // empty lists are always sorted |
|
| 883 } |
|
| 884 |
746 |
| 885 /** |
747 /** |
| 886 * Swaps two items in the list. |
748 * Swaps two items in the list. |
| 887 * |
749 * |
| 888 * Implementations should only allocate temporary memory for the swap if |
750 * Implementations should only allocate temporary memory for the swap if |
| 894 * @retval zero success |
756 * @retval zero success |
| 895 * @retval non-zero one of the indices is out of bounds, |
757 * @retval non-zero one of the indices is out of bounds, |
| 896 * or the swap needed extra memory, but allocation failed |
758 * or the swap needed extra memory, but allocation failed |
| 897 */ |
759 */ |
| 898 cx_attr_nonnull |
760 cx_attr_nonnull |
| 899 static inline int cxListSwap( |
761 CX_EXPORT int cxListSwap(CxList *list, size_t i, size_t j); |
| 900 CxList *list, |
|
| 901 size_t i, |
|
| 902 size_t j |
|
| 903 ) { |
|
| 904 list->collection.sorted = false; |
|
| 905 return list->cl->swap(list, i, j); |
|
| 906 } |
|
| 907 |
762 |
| 908 /** |
763 /** |
| 909 * Returns a pointer to the element at the specified index. |
764 * Returns a pointer to the element at the specified index. |
| 910 * |
765 * |
| 911 * If the list is storing pointers, returns the pointer stored at the specified index. |
766 * If the list is storing pointers, returns the pointer stored at the specified index. |
| 913 * @param list the list |
768 * @param list the list |
| 914 * @param index the index of the element |
769 * @param index the index of the element |
| 915 * @return a pointer to the element or @c NULL if the index is out of bounds |
770 * @return a pointer to the element or @c NULL if the index is out of bounds |
| 916 */ |
771 */ |
| 917 cx_attr_nonnull |
772 cx_attr_nonnull |
| 918 static inline void *cxListAt( |
773 CX_EXPORT void *cxListAt(const CxList *list, size_t index); |
| 919 const CxList *list, |
|
| 920 size_t index |
|
| 921 ) { |
|
| 922 return list->cl->at(list, index); |
|
| 923 } |
|
| 924 |
774 |
| 925 /** |
775 /** |
| 926 * Returns a pointer to the first element. |
776 * Returns a pointer to the first element. |
| 927 * |
777 * |
| 928 * If the list is storing pointers, returns the first pointer stored in the list. |
778 * If the list is storing pointers, returns the first pointer stored in the list. |
| 929 * |
779 * |
| 930 * @param list the list |
780 * @param list the list |
| 931 * @return a pointer to the first element or @c NULL if the list is empty |
781 * @return a pointer to the first element or @c NULL if the list is empty |
| 932 */ |
782 */ |
| 933 cx_attr_nonnull |
783 cx_attr_nonnull |
| 934 static inline void *cxListFirst(const CxList *list) { |
784 CX_EXPORT void *cxListFirst(const CxList *list); |
| 935 return list->cl->at(list, 0); |
|
| 936 } |
|
| 937 |
785 |
| 938 /** |
786 /** |
| 939 * Returns a pointer to the last element. |
787 * Returns a pointer to the last element. |
| 940 * |
788 * |
| 941 * If the list is storing pointers, returns the last pointer stored in the list. |
789 * If the list is storing pointers, returns the last pointer stored in the list. |
| 942 * |
790 * |
| 943 * @param list the list |
791 * @param list the list |
| 944 * @return a pointer to the last element or @c NULL if the list is empty |
792 * @return a pointer to the last element or @c NULL if the list is empty |
| 945 */ |
793 */ |
| 946 cx_attr_nonnull |
794 cx_attr_nonnull |
| 947 static inline void *cxListLast(const CxList *list) { |
795 CX_EXPORT void *cxListLast(const CxList *list); |
| 948 return list->cl->at(list, list->collection.size - 1); |
796 |
| 949 } |
797 /** |
| 950 |
798 * Sets the element at the specified index in the list. |
| 951 /** |
799 * |
| 952 * Sets the element at the specified index in the list |
800 * This overwrites the element in-place without calling any destructor |
| |
801 * on the overwritten element. |
| 953 * |
802 * |
| 954 * @param list the list to set the element in |
803 * @param list the list to set the element in |
| 955 * @param index the index to set the element at |
804 * @param index the index to set the element at |
| 956 * @param elem element to set |
805 * @param elem element to set |
| 957 * @retval zero on success |
806 * @retval zero on success |
| 958 * @retval non-zero when index is out of bounds |
807 * @retval non-zero when index is out of bounds |
| 959 */ |
808 */ |
| 960 cx_attr_nonnull |
809 cx_attr_nonnull |
| 961 cx_attr_export |
810 CX_EXPORT int cxListSet(CxList *list, size_t index, const void *elem); |
| 962 int cxListSet( |
|
| 963 CxList *list, |
|
| 964 size_t index, |
|
| 965 const void *elem |
|
| 966 ); |
|
| 967 |
811 |
| 968 /** |
812 /** |
| 969 * Returns an iterator pointing to the item at the specified index. |
813 * Returns an iterator pointing to the item at the specified index. |
| 970 * |
814 * |
| 971 * The returned iterator is position-aware. |
815 * The returned iterator is position-aware. |
| 995 * @param list the list |
833 * @param list the list |
| 996 * @param index the index where the iterator shall point at |
834 * @param index the index where the iterator shall point at |
| 997 * @return a new iterator |
835 * @return a new iterator |
| 998 */ |
836 */ |
| 999 cx_attr_nodiscard |
837 cx_attr_nodiscard |
| 1000 static inline CxIterator cxListBackwardsIteratorAt( |
838 CX_EXPORT CxIterator cxListBackwardsIteratorAt(const CxList *list, size_t index); |
| 1001 const CxList *list, |
839 |
| 1002 size_t index |
840 /** |
| 1003 ) { |
841 * Returns an iterator pointing to the first item of the list. |
| 1004 if (list == NULL) list = cxEmptyList; |
|
| 1005 return list->cl->iterator(list, index, true); |
|
| 1006 } |
|
| 1007 |
|
| 1008 /** |
|
| 1009 * Returns a mutating iterator pointing to the item at the specified index. |
|
| 1010 * |
842 * |
| 1011 * The returned iterator is position-aware. |
843 * The returned iterator is position-aware. |
| 1012 * |
844 * |
| 1013 * If the index is out of range or @p list is @c NULL, a past-the-end iterator will be returned. |
845 * If the list is empty or @c NULL, a past-the-end iterator will be returned. |
| 1014 * |
846 * |
| 1015 * @param list the list |
847 * @param list the list |
| 1016 * @param index the index where the iterator shall point at |
|
| 1017 * @return a new iterator |
848 * @return a new iterator |
| 1018 */ |
849 */ |
| 1019 cx_attr_nodiscard |
850 cx_attr_nodiscard |
| 1020 cx_attr_export |
851 CX_EXPORT CxIterator cxListIterator(const CxList *list); |
| 1021 CxIterator cxListMutIteratorAt( |
852 |
| 1022 CxList *list, |
853 /** |
| 1023 size_t index |
854 * Returns a backwards iterator pointing to the last item of the list. |
| 1024 ); |
|
| 1025 |
|
| 1026 /** |
|
| 1027 * Returns a mutating backwards iterator pointing to the item at the |
|
| 1028 * specified index. |
|
| 1029 * |
855 * |
| 1030 * The returned iterator is position-aware. |
856 * The returned iterator is position-aware. |
| 1031 * |
857 * |
| 1032 * If the index is out of range or @p list is @c NULL, a past-the-end iterator will be returned. |
858 * If the list is empty or @c NULL, a past-the-end iterator will be returned. |
| 1033 * |
859 * |
| 1034 * @param list the list |
860 * @param list the list |
| 1035 * @param index the index where the iterator shall point at |
|
| 1036 * @return a new iterator |
861 * @return a new iterator |
| 1037 */ |
862 */ |
| 1038 cx_attr_nodiscard |
863 cx_attr_nodiscard |
| 1039 cx_attr_export |
864 CX_EXPORT CxIterator cxListBackwardsIterator(const CxList *list); |
| 1040 CxIterator cxListMutBackwardsIteratorAt( |
|
| 1041 CxList *list, |
|
| 1042 size_t index |
|
| 1043 ); |
|
| 1044 |
|
| 1045 /** |
|
| 1046 * Returns an iterator pointing to the first item of the list. |
|
| 1047 * |
|
| 1048 * The returned iterator is position-aware. |
|
| 1049 * |
|
| 1050 * If the list is empty or @c NULL, a past-the-end iterator will be returned. |
|
| 1051 * |
|
| 1052 * @param list the list |
|
| 1053 * @return a new iterator |
|
| 1054 */ |
|
| 1055 cx_attr_nodiscard |
|
| 1056 static inline CxIterator cxListIterator(const CxList *list) { |
|
| 1057 if (list == NULL) list = cxEmptyList; |
|
| 1058 return list->cl->iterator(list, 0, false); |
|
| 1059 } |
|
| 1060 |
|
| 1061 /** |
|
| 1062 * Returns a mutating iterator pointing to the first item of the list. |
|
| 1063 * |
|
| 1064 * The returned iterator is position-aware. |
|
| 1065 * |
|
| 1066 * If the list is empty or @c NULL, a past-the-end iterator will be returned. |
|
| 1067 * |
|
| 1068 * @param list the list |
|
| 1069 * @return a new iterator |
|
| 1070 */ |
|
| 1071 cx_attr_nodiscard |
|
| 1072 static inline CxIterator cxListMutIterator(CxList *list) { |
|
| 1073 if (list == NULL) list = cxEmptyList; |
|
| 1074 return cxListMutIteratorAt(list, 0); |
|
| 1075 } |
|
| 1076 |
|
| 1077 |
|
| 1078 /** |
|
| 1079 * Returns a backwards iterator pointing to the last item of the list. |
|
| 1080 * |
|
| 1081 * The returned iterator is position-aware. |
|
| 1082 * |
|
| 1083 * If the list is empty or @c NULL, a past-the-end iterator will be returned. |
|
| 1084 * |
|
| 1085 * @param list the list |
|
| 1086 * @return a new iterator |
|
| 1087 */ |
|
| 1088 cx_attr_nodiscard |
|
| 1089 static inline CxIterator cxListBackwardsIterator(const CxList *list) { |
|
| 1090 if (list == NULL) list = cxEmptyList; |
|
| 1091 return list->cl->iterator(list, list->collection.size - 1, true); |
|
| 1092 } |
|
| 1093 |
|
| 1094 /** |
|
| 1095 * Returns a mutating backwards iterator pointing to the last item of the list. |
|
| 1096 * |
|
| 1097 * The returned iterator is position-aware. |
|
| 1098 * |
|
| 1099 * If the list is empty or @c NULL, a past-the-end iterator will be returned. |
|
| 1100 * |
|
| 1101 * @param list the list |
|
| 1102 * @return a new iterator |
|
| 1103 */ |
|
| 1104 cx_attr_nodiscard |
|
| 1105 static inline CxIterator cxListMutBackwardsIterator(CxList *list) { |
|
| 1106 if (list == NULL) list = cxEmptyList; |
|
| 1107 return cxListMutBackwardsIteratorAt(list, list->collection.size - 1); |
|
| 1108 } |
|
| 1109 |
865 |
| 1110 /** |
866 /** |
| 1111 * Returns the index of the first element that equals @p elem. |
867 * Returns the index of the first element that equals @p elem. |
| 1112 * |
868 * |
| 1113 * Determining equality is performed by the list's comparator function. |
869 * Determining equality is performed by the list's comparator function. |
| 1116 * @param elem the element to find |
872 * @param elem the element to find |
| 1117 * @return the index of the element or the size of the list when the element is not found |
873 * @return the index of the element or the size of the list when the element is not found |
| 1118 * @see cxListIndexValid() |
874 * @see cxListIndexValid() |
| 1119 * @see cxListContains() |
875 * @see cxListContains() |
| 1120 */ |
876 */ |
| 1121 cx_attr_nonnull |
877 cx_attr_nonnull cx_attr_nodiscard |
| 1122 cx_attr_nodiscard |
878 CX_EXPORT size_t cxListFind(const CxList *list, const void *elem); |
| 1123 static inline size_t cxListFind( |
|
| 1124 const CxList *list, |
|
| 1125 const void *elem |
|
| 1126 ) { |
|
| 1127 return list->cl->find_remove((CxList*)list, elem, false); |
|
| 1128 } |
|
| 1129 |
879 |
| 1130 /** |
880 /** |
| 1131 * Checks if the list contains the specified element. |
881 * Checks if the list contains the specified element. |
| 1132 * |
882 * |
| 1133 * The elements are compared with the list's comparator function. |
883 * The elements are compared with the list's comparator function. |
| 1136 * @param elem the element to find |
886 * @param elem the element to find |
| 1137 * @retval true if the element is contained |
887 * @retval true if the element is contained |
| 1138 * @retval false if the element is not contained |
888 * @retval false if the element is not contained |
| 1139 * @see cxListFind() |
889 * @see cxListFind() |
| 1140 */ |
890 */ |
| 1141 cx_attr_nonnull |
891 cx_attr_nonnull cx_attr_nodiscard |
| 1142 cx_attr_nodiscard |
892 CX_EXPORT bool cxListContains(const CxList* list, const void* elem); |
| 1143 static inline bool cxListContains( |
|
| 1144 const CxList* list, |
|
| 1145 const void* elem |
|
| 1146 ) { |
|
| 1147 return list->cl->find_remove((CxList*)list, elem, false) < list->collection.size; |
|
| 1148 } |
|
| 1149 |
893 |
| 1150 /** |
894 /** |
| 1151 * Checks if the specified index is within bounds. |
895 * Checks if the specified index is within bounds. |
| 1152 * |
896 * |
| 1153 * @param list the list |
897 * @param list the list |
| 1154 * @param index the index |
898 * @param index the index |
| 1155 * @retval true if the index is within bounds |
899 * @retval true if the index is within bounds |
| 1156 * @retval false if the index is out of bounds |
900 * @retval false if the index is out of bounds |
| 1157 */ |
901 */ |
| 1158 cx_attr_nonnull |
902 cx_attr_nonnull cx_attr_nodiscard |
| 1159 cx_attr_nodiscard |
903 CX_EXPORT bool cxListIndexValid(const CxList *list, size_t index); |
| 1160 static inline bool cxListIndexValid(const CxList *list, size_t index) { |
|
| 1161 return index < list->collection.size; |
|
| 1162 } |
|
| 1163 |
904 |
| 1164 /** |
905 /** |
| 1165 * Removes and returns the index of the first element that equals @p elem. |
906 * Removes and returns the index of the first element that equals @p elem. |
| 1166 * |
907 * |
| 1167 * Determining equality is performed by the list's comparator function. |
908 * Determining equality is performed by the list's comparator function. |
| 1171 * @return the index of the now removed element or the list size |
912 * @return the index of the now removed element or the list size |
| 1172 * when the element is not found or could not be removed |
913 * when the element is not found or could not be removed |
| 1173 * @see cxListIndexValid() |
914 * @see cxListIndexValid() |
| 1174 */ |
915 */ |
| 1175 cx_attr_nonnull |
916 cx_attr_nonnull |
| 1176 static inline size_t cxListFindRemove( |
917 CX_EXPORT size_t cxListFindRemove(CxList *list, const void *elem); |
| 1177 CxList *list, |
|
| 1178 const void *elem |
|
| 1179 ) { |
|
| 1180 return list->cl->find_remove(list, elem, true); |
|
| 1181 } |
|
| 1182 |
918 |
| 1183 /** |
919 /** |
| 1184 * Sorts the list. |
920 * Sorts the list. |
| 1185 * |
921 * |
| 1186 * @remark The underlying sort algorithm is implementation defined. |
922 * @remark The underlying sort algorithm is implementation defined. |
| 1187 * |
923 * |
| 1188 * @param list the list |
924 * @param list the list |
| 1189 */ |
925 */ |
| 1190 cx_attr_nonnull |
926 cx_attr_nonnull |
| 1191 static inline void cxListSort(CxList *list) { |
927 CX_EXPORT void cxListSort(CxList *list); |
| 1192 if (list->collection.sorted) return; |
|
| 1193 list->cl->sort(list); |
|
| 1194 list->collection.sorted = true; |
|
| 1195 } |
|
| 1196 |
928 |
| 1197 /** |
929 /** |
| 1198 * Reverses the order of the items. |
930 * Reverses the order of the items. |
| 1199 * |
931 * |
| 1200 * @param list the list |
932 * @param list the list |
| 1201 */ |
933 */ |
| 1202 cx_attr_nonnull |
934 cx_attr_nonnull |
| 1203 static inline void cxListReverse(CxList *list) { |
935 CX_EXPORT void cxListReverse(CxList *list); |
| 1204 // still sorted, but not according to the cmp_func |
|
| 1205 list->collection.sorted = false; |
|
| 1206 list->cl->reverse(list); |
|
| 1207 } |
|
| 1208 |
936 |
| 1209 /** |
937 /** |
| 1210 * Compares a list to another list of the same type. |
938 * Compares a list to another list of the same type. |
| 1211 * |
939 * |
| 1212 * First, the list sizes are compared. |
940 * First, the list sizes are compared. |
| 1213 * If they match, the lists are compared element-wise. |
941 * If they match, the lists are compared element-wise. |
| 1214 * |
942 * |
| 1215 * @param list the list |
943 * @param list the list |
| 1216 * @param other the list to compare to |
944 * @param other the list to compare to |
| 1217 * @retval zero both lists are equal element wise |
945 * @retval zero both lists are equal element wise |
| 1218 * @retval negative the first list is smaller |
946 * @retval negative the first list is smaller, |
| 1219 * or the first non-equal element in the first list is smaller |
947 * or the first non-equal element in the first list is smaller |
| 1220 * @retval positive the first list is larger |
948 * @retval positive the first list is larger |
| 1221 * or the first non-equal element in the first list is larger |
949 * or the first non-equal element in the first list is larger |
| 1222 */ |
950 */ |
| 1223 cx_attr_nonnull |
951 cx_attr_nonnull cx_attr_nodiscard |
| 1224 cx_attr_nodiscard |
952 CX_EXPORT int cxListCompare(const CxList *list, const CxList *other); |
| 1225 cx_attr_export |
|
| 1226 int cxListCompare( |
|
| 1227 const CxList *list, |
|
| 1228 const CxList *other |
|
| 1229 ); |
|
| 1230 |
953 |
| 1231 /** |
954 /** |
| 1232 * Deallocates the memory of the specified list structure. |
955 * Deallocates the memory of the specified list structure. |
| 1233 * |
956 * |
| 1234 * Also calls the content destructor functions for each element, if specified. |
957 * Also calls the content destructor functions for each element, if specified. |
| 1235 * |
958 * |
| 1236 * @param list the list that shall be freed |
959 * @param list the list that shall be freed |
| 1237 */ |
960 */ |
| 1238 cx_attr_export |
961 CX_EXPORT void cxListFree(CxList *list); |
| 1239 void cxListFree(CxList *list); |
|
| 1240 |
962 |
| 1241 |
963 |
| 1242 #ifdef __cplusplus |
964 #ifdef __cplusplus |
| 1243 } // extern "C" |
965 } // extern "C" |
| 1244 #endif |
966 #endif |