ucx/cx/list.h

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

mercurial