src/ucx/cx/list.h

changeset 621
956c03c25edd
parent 582
82b60a8dd55c
child 645
0c85c4cd0dd8
equal deleted inserted replaced
620:a202cb1ee175 621:956c03c25edd
78 */ 78 */
79 void (*deallocate)(struct cx_list_s *list); 79 void (*deallocate)(struct cx_list_s *list);
80 80
81 /** 81 /**
82 * Member function for inserting a single element. 82 * Member function for inserting a single element.
83 * The data pointer may be @c NULL in which case the function shall only allocate memory. 83 * The data pointer may be @c NULL, in which case the function shall only allocate memory.
84 * Returns a pointer to the data of the inserted element. 84 * Returns a pointer to the allocated memory or @c NULL if allocation fails.
85 */ 85 */
86 void *(*insert_element)( 86 void *(*insert_element)(struct cx_list_s *list, size_t index, const void *data);
87 struct cx_list_s *list,
88 size_t index,
89 const void *data
90 );
91 87
92 /** 88 /**
93 * Member function for inserting multiple elements. 89 * Member function for inserting multiple elements.
94 * 90 *
91 * The data pointer may be @c NULL, in which case the function shall only allocate memory.
92 * Returns the number of successfully inserted or allocated elements.
93 *
95 * @see cx_list_default_insert_array() 94 * @see cx_list_default_insert_array()
96 */ 95 */
97 size_t (*insert_array)( 96 size_t (*insert_array)(struct cx_list_s *list, size_t index, const void *data, size_t n);
98 struct cx_list_s *list,
99 size_t index,
100 const void *data,
101 size_t n
102 );
103 97
104 /** 98 /**
105 * Member function for inserting sorted elements into a sorted list. 99 * Member function for inserting sorted elements into a sorted list.
100 * Returns the number of successfully inserted elements.
106 * 101 *
107 * @see cx_list_default_insert_sorted() 102 * @see cx_list_default_insert_sorted()
108 */ 103 */
109 size_t (*insert_sorted)( 104 size_t (*insert_sorted)(struct cx_list_s *list, const void *sorted_data, size_t n);
110 struct cx_list_s *list, 105
111 const void *sorted_data, 106 /**
112 size_t n 107 * Member function for inserting multiple elements if they do not exist.
113 ); 108 * Implementations shall return the number of successfully processed elements
109 * (including those which were not added because they are already contained).
110 * @see cx_list_default_insert_unique()
111 */
112 size_t (*insert_unique)(struct cx_list_s *list, const void *sorted_data, size_t n);
114 113
115 /** 114 /**
116 * Member function for inserting an element relative to an iterator position. 115 * Member function for inserting an element relative to an iterator position.
117 */ 116 */
118 int (*insert_iter)( 117 int (*insert_iter)(struct cx_iterator_s *iter, const void *elem, int prepend);
119 struct cx_iterator_s *iter,
120 const void *elem,
121 int prepend
122 );
123 118
124 /** 119 /**
125 * Member function for removing elements. 120 * Member function for removing elements.
126 * 121 *
127 * Implementations SHALL check if @p targetbuf is set and copy the elements 122 * Implementations SHALL check if @p targetbuf is set and copy the elements
129 * When @p targetbuf is not set, the destructors SHALL be invoked. 124 * When @p targetbuf is not set, the destructors SHALL be invoked.
130 * 125 *
131 * The function SHALL return the actual number of elements removed, which 126 * The function SHALL return the actual number of elements removed, which
132 * might be lower than @p num when going out of bounds. 127 * might be lower than @p num when going out of bounds.
133 */ 128 */
134 size_t (*remove)( 129 size_t (*remove)(struct cx_list_s *list, size_t index, size_t num, void *targetbuf);
135 struct cx_list_s *list,
136 size_t index,
137 size_t num,
138 void *targetbuf
139 );
140 130
141 /** 131 /**
142 * Member function for removing all elements. 132 * Member function for removing all elements.
143 */ 133 */
144 void (*clear)(struct cx_list_s *list); 134 void (*clear)(struct cx_list_s *list);
146 /** 136 /**
147 * Member function for swapping two elements. 137 * Member function for swapping two elements.
148 * 138 *
149 * @see cx_list_default_swap() 139 * @see cx_list_default_swap()
150 */ 140 */
151 int (*swap)( 141 int (*swap)(struct cx_list_s *list, size_t i, size_t j);
152 struct cx_list_s *list,
153 size_t i,
154 size_t j
155 );
156 142
157 /** 143 /**
158 * Member function for element lookup. 144 * Member function for element lookup.
159 */ 145 */
160 void *(*at)( 146 void *(*at)(const struct cx_list_s *list, size_t index);
161 const struct cx_list_s *list,
162 size_t index
163 );
164 147
165 /** 148 /**
166 * Member function for finding and optionally removing an element. 149 * Member function for finding and optionally removing an element.
167 */ 150 */
168 size_t (*find_remove)( 151 size_t (*find_remove)(struct cx_list_s *list, const void *elem, bool remove);
169 struct cx_list_s *list,
170 const void *elem,
171 bool remove
172 );
173 152
174 /** 153 /**
175 * Member function for sorting the list. 154 * Member function for sorting the list.
176 * 155 *
177 * @see cx_list_default_sort() 156 * @see cx_list_default_sort()
179 void (*sort)(struct cx_list_s *list); 158 void (*sort)(struct cx_list_s *list);
180 159
181 /** 160 /**
182 * Optional member function for comparing this list 161 * Optional member function for comparing this list
183 * to another list of the same type. 162 * to another list of the same type.
184 * If set to @c NULL, comparison won't be optimized. 163 * If set to @c NULL, the comparison won't be optimized.
185 */ 164 */
186 cx_attr_nonnull 165 int (*compare)(const struct cx_list_s *list, const struct cx_list_s *other);
187 int (*compare)(
188 const struct cx_list_s *list,
189 const struct cx_list_s *other
190 );
191 166
192 /** 167 /**
193 * Member function for reversing the order of the items. 168 * Member function for reversing the order of the items.
194 */ 169 */
195 void (*reverse)(struct cx_list_s *list); 170 void (*reverse)(struct cx_list_s *list);
196 171
197 /** 172 /**
198 * Member function for returning an iterator pointing to the specified index. 173 * Member function for returning an iterator pointing to the specified index.
199 */ 174 */
200 struct cx_iterator_s (*iterator)( 175 struct cx_iterator_s (*iterator)(const struct cx_list_s *list, size_t index, bool backward);
201 const struct cx_list_s *list,
202 size_t index,
203 bool backward
204 );
205 }; 176 };
206 177
207 /** 178 /**
208 * Common type for all list implementations. 179 * Common type for all list implementations.
209 */ 180 */
212 /** 183 /**
213 * A shared instance of an empty list. 184 * A shared instance of an empty list.
214 * 185 *
215 * Writing to that list is not allowed. 186 * Writing to that list is not allowed.
216 * 187 *
217 * You can use this is a placeholder for initializing CxList pointers 188 * You can use this as a placeholder for initializing CxList pointers
218 * for which you do not want to reserve memory right from the beginning. 189 * for which you do not want to reserve memory right from the beginning.
219 */ 190 */
220 cx_attr_export 191 CX_EXPORT extern CxList *const cxEmptyList;
221 extern CxList *const cxEmptyList;
222 192
223 /** 193 /**
224 * Default implementation of an array insert. 194 * Default implementation of an array insert.
225 * 195 *
226 * This function uses the element insert function for each element of the array. 196 * This function uses the element insert function for each element of the array.
233 * @param data a pointer to the array of data to insert 203 * @param data a pointer to the array of data to insert
234 * @param n the number of elements to insert 204 * @param n the number of elements to insert
235 * @return the number of elements actually inserted 205 * @return the number of elements actually inserted
236 */ 206 */
237 cx_attr_nonnull 207 cx_attr_nonnull
238 cx_attr_export 208 CX_EXPORT size_t cx_list_default_insert_array(struct cx_list_s *list,
239 size_t cx_list_default_insert_array( 209 size_t index, const void *data, size_t n);
240 struct cx_list_s *list,
241 size_t index,
242 const void *data,
243 size_t n
244 );
245 210
246 /** 211 /**
247 * Default implementation of a sorted insert. 212 * Default implementation of a sorted insert.
248 * 213 *
249 * This function uses the array insert function to insert consecutive groups 214 * This function uses the array insert function to insert consecutive groups
258 * @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
259 * @param n the number of elements to insert 224 * @param n the number of elements to insert
260 * @return the number of elements actually inserted 225 * @return the number of elements actually inserted
261 */ 226 */
262 cx_attr_nonnull 227 cx_attr_nonnull
263 cx_attr_export 228 CX_EXPORT size_t cx_list_default_insert_sorted(struct cx_list_s *list,
264 size_t cx_list_default_insert_sorted( 229 const void *sorted_data, size_t n);
265 struct cx_list_s *list, 230
266 const void *sorted_data, 231 /**
267 size_t n 232 * Default implementation of an array insert where only elements are inserted when they don't exist in the list.
268 ); 233 *
234 * This function is similar to cx_list_default_insert_sorted(), except it skips elements that are already in the list.
235 *
236 * @note The return value of this function denotes the number of elements from the @p sorted_data that are definitely
237 * contained in the list after completing the call. It is @em not the number of elements that were newly inserted.
238 * That means, when no error occurred, the return value should be @p n.
239 *
240 * Use this in your own list class if you do not want to implement an optimized version for your list.
241 *
242 * @param list the list
243 * @param sorted_data a pointer to the array of pre-sorted data to insert
244 * @param n the number of elements to insert
245 * @return the number of elements from the @p sorted_data that are definitely present in the list after this call
246 */
247 cx_attr_nonnull
248 CX_EXPORT size_t cx_list_default_insert_unique(struct cx_list_s *list,
249 const void *sorted_data, size_t n);
269 250
270 /** 251 /**
271 * Default unoptimized sort implementation. 252 * Default unoptimized sort implementation.
272 * 253 *
273 * 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
277 * version for your list. 258 * version for your list.
278 * 259 *
279 * @param list the list that shall be sorted 260 * @param list the list that shall be sorted
280 */ 261 */
281 cx_attr_nonnull 262 cx_attr_nonnull
282 cx_attr_export 263 CX_EXPORT void cx_list_default_sort(struct cx_list_s *list);
283 void cx_list_default_sort(struct cx_list_s *list);
284 264
285 /** 265 /**
286 * Default unoptimized swap implementation. 266 * Default unoptimized swap implementation.
287 * 267 *
288 * Use this in your own list class if you do not want to implement an optimized 268 * Use this in your own list class if you do not want to implement an optimized
294 * @retval zero success 274 * @retval zero success
295 * @retval non-zero when indices are out of bounds or memory 275 * @retval non-zero when indices are out of bounds or memory
296 * allocation for the temporary buffer fails 276 * allocation for the temporary buffer fails
297 */ 277 */
298 cx_attr_nonnull 278 cx_attr_nonnull
299 cx_attr_export 279 CX_EXPORT int cx_list_default_swap(struct cx_list_s *list, size_t i, size_t j);
300 int cx_list_default_swap(struct cx_list_s *list, size_t i, size_t j);
301 280
302 /** 281 /**
303 * Initializes a list struct. 282 * Initializes a list struct.
304 * 283 *
305 * Only use this function if you are creating your own list implementation. 284 * Only use this function if you are creating your own list implementation.
306 * The purpose of this function is to be called in the initialization code 285 * The purpose of this function is to be called in the initialization code
307 * of your list, to set certain members correctly. 286 * of your list to set certain members correctly.
308 * 287 *
309 * This is particularly important when you want your list to support 288 * This is particularly important when you want your list to support
310 * #CX_STORE_POINTERS as @p elem_size. This function will wrap the list 289 * #CX_STORE_POINTERS as @p elem_size. This function will wrap the list
311 * class accordingly and make sure that you can implement your list as if 290 * class accordingly and make sure that you can implement your list as if
312 * it was only storing objects and the wrapper will automatically enable 291 * it was only storing objects, and the wrapper will automatically enable
313 * the feature of storing pointers. 292 * the feature of storing pointers.
314 * 293 *
315 * @par Example 294 * @par Example
316 * 295 *
317 * @code 296 * @code
342 * @param allocator the allocator for the elements 321 * @param allocator the allocator for the elements
343 * @param comparator a compare function for the elements 322 * @param comparator a compare function for the elements
344 * @param elem_size the size of one element 323 * @param elem_size the size of one element
345 */ 324 */
346 cx_attr_nonnull_arg(1, 2, 3) 325 cx_attr_nonnull_arg(1, 2, 3)
347 cx_attr_export 326 CX_EXPORT void cx_list_init(struct cx_list_s *list,
348 void cx_list_init( 327 struct cx_list_class_s *cl, const struct cx_allocator_s *allocator,
349 struct cx_list_s *list, 328 cx_compare_func comparator, size_t elem_size);
350 struct cx_list_class_s *cl,
351 const struct cx_allocator_s *allocator,
352 cx_compare_func comparator,
353 size_t elem_size
354 );
355 329
356 /** 330 /**
357 * Returns the number of elements currently stored in the list. 331 * Returns the number of elements currently stored in the list.
358 * 332 *
359 * @param list the list 333 * @param list the list
360 * @return the number of currently stored elements 334 * @return the number of currently stored elements
361 */ 335 */
362 cx_attr_nonnull 336 cx_attr_nonnull
363 static inline size_t cxListSize(const CxList *list) { 337 CX_EXPORT size_t cxListSize(const CxList *list);
364 return list->collection.size;
365 }
366 338
367 /** 339 /**
368 * Adds an item to the end of the list. 340 * Adds an item to the end of the list.
369 * 341 *
370 * @param list the list 342 * @param list the list
373 * @retval non-zero memory allocation failure 345 * @retval non-zero memory allocation failure
374 * @see cxListAddArray() 346 * @see cxListAddArray()
375 * @see cxListEmplace() 347 * @see cxListEmplace()
376 */ 348 */
377 cx_attr_nonnull 349 cx_attr_nonnull
378 static inline int cxListAdd( 350 CX_EXPORT int cxListAdd(CxList *list, const void *elem);
379 CxList *list,
380 const void *elem
381 ) {
382 list->collection.sorted = false;
383 return list->cl->insert_element(list, list->collection.size, elem) == NULL;
384 }
385 351
386 /** 352 /**
387 * Adds multiple items to the end of the list. 353 * Adds multiple items to the end of the list.
388 * 354 *
389 * This method is more efficient than invoking cxListAdd() multiple times. 355 * This method is more efficient than invoking cxListAdd() multiple times.
390 * 356 *
391 * If there is not enough memory to add all elements, the returned value is 357 * If there is not enough memory to add all elements, the returned value is
392 * less than @p n. 358 * less than @p n.
393 * 359 *
394 * If this list is storing pointers instead of objects @p array is expected to 360 * If this list is storing pointers instead of objects, @p array is expected to
395 * be an array of pointers. 361 * be an array of pointers.
396 * 362 *
397 * @param list the list 363 * @param list the list
398 * @param array a pointer to the elements to add 364 * @param array a pointer to the elements to add
399 * @param n the number of elements to add 365 * @param n the number of elements to add
400 * @return the number of added elements 366 * @return the number of added elements
401 */ 367 * @see cxListEmplaceArray()
402 cx_attr_nonnull 368 */
403 static inline size_t cxListAddArray( 369 cx_attr_nonnull
404 CxList *list, 370 CX_EXPORT size_t cxListAddArray(CxList *list, const void *array, size_t n);
405 const void *array,
406 size_t n
407 ) {
408 list->collection.sorted = false;
409 return list->cl->insert_array(list, list->collection.size, array, n);
410 }
411 371
412 /** 372 /**
413 * Inserts an item at the specified index. 373 * Inserts an item at the specified index.
414 * 374 *
415 * If @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().
416 * 376 *
417 * @param list the list 377 * @param list the list
418 * @param index the index the element shall have 378 * @param index the index the element shall have
419 * @param elem a pointer to the element to add 379 * @param elem a pointer to the element to add
420 * @retval zero success 380 * @retval zero success
422 * @see cxListInsertAfter() 382 * @see cxListInsertAfter()
423 * @see cxListInsertBefore() 383 * @see cxListInsertBefore()
424 * @see cxListEmplaceAt() 384 * @see cxListEmplaceAt()
425 */ 385 */
426 cx_attr_nonnull 386 cx_attr_nonnull
427 static inline int cxListInsert( 387 CX_EXPORT int cxListInsert(CxList *list, size_t index, const void *elem);
428 CxList *list,
429 size_t index,
430 const void *elem
431 ) {
432 list->collection.sorted = false;
433 return list->cl->insert_element(list, index, elem) == NULL;
434 }
435 388
436 /** 389 /**
437 * 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.
438 * 391 *
439 * @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**.
440 * 393 *
441 * @param list the list 394 * @param list the list
442 * @param index the index where to emplace the element 395 * @param index the index where to emplace the element
443 * @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
444 * @see cxListEmplace() 397 * @see cxListEmplace()
398 * @see cxListEmplaceArrayAt()
445 * @see cxListInsert() 399 * @see cxListInsert()
446 */ 400 */
447 cx_attr_nonnull 401 cx_attr_nonnull
448 static inline void *cxListEmplaceAt(CxList *list, size_t index) { 402 CX_EXPORT void *cxListEmplaceAt(CxList *list, size_t index);
449 list->collection.sorted = false;
450 return list->cl->insert_element(list, index, NULL);
451 }
452
453 403
454 /** 404 /**
455 * 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.
456 * 406 *
457 * @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**.
460 * @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
461 * @see cxListEmplaceAt() 411 * @see cxListEmplaceAt()
462 * @see cxListAdd() 412 * @see cxListAdd()
463 */ 413 */
464 cx_attr_nonnull 414 cx_attr_nonnull
465 static inline void *cxListEmplace(CxList *list) { 415 CX_EXPORT void *cxListEmplace(CxList *list);
466 list->collection.sorted = false; 416
467 return list->cl->insert_element(list, list->collection.size, NULL); 417 /**
468 } 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);
469 455
470 /** 456 /**
471 * Inserts an item into a sorted list. 457 * Inserts an item into a sorted list.
472 * 458 *
473 * If the list is not sorted already, the behavior is undefined. 459 * If the list is not sorted already, the behavior is undefined.
476 * @param elem a pointer to the element to add 462 * @param elem a pointer to the element to add
477 * @retval zero success 463 * @retval zero success
478 * @retval non-zero memory allocation failure 464 * @retval non-zero memory allocation failure
479 */ 465 */
480 cx_attr_nonnull 466 cx_attr_nonnull
481 static inline int cxListInsertSorted( 467 CX_EXPORT int cxListInsertSorted(CxList *list, const void *elem);
482 CxList *list, 468
483 const void *elem 469 /**
484 ) { 470 * Inserts an item into a list if it does not exist.
485 list->collection.sorted = true; // guaranteed by definition 471 *
486 const void *data = list->collection.store_pointer ? &elem : elem; 472 * If the list is not sorted already, this function will check all elements
487 return list->cl->insert_sorted(list, data, 1) == 0; 473 * and append the new element when it was not found.
488 } 474 * It is strongly recommended to use this function only on sorted lists, where
475 * the element, if it is not contained, is inserted at the correct position.
476 *
477 * @param list the list
478 * @param elem a pointer to the element to add
479 * @retval zero success (also when the element was already in the list)
480 * @retval non-zero memory allocation failure
481 */
482 cx_attr_nonnull
483 CX_EXPORT int cxListInsertUnique(CxList *list, const void *elem);
489 484
490 /** 485 /**
491 * Inserts multiple items to the list at the specified index. 486 * Inserts multiple items to the list at the specified index.
492 * If @p index equals the list size, this is effectively cxListAddArray(). 487 * If the @p index equals the list size, this is effectively cxListAddArray().
493 * 488 *
494 * This method is usually more efficient than invoking cxListInsert() 489 * This method is usually more efficient than invoking cxListInsert()
495 * multiple times. 490 * multiple times.
496 * 491 *
497 * If there is not enough memory to add all elements, the returned value is 492 * If there is not enough memory to add all elements, the returned value is
498 * less than @p n. 493 * less than @p n.
499 * 494 *
500 * If this list is storing pointers instead of objects @p array is expected to 495 * If this list is storing pointers instead of objects, @p array is expected to
501 * be an array of pointers. 496 * be an array of pointers.
502 * 497 *
503 * @param list the list 498 * @param list the list
504 * @param index the index where to add the elements 499 * @param index the index where to add the elements
505 * @param array a pointer to the elements to add 500 * @param array a pointer to the elements to add
506 * @param n the number of elements to add 501 * @param n the number of elements to add
507 * @return the number of added elements 502 * @return the number of added elements
508 */ 503 * @see cxListEmplaceArrayAt()
509 cx_attr_nonnull 504 */
510 static inline size_t cxListInsertArray( 505 cx_attr_nonnull
511 CxList *list, 506 CX_EXPORT size_t cxListInsertArray(CxList *list, size_t index, const void *array, size_t n);
512 size_t index,
513 const void *array,
514 size_t n
515 ) {
516 list->collection.sorted = false;
517 return list->cl->insert_array(list, index, array, n);
518 }
519 507
520 /** 508 /**
521 * Inserts a sorted array into a sorted list. 509 * Inserts a sorted array into a sorted list.
522 * 510 *
523 * This method is usually more efficient than inserting each element separately, 511 * This method is usually more efficient than inserting each element separately
524 * because consecutive chunks of sorted data are inserted in one pass. 512 * because consecutive chunks of sorted data are inserted in one pass.
525 * 513 *
526 * If there is not enough memory to add all elements, the returned value is 514 * If there is not enough memory to add all elements, the returned value is
527 * less than @p n. 515 * less than @p n.
528 * 516 *
529 * If this list is storing pointers instead of objects @p array is expected to 517 * If this list is storing pointers instead of objects, @p array is expected to
530 * be an array of pointers. 518 * be an array of pointers.
531 * 519 *
532 * If the list is not sorted already, the behavior is undefined. 520 * If the list is not sorted already, the behavior is undefined.
533 * 521 *
534 * @param list the list 522 * @param list the list
535 * @param array a pointer to the elements to add 523 * @param array a pointer to the elements to add
536 * @param n the number of elements to add 524 * @param n the number of elements to add
537 * @return the number of added elements 525 * @return the number of added elements
538 */ 526 */
539 cx_attr_nonnull 527 cx_attr_nonnull
540 static inline size_t cxListInsertSortedArray( 528 CX_EXPORT size_t cxListInsertSortedArray(CxList *list, const void *array, size_t n);
541 CxList *list, 529
542 const void *array, 530 /**
543 size_t n 531 * Inserts an array into a list, skipping duplicates.
544 ) { 532 *
545 list->collection.sorted = true; // guaranteed by definition 533 * The @p list does not need to be sorted (in contrast to cxListInsertSortedArray()).
546 return list->cl->insert_sorted(list, array, n); 534 * But it is strongly recommended to use this function only on sorted lists,
547 } 535 * because otherwise it will fall back to an inefficient algorithm which inserts
536 * all elements one by one.
537 * If the @p list is not sorted, the @p array also does not need to be sorted.
538 * But when the @p list is sorted, the @p array must also be sorted.
539 *
540 * This method is usually more efficient than inserting each element separately
541 * because consecutive chunks of sorted data are inserted in one pass.
542 *
543 * If there is not enough memory to add all elements, the returned value is
544 * less than @p n.
545 *
546 * @note The return value of this function denotes the number of elements
547 * from the @p sorted_data that are definitely contained in the list after
548 * completing the call. It is @em not the number of elements that were newly
549 * inserted. That means, when no error occurred, the return value should
550 * be @p n.
551 *
552 * If this list is storing pointers instead of objects @p array is expected to
553 * be an array of pointers.
554 *
555 * @param list the list
556 * @param array a pointer to the elements to add
557 * @param n the number of elements to add
558 * @return the number of added elements
559 *
560 * @return the number of elements from the @p sorted_data that are definitely present in the list after this call
561 */
562 cx_attr_nonnull
563 CX_EXPORT size_t cxListInsertUniqueArray(CxList *list, const void *array, size_t n);
548 564
549 /** 565 /**
550 * Inserts an element after the current location of the specified iterator. 566 * Inserts an element after the current location of the specified iterator.
551 * 567 *
552 * The used iterator remains operational, but all other active iterators should 568 * The used iterator remains operational, but all other active iterators should
561 * @retval non-zero memory allocation failure 577 * @retval non-zero memory allocation failure
562 * @see cxListInsert() 578 * @see cxListInsert()
563 * @see cxListInsertBefore() 579 * @see cxListInsertBefore()
564 */ 580 */
565 cx_attr_nonnull 581 cx_attr_nonnull
566 static inline int cxListInsertAfter( 582 CX_EXPORT int cxListInsertAfter(CxIterator *iter, const void *elem);
567 CxIterator *iter,
568 const void *elem
569 ) {
570 CxList* list = (CxList*)iter->src_handle.m;
571 list->collection.sorted = false;
572 return list->cl->insert_iter(iter, elem, 0);
573 }
574 583
575 /** 584 /**
576 * Inserts an element before the current location of the specified iterator. 585 * Inserts an element before the current location of the specified iterator.
577 * 586 *
578 * The used iterator remains operational, but all other active iterators should 587 * The used iterator remains operational, but all other active iterators should
587 * @retval non-zero memory allocation failure 596 * @retval non-zero memory allocation failure
588 * @see cxListInsert() 597 * @see cxListInsert()
589 * @see cxListInsertAfter() 598 * @see cxListInsertAfter()
590 */ 599 */
591 cx_attr_nonnull 600 cx_attr_nonnull
592 static inline int cxListInsertBefore( 601 CX_EXPORT int cxListInsertBefore(CxIterator *iter, const void *elem);
593 CxIterator *iter,
594 const void *elem
595 ) {
596 CxList* list = (CxList*)iter->src_handle.m;
597 list->collection.sorted = false;
598 return list->cl->insert_iter(iter, elem, 1);
599 }
600 602
601 /** 603 /**
602 * Removes the element at the specified index. 604 * Removes the element at the specified index.
603 * 605 *
604 * If an element destructor function is specified, it is called before 606 * If an element destructor function is specified, it is called before
608 * @param index the index of the element 610 * @param index the index of the element
609 * @retval zero success 611 * @retval zero success
610 * @retval non-zero index out of bounds 612 * @retval non-zero index out of bounds
611 */ 613 */
612 cx_attr_nonnull 614 cx_attr_nonnull
613 static inline int cxListRemove( 615 CX_EXPORT int cxListRemove(CxList *list, size_t index);
614 CxList *list,
615 size_t index
616 ) {
617 return list->cl->remove(list, index, 1, NULL) == 0;
618 }
619 616
620 /** 617 /**
621 * Removes and returns the element at the specified index. 618 * Removes and returns the element at the specified index.
622 * 619 *
623 * No destructor is called, and instead the element is copied to the 620 * No destructor is called, and instead the element is copied to the
628 * @param index the index of the element 625 * @param index the index of the element
629 * @param targetbuf a buffer where to copy the element 626 * @param targetbuf a buffer where to copy the element
630 * @retval zero success 627 * @retval zero success
631 * @retval non-zero index out of bounds 628 * @retval non-zero index out of bounds
632 */ 629 */
633 cx_attr_nonnull 630 cx_attr_nonnull cx_attr_access_w(3)
634 cx_attr_access_w(3) 631 CX_EXPORT int cxListRemoveAndGet(CxList *list, size_t index, void *targetbuf);
635 static inline int cxListRemoveAndGet(
636 CxList *list,
637 size_t index,
638 void *targetbuf
639 ) {
640 return list->cl->remove(list, index, 1, targetbuf) == 0;
641 }
642 632
643 /** 633 /**
644 * Removes and returns the first element of the list. 634 * Removes and returns the first element of the list.
645 * 635 *
646 * 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
648 * If the list is storing pointers, only the pointer is copied to @p targetbuf. 638 * If the list is storing pointers, only the pointer is copied to @p targetbuf.
649 * 639 *
650 * @param list the list 640 * @param list the list
651 * @param targetbuf a buffer where to copy the element 641 * @param targetbuf a buffer where to copy the element
652 * @retval zero success 642 * @retval zero success
653 * @retval non-zero list is empty 643 * @retval non-zero the list is empty
654 * @see cxListPopFront() 644 * @see cxListPopFront()
655 * @see cxListRemoveAndGetLast() 645 * @see cxListRemoveAndGetLast()
656 */ 646 */
657 cx_attr_nonnull 647 cx_attr_nonnull cx_attr_access_w(2)
658 cx_attr_access_w(2) 648 CX_EXPORT int cxListRemoveAndGetFirst(CxList *list, void *targetbuf);
659 static inline int cxListRemoveAndGetFirst(
660 CxList *list,
661 void *targetbuf
662 ) {
663 return list->cl->remove(list, 0, 1, targetbuf) == 0;
664 }
665 649
666 /** 650 /**
667 * Removes and returns the first element of the list. 651 * Removes and returns the first element of the list.
668 * 652 *
669 * Alias for cxListRemoveAndGetFirst(). 653 * Alias for cxListRemoveAndGetFirst().
673 * If the list is storing pointers, only the pointer is copied to @p targetbuf. 657 * If the list is storing pointers, only the pointer is copied to @p targetbuf.
674 * 658 *
675 * @param list (@c CxList*) the list 659 * @param list (@c CxList*) the list
676 * @param targetbuf (@c void*) a buffer where to copy the element 660 * @param targetbuf (@c void*) a buffer where to copy the element
677 * @retval zero success 661 * @retval zero success
678 * @retval non-zero list is empty 662 * @retval non-zero the list is empty
679 * @see cxListRemoveAndGetFirst() 663 * @see cxListRemoveAndGetFirst()
680 * @see cxListPop() 664 * @see cxListPop()
681 */ 665 */
682 #define cxListPopFront(list, targetbuf) cxListRemoveAndGetFirst((list), (targetbuf)) 666 #define cxListPopFront(list, targetbuf) cxListRemoveAndGetFirst((list), (targetbuf))
683 667
690 * If the list is storing pointers, only the pointer is copied to @p targetbuf. 674 * If the list is storing pointers, only the pointer is copied to @p targetbuf.
691 * 675 *
692 * @param list the list 676 * @param list the list
693 * @param targetbuf a buffer where to copy the element 677 * @param targetbuf a buffer where to copy the element
694 * @retval zero success 678 * @retval zero success
695 * @retval non-zero list is empty 679 * @retval non-zero the list is empty
696 */ 680 */
697 cx_attr_nonnull 681 cx_attr_nonnull cx_attr_access_w(2)
698 cx_attr_access_w(2) 682 CX_EXPORT int cxListRemoveAndGetLast(CxList *list, void *targetbuf);
699 static inline int cxListRemoveAndGetLast(
700 CxList *list,
701 void *targetbuf
702 ) {
703 // note: index may wrap - member function will catch that
704 return list->cl->remove(list, list->collection.size - 1, 1, targetbuf) == 0;
705 }
706 683
707 /** 684 /**
708 * Removes and returns the last element of the list. 685 * Removes and returns the last element of the list.
709 * 686 *
710 * Alias for cxListRemoveAndGetLast(). 687 * Alias for cxListRemoveAndGetLast().
714 * If the list is storing pointers, only the pointer is copied to @p targetbuf. 691 * If the list is storing pointers, only the pointer is copied to @p targetbuf.
715 * 692 *
716 * @param list (@c CxList*) the list 693 * @param list (@c CxList*) the list
717 * @param targetbuf (@c void*) a buffer where to copy the element 694 * @param targetbuf (@c void*) a buffer where to copy the element
718 * @retval zero success 695 * @retval zero success
719 * @retval non-zero list is empty 696 * @retval non-zero the list is empty
720 * @see cxListRemoveAndGetLast() 697 * @see cxListRemoveAndGetLast()
721 * @see cxListPopFront() 698 * @see cxListPopFront()
722 */ 699 */
723 #define cxListPop(list, targetbuf) cxListRemoveAndGetLast((list), (targetbuf)) 700 #define cxListPop(list, targetbuf) cxListRemoveAndGetLast((list), (targetbuf))
724 701
736 * @param index the index of the element 713 * @param index the index of the element
737 * @param num the number of elements to remove 714 * @param num the number of elements to remove
738 * @return the actual number of removed elements 715 * @return the actual number of removed elements
739 */ 716 */
740 cx_attr_nonnull 717 cx_attr_nonnull
741 static inline size_t cxListRemoveArray( 718 CX_EXPORT size_t cxListRemoveArray(CxList *list, size_t index, size_t num);
742 CxList *list,
743 size_t index,
744 size_t num
745 ) {
746 return list->cl->remove(list, index, num, NULL);
747 }
748 719
749 /** 720 /**
750 * Removes and returns multiple elements starting at the specified index. 721 * Removes and returns multiple elements starting at the specified index.
751 * 722 *
752 * 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
757 * @param index the index of the element 728 * @param index the index of the element
758 * @param num the number of elements to remove 729 * @param num the number of elements to remove
759 * @param targetbuf a buffer where to copy the elements 730 * @param targetbuf a buffer where to copy the elements
760 * @return the actual number of removed elements 731 * @return the actual number of removed elements
761 */ 732 */
762 cx_attr_nonnull 733 cx_attr_nonnull cx_attr_access_w(4)
763 cx_attr_access_w(4) 734 CX_EXPORT size_t cxListRemoveArrayAndGet(CxList *list, size_t index, size_t num, void *targetbuf);
764 static inline size_t cxListRemoveArrayAndGet(
765 CxList *list,
766 size_t index,
767 size_t num,
768 void *targetbuf
769 ) {
770 return list->cl->remove(list, index, num, targetbuf);
771 }
772 735
773 /** 736 /**
774 * Removes all elements from this list. 737 * Removes all elements from this list.
775 * 738 *
776 * If element destructor functions are specified, they are called for each 739 * If element destructor functions are specified, they are called for each
777 * element before removing them. 740 * element before removing them.
778 * 741 *
779 * @param list the list 742 * @param list the list
780 */ 743 */
781 cx_attr_nonnull 744 cx_attr_nonnull
782 static inline void cxListClear(CxList *list) { 745 CX_EXPORT void cxListClear(CxList *list);
783 list->collection.sorted = true; // empty lists are always sorted
784 list->cl->clear(list);
785 }
786 746
787 /** 747 /**
788 * Swaps two items in the list. 748 * Swaps two items in the list.
789 * 749 *
790 * Implementations should only allocate temporary memory for the swap if 750 * Implementations should only allocate temporary memory for the swap if
796 * @retval zero success 756 * @retval zero success
797 * @retval non-zero one of the indices is out of bounds, 757 * @retval non-zero one of the indices is out of bounds,
798 * or the swap needed extra memory, but allocation failed 758 * or the swap needed extra memory, but allocation failed
799 */ 759 */
800 cx_attr_nonnull 760 cx_attr_nonnull
801 static inline int cxListSwap( 761 CX_EXPORT int cxListSwap(CxList *list, size_t i, size_t j);
802 CxList *list,
803 size_t i,
804 size_t j
805 ) {
806 list->collection.sorted = false;
807 return list->cl->swap(list, i, j);
808 }
809 762
810 /** 763 /**
811 * Returns a pointer to the element at the specified index. 764 * Returns a pointer to the element at the specified index.
812 * 765 *
813 * 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.
815 * @param list the list 768 * @param list the list
816 * @param index the index of the element 769 * @param index the index of the element
817 * @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
818 */ 771 */
819 cx_attr_nonnull 772 cx_attr_nonnull
820 static inline void *cxListAt( 773 CX_EXPORT void *cxListAt(const CxList *list, size_t index);
821 const CxList *list,
822 size_t index
823 ) {
824 return list->cl->at(list, index);
825 }
826 774
827 /** 775 /**
828 * Returns a pointer to the first element. 776 * Returns a pointer to the first element.
829 * 777 *
830 * 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.
831 * 779 *
832 * @param list the list 780 * @param list the list
833 * @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
834 */ 782 */
835 cx_attr_nonnull 783 cx_attr_nonnull
836 static inline void *cxListFirst(const CxList *list) { 784 CX_EXPORT void *cxListFirst(const CxList *list);
837 return list->cl->at(list, 0);
838 }
839 785
840 /** 786 /**
841 * Returns a pointer to the last element. 787 * Returns a pointer to the last element.
842 * 788 *
843 * 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.
844 * 790 *
845 * @param list the list 791 * @param list the list
846 * @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
847 */ 793 */
848 cx_attr_nonnull 794 cx_attr_nonnull
849 static inline void *cxListLast(const CxList *list) { 795 CX_EXPORT void *cxListLast(const CxList *list);
850 return list->cl->at(list, list->collection.size - 1); 796
851 } 797 /**
852 798 * Sets the element at the specified index in the list.
853 /** 799 *
854 * 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.
855 * 802 *
856 * @param list the list to set the element in 803 * @param list the list to set the element in
857 * @param index the index to set the element at 804 * @param index the index to set the element at
858 * @param elem element to set 805 * @param elem element to set
859 * @retval zero on success 806 * @retval zero on success
860 * @retval non-zero when index is out of bounds 807 * @retval non-zero when index is out of bounds
861 */ 808 */
862 cx_attr_nonnull 809 cx_attr_nonnull
863 cx_attr_export 810 CX_EXPORT int cxListSet(CxList *list, size_t index, const void *elem);
864 int cxListSet(
865 CxList *list,
866 size_t index,
867 const void *elem
868 );
869 811
870 /** 812 /**
871 * Returns an iterator pointing to the item at the specified index. 813 * Returns an iterator pointing to the item at the specified index.
872 * 814 *
873 * The returned iterator is position-aware. 815 * The returned iterator is position-aware.
874 * 816 *
875 * If the index is out of range, a past-the-end iterator will be returned. 817 * If the index is out of range or @p list is @c NULL, a past-the-end iterator will be returned.
876 * 818 *
877 * @param list the list 819 * @param list the list
878 * @param index the index where the iterator shall point at 820 * @param index the index where the iterator shall point at
879 * @return a new iterator 821 * @return a new iterator
880 */ 822 */
881 cx_attr_nonnull
882 cx_attr_nodiscard 823 cx_attr_nodiscard
883 static inline CxIterator cxListIteratorAt( 824 CX_EXPORT CxIterator cxListIteratorAt(const CxList *list, size_t index);
884 const CxList *list,
885 size_t index
886 ) {
887 return list->cl->iterator(list, index, false);
888 }
889 825
890 /** 826 /**
891 * Returns a backwards iterator pointing to the item at the specified index. 827 * Returns a backwards iterator pointing to the item at the specified index.
892 * 828 *
893 * The returned iterator is position-aware. 829 * The returned iterator is position-aware.
894 * 830 *
895 * If the index is out of range, a past-the-end iterator will be returned. 831 * If the index is out of range or @p list is @c NULL, a past-the-end iterator will be returned.
896 * 832 *
897 * @param list the list 833 * @param list the list
898 * @param index the index where the iterator shall point at 834 * @param index the index where the iterator shall point at
899 * @return a new iterator 835 * @return a new iterator
900 */ 836 */
901 cx_attr_nonnull
902 cx_attr_nodiscard 837 cx_attr_nodiscard
903 static inline CxIterator cxListBackwardsIteratorAt( 838 CX_EXPORT CxIterator cxListBackwardsIteratorAt(const CxList *list, size_t index);
904 const CxList *list, 839
905 size_t index 840 /**
906 ) { 841 * Returns an iterator pointing to the first item of the list.
907 return list->cl->iterator(list, index, true);
908 }
909
910 /**
911 * Returns a mutating iterator pointing to the item at the specified index.
912 * 842 *
913 * The returned iterator is position-aware. 843 * The returned iterator is position-aware.
914 * 844 *
915 * If the index is out of range, 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.
916 * 846 *
917 * @param list the list 847 * @param list the list
918 * @param index the index where the iterator shall point at
919 * @return a new iterator 848 * @return a new iterator
920 */ 849 */
921 cx_attr_nonnull
922 cx_attr_nodiscard 850 cx_attr_nodiscard
923 cx_attr_export 851 CX_EXPORT CxIterator cxListIterator(const CxList *list);
924 CxIterator cxListMutIteratorAt( 852
925 CxList *list, 853 /**
926 size_t index 854 * Returns a backwards iterator pointing to the last item of the list.
927 );
928
929 /**
930 * Returns a mutating backwards iterator pointing to the item at the
931 * specified index.
932 * 855 *
933 * The returned iterator is position-aware. 856 * The returned iterator is position-aware.
934 * 857 *
935 * If the index is out of range, 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.
936 * 859 *
937 * @param list the list 860 * @param list the list
938 * @param index the index where the iterator shall point at
939 * @return a new iterator 861 * @return a new iterator
940 */ 862 */
941 cx_attr_nonnull
942 cx_attr_nodiscard 863 cx_attr_nodiscard
943 cx_attr_export 864 CX_EXPORT CxIterator cxListBackwardsIterator(const CxList *list);
944 CxIterator cxListMutBackwardsIteratorAt(
945 CxList *list,
946 size_t index
947 );
948
949 /**
950 * Returns an iterator pointing to the first item of the list.
951 *
952 * The returned iterator is position-aware.
953 *
954 * If the list is empty or @c NULL, a past-the-end iterator will be returned.
955 *
956 * @param list the list
957 * @return a new iterator
958 */
959 cx_attr_nodiscard
960 static inline CxIterator cxListIterator(const CxList *list) {
961 if (list == NULL) list = cxEmptyList;
962 return list->cl->iterator(list, 0, false);
963 }
964
965 /**
966 * Returns a mutating iterator pointing to the first item of the list.
967 *
968 * The returned iterator is position-aware.
969 *
970 * If the list is empty or @c NULL, a past-the-end iterator will be returned.
971 *
972 * @param list the list
973 * @return a new iterator
974 */
975 cx_attr_nodiscard
976 static inline CxIterator cxListMutIterator(CxList *list) {
977 if (list == NULL) list = cxEmptyList;
978 return cxListMutIteratorAt(list, 0);
979 }
980
981
982 /**
983 * Returns a backwards iterator pointing to the last item of the list.
984 *
985 * The returned iterator is position-aware.
986 *
987 * If the list is empty or @c NULL, a past-the-end iterator will be returned.
988 *
989 * @param list the list
990 * @return a new iterator
991 */
992 cx_attr_nodiscard
993 static inline CxIterator cxListBackwardsIterator(const CxList *list) {
994 if (list == NULL) list = cxEmptyList;
995 return list->cl->iterator(list, list->collection.size - 1, true);
996 }
997
998 /**
999 * Returns a mutating backwards iterator pointing to the last item of the list.
1000 *
1001 * The returned iterator is position-aware.
1002 *
1003 * If the list is empty or @c NULL, a past-the-end iterator will be returned.
1004 *
1005 * @param list the list
1006 * @return a new iterator
1007 */
1008 cx_attr_nodiscard
1009 static inline CxIterator cxListMutBackwardsIterator(CxList *list) {
1010 if (list == NULL) list = cxEmptyList;
1011 return cxListMutBackwardsIteratorAt(list, list->collection.size - 1);
1012 }
1013 865
1014 /** 866 /**
1015 * Returns the index of the first element that equals @p elem. 867 * Returns the index of the first element that equals @p elem.
1016 * 868 *
1017 * Determining equality is performed by the list's comparator function. 869 * Determining equality is performed by the list's comparator function.
1020 * @param elem the element to find 872 * @param elem the element to find
1021 * @return the index of the element or the size of the list when the element is not found 873 * @return the index of the element or the size of the list when the element is not found
1022 * @see cxListIndexValid() 874 * @see cxListIndexValid()
1023 * @see cxListContains() 875 * @see cxListContains()
1024 */ 876 */
1025 cx_attr_nonnull 877 cx_attr_nonnull cx_attr_nodiscard
1026 cx_attr_nodiscard 878 CX_EXPORT size_t cxListFind(const CxList *list, const void *elem);
1027 static inline size_t cxListFind( 879
1028 const CxList *list, 880 /**
1029 const void *elem 881 * Checks if the list contains the specified element.
1030 ) {
1031 return list->cl->find_remove((CxList*)list, elem, false);
1032 }
1033
1034 /**
1035 * Checks, if the list contains the specified element.
1036 * 882 *
1037 * The elements are compared with the list's comparator function. 883 * The elements are compared with the list's comparator function.
1038 * 884 *
1039 * @param list the list 885 * @param list the list
1040 * @param elem the element to find 886 * @param elem the element to find
1041 * @retval true if the element is contained 887 * @retval true if the element is contained
1042 * @retval false if the element is not contained 888 * @retval false if the element is not contained
1043 * @see cxListFind() 889 * @see cxListFind()
1044 */ 890 */
1045 cx_attr_nonnull 891 cx_attr_nonnull cx_attr_nodiscard
1046 cx_attr_nodiscard 892 CX_EXPORT bool cxListContains(const CxList* list, const void* elem);
1047 static inline bool cxListContains(
1048 const CxList* list,
1049 const void* elem
1050 ) {
1051 return list->cl->find_remove((CxList*)list, elem, false) < list->collection.size;
1052 }
1053 893
1054 /** 894 /**
1055 * Checks if the specified index is within bounds. 895 * Checks if the specified index is within bounds.
1056 * 896 *
1057 * @param list the list 897 * @param list the list
1058 * @param index the index 898 * @param index the index
1059 * @retval true if the index is within bounds 899 * @retval true if the index is within bounds
1060 * @retval false if the index is out of bounds 900 * @retval false if the index is out of bounds
1061 */ 901 */
1062 cx_attr_nonnull 902 cx_attr_nonnull cx_attr_nodiscard
1063 cx_attr_nodiscard 903 CX_EXPORT bool cxListIndexValid(const CxList *list, size_t index);
1064 static inline bool cxListIndexValid(const CxList *list, size_t index) {
1065 return index < list->collection.size;
1066 }
1067 904
1068 /** 905 /**
1069 * 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.
1070 * 907 *
1071 * Determining equality is performed by the list's comparator function. 908 * Determining equality is performed by the list's comparator function.
1075 * @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
1076 * when the element is not found or could not be removed 913 * when the element is not found or could not be removed
1077 * @see cxListIndexValid() 914 * @see cxListIndexValid()
1078 */ 915 */
1079 cx_attr_nonnull 916 cx_attr_nonnull
1080 static inline size_t cxListFindRemove( 917 CX_EXPORT size_t cxListFindRemove(CxList *list, const void *elem);
1081 CxList *list,
1082 const void *elem
1083 ) {
1084 return list->cl->find_remove(list, elem, true);
1085 }
1086 918
1087 /** 919 /**
1088 * Sorts the list. 920 * Sorts the list.
1089 * 921 *
1090 * @remark The underlying sort algorithm is implementation defined. 922 * @remark The underlying sort algorithm is implementation defined.
1091 * 923 *
1092 * @param list the list 924 * @param list the list
1093 */ 925 */
1094 cx_attr_nonnull 926 cx_attr_nonnull
1095 static inline void cxListSort(CxList *list) { 927 CX_EXPORT void cxListSort(CxList *list);
1096 if (list->collection.sorted) return;
1097 list->cl->sort(list);
1098 list->collection.sorted = true;
1099 }
1100 928
1101 /** 929 /**
1102 * Reverses the order of the items. 930 * Reverses the order of the items.
1103 * 931 *
1104 * @param list the list 932 * @param list the list
1105 */ 933 */
1106 cx_attr_nonnull 934 cx_attr_nonnull
1107 static inline void cxListReverse(CxList *list) { 935 CX_EXPORT void cxListReverse(CxList *list);
1108 // still sorted, but not according to the cmp_func
1109 list->collection.sorted = false;
1110 list->cl->reverse(list);
1111 }
1112 936
1113 /** 937 /**
1114 * Compares a list to another list of the same type. 938 * Compares a list to another list of the same type.
1115 * 939 *
1116 * First, the list sizes are compared. 940 * First, the list sizes are compared.
1117 * If they match, the lists are compared element-wise. 941 * If they match, the lists are compared element-wise.
1118 * 942 *
1119 * @param list the list 943 * @param list the list
1120 * @param other the list to compare to 944 * @param other the list to compare to
1121 * @retval zero both lists are equal element wise 945 * @retval zero both lists are equal element wise
1122 * @retval negative the first list is smaller 946 * @retval negative the first list is smaller,
1123 * 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
1124 * @retval positive the first list is larger 948 * @retval positive the first list is larger
1125 * 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
1126 */ 950 */
1127 cx_attr_nonnull 951 cx_attr_nonnull cx_attr_nodiscard
1128 cx_attr_nodiscard 952 CX_EXPORT int cxListCompare(const CxList *list, const CxList *other);
1129 cx_attr_export
1130 int cxListCompare(
1131 const CxList *list,
1132 const CxList *other
1133 );
1134 953
1135 /** 954 /**
1136 * Deallocates the memory of the specified list structure. 955 * Deallocates the memory of the specified list structure.
1137 * 956 *
1138 * Also calls the content destructor functions for each element, if specified. 957 * Also calls the content destructor functions for each element, if specified.
1139 * 958 *
1140 * @param list the list which shall be freed 959 * @param list the list that shall be freed
1141 */ 960 */
1142 cx_attr_export 961 CX_EXPORT void cxListFree(CxList *list);
1143 void cxListFree(CxList *list); 962
1144 963
964 /**
965 * Performs a deep clone of one list into another.
966 *
967 * If the destination list already contains elements, the cloned elements
968 * are appended to that list.
969 *
970 * @attention If the cloned elements need to be destroyed by a destructor
971 * function, you must make sure that the destination list also uses this
972 * destructor function.
973 *
974 * @param dst the destination list
975 * @param src the source list
976 * @param clone_func the clone function for the elements
977 * @param clone_allocator the allocator that is passed to the clone function
978 * @param data optional additional data that is passed to the clone function
979 * @retval zero when all elements were successfully cloned
980 * @retval non-zero when an allocation error occurred
981 * @see cxListCloneSimple()
982 */
983 cx_attr_nonnull_arg(1, 2, 3)
984 CX_EXPORT int cxListClone(CxList *dst, const CxList *src,
985 cx_clone_func clone_func, const CxAllocator *clone_allocator, void *data);
986
987 /**
988 * Clones elements from a list only if they are not present in another list.
989 *
990 * If the @p minuend does not contain duplicates, this is equivalent to adding
991 * the set difference to the destination list.
992 *
993 * This function is optimized for the case when both the @p minuend and the
994 * @p subtrahend are sorted.
995 *
996 * @param dst the destination list
997 * @param minuend the list to subtract elements from
998 * @param subtrahend the elements that shall be subtracted
999 * @param clone_func the clone function for the elements
1000 * @param clone_allocator the allocator that is passed to the clone function
1001 * @param data optional additional data that is passed to the clone function
1002 * @retval zero when the elements were successfully cloned
1003 * @retval non-zero when an allocation error occurred
1004 * @see cxListDifferenceSimple()
1005 */
1006 cx_attr_nonnull_arg(1, 2, 3, 4)
1007 CX_EXPORT int cxListDifference(CxList *dst,
1008 const CxList *minuend, const CxList *subtrahend,
1009 cx_clone_func clone_func, const CxAllocator *clone_allocator, void *data);
1010
1011 /**
1012 * Clones elements from a list only if they are also present in another list.
1013 *
1014 * This function is optimized for the case when both the @p src and the
1015 * @p other list are sorted.
1016 *
1017 * If the destination list already contains elements, the intersection is appended
1018 * to that list.
1019 *
1020 * @param dst the destination list
1021 * @param src the list to clone the elements from
1022 * @param other the list to check the elements for existence
1023 * @param clone_func the clone function for the elements
1024 * @param clone_allocator the allocator that is passed to the clone function
1025 * @param data optional additional data that is passed to the clone function
1026 * @retval zero when the elements were successfully cloned
1027 * @retval non-zero when an allocation error occurred
1028 * @see cxListIntersectionSimple()
1029 */
1030 cx_attr_nonnull_arg(1, 2, 3, 4)
1031 CX_EXPORT int cxListIntersection(CxList *dst, const CxList *src, const CxList *other,
1032 cx_clone_func clone_func, const CxAllocator *clone_allocator, void *data);
1033
1034 /**
1035 * Performs a deep clone of one list into another, skipping duplicates.
1036 *
1037 * This function is optimized for the case when both the @p src and the
1038 * @p other list are sorted.
1039 * In that case, the union will also be sorted.
1040 *
1041 * If the destination list already contains elements, the union is appended
1042 * to that list. In that case the destination is not necessarily sorted.
1043 *
1044 * @param dst the destination list
1045 * @param src the primary source list
1046 * @param other the other list, where elements are only cloned from
1047 * when they are not in @p src
1048 * @param clone_func the clone function for the elements
1049 * @param clone_allocator the allocator that is passed to the clone function
1050 * @param data optional additional data that is passed to the clone function
1051 * @retval zero when the elements were successfully cloned
1052 * @retval non-zero when an allocation error occurred
1053 * @see cxListUnionSimple()
1054 */
1055 cx_attr_nonnull_arg(1, 2, 3, 4)
1056 CX_EXPORT int cxListUnion(CxList *dst, const CxList *src, const CxList *other,
1057 cx_clone_func clone_func, const CxAllocator *clone_allocator, void *data);
1058
1059 /**
1060 * Performs a shallow clone of one list into another.
1061 *
1062 * This function uses the default allocator, if needed, and performs
1063 * shallow clones with @c memcpy().
1064 *
1065 * If the destination list already contains elements, the cloned elements
1066 * are appended to that list.
1067 *
1068 * @attention If the cloned elements need to be destroyed by a destructor
1069 * function, you must make sure that the destination list also uses this
1070 * destructor function.
1071 *
1072 * @param dst the destination list
1073 * @param src the source list
1074 * @retval zero when all elements were successfully cloned
1075 * @retval non-zero when an allocation error occurred
1076 * @see cxListClone()
1077 */
1078 cx_attr_nonnull
1079 CX_EXPORT int cxListCloneSimple(CxList *dst, const CxList *src);
1080
1081 /**
1082 * Clones elements from a list only if they are not present in another list.
1083 *
1084 * This function uses the default allocator, if needed, and performs
1085 * shallow clones with @c memcpy().
1086 *
1087 * If the @p minuend does not contain duplicates, this is equivalent to adding
1088 * the set difference to the destination list.
1089 *
1090 * This function is optimized for the case when both the @p minuend and the
1091 * @p subtrahend are sorted.
1092 *
1093 * @param dst the destination list
1094 * @param minuend the list to subtract elements from
1095 * @param subtrahend the elements that shall be subtracted
1096 * @retval zero when the elements were successfully cloned
1097 * @retval non-zero when an allocation error occurred
1098 * @see cxListDifference()
1099 */
1100 cx_attr_nonnull
1101 CX_EXPORT int cxListDifferenceSimple(CxList *dst,
1102 const CxList *minuend, const CxList *subtrahend);
1103
1104 /**
1105 * Clones elements from a list only if they are also present in another list.
1106 *
1107 * This function uses the default allocator, if needed, and performs
1108 * shallow clones with @c memcpy().
1109 *
1110 * This function is optimized for the case when both the @p src and the
1111 * @p other list are sorted.
1112 *
1113 * If the destination list already contains elements, the intersection is appended
1114 * to that list.
1115 *
1116 * @param dst the destination list
1117 * @param src the list to clone the elements from
1118 * @param other the list to check the elements for existence
1119 * @retval zero when the elements were successfully cloned
1120 * @retval non-zero when an allocation error occurred
1121 * @see cxListIntersection()
1122 */
1123 cx_attr_nonnull
1124 CX_EXPORT int cxListIntersectionSimple(CxList *dst, const CxList *src, const CxList *other);
1125
1126 /**
1127 * Performs a deep clone of one list into another, skipping duplicates.
1128 *
1129 * This function uses the default allocator, if needed, and performs
1130 * shallow clones with @c memcpy().
1131 *
1132 * This function is optimized for the case when both the @p src and the
1133 * @p other list are sorted.
1134 * In that case, the union will also be sorted.
1135 *
1136 * If the destination list already contains elements, the union is appended
1137 * to that list. In that case the destination is not necessarily sorted.
1138 *
1139 * @param dst the destination list
1140 * @param src the primary source list
1141 * @param other the other list, where elements are only cloned from
1142 * when they are not in @p src
1143 * @retval zero when the elements were successfully cloned
1144 * @retval non-zero when an allocation error occurred
1145 * @see cxListUnion()
1146 */
1147 cx_attr_nonnull
1148 CX_EXPORT int cxListUnionSimple(CxList *dst, const CxList *src, const CxList *other);
1145 1149
1146 #ifdef __cplusplus 1150 #ifdef __cplusplus
1147 } // extern "C" 1151 } // extern "C"
1148 #endif 1152 #endif
1149 1153

mercurial