ucx/cx/list.h

changeset 888
af685cc9d623
parent 854
1c8401ece69e
equal deleted inserted replaced
877:b60487c3ec36 888:af685cc9d623
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 */ 83 * The data pointer may be @c NULL, in which case the function shall only allocate memory.
84 int (*insert_element)( 84 * Returns a pointer to the allocated memory or @c NULL if allocation fails.
85 struct cx_list_s *list, 85 */
86 size_t index, 86 void *(*insert_element)(struct cx_list_s *list, size_t index, const void *data);
87 const void *data
88 );
89 87
90 /** 88 /**
91 * Member function for inserting multiple elements. 89 * Member function for inserting multiple elements.
92 * 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 *
93 * @see cx_list_default_insert_array() 94 * @see cx_list_default_insert_array()
94 */ 95 */
95 size_t (*insert_array)( 96 size_t (*insert_array)(struct cx_list_s *list, size_t index, const void *data, size_t n);
96 struct cx_list_s *list,
97 size_t index,
98 const void *data,
99 size_t n
100 );
101 97
102 /** 98 /**
103 * 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.
104 * 101 *
105 * @see cx_list_default_insert_sorted() 102 * @see cx_list_default_insert_sorted()
106 */ 103 */
107 size_t (*insert_sorted)( 104 size_t (*insert_sorted)(struct cx_list_s *list, const void *sorted_data, size_t n);
108 struct cx_list_s *list, 105
109 const void *sorted_data, 106 /**
110 size_t n 107 * Member function for inserting multiple elements if they do not exist.
111 ); 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);
112 113
113 /** 114 /**
114 * Member function for inserting an element relative to an iterator position. 115 * Member function for inserting an element relative to an iterator position.
115 */ 116 */
116 int (*insert_iter)( 117 int (*insert_iter)(struct cx_iterator_s *iter, const void *elem, int prepend);
117 struct cx_iterator_s *iter,
118 const void *elem,
119 int prepend
120 );
121 118
122 /** 119 /**
123 * Member function for removing elements. 120 * Member function for removing elements.
124 * 121 *
125 * 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
127 * When @p targetbuf is not set, the destructors SHALL be invoked. 124 * When @p targetbuf is not set, the destructors SHALL be invoked.
128 * 125 *
129 * The function SHALL return the actual number of elements removed, which 126 * The function SHALL return the actual number of elements removed, which
130 * might be lower than @p num when going out of bounds. 127 * might be lower than @p num when going out of bounds.
131 */ 128 */
132 size_t (*remove)( 129 size_t (*remove)(struct cx_list_s *list, size_t index, size_t num, void *targetbuf);
133 struct cx_list_s *list,
134 size_t index,
135 size_t num,
136 void *targetbuf
137 );
138 130
139 /** 131 /**
140 * Member function for removing all elements. 132 * Member function for removing all elements.
141 */ 133 */
142 void (*clear)(struct cx_list_s *list); 134 void (*clear)(struct cx_list_s *list);
144 /** 136 /**
145 * Member function for swapping two elements. 137 * Member function for swapping two elements.
146 * 138 *
147 * @see cx_list_default_swap() 139 * @see cx_list_default_swap()
148 */ 140 */
149 int (*swap)( 141 int (*swap)(struct cx_list_s *list, size_t i, size_t j);
150 struct cx_list_s *list,
151 size_t i,
152 size_t j
153 );
154 142
155 /** 143 /**
156 * Member function for element lookup. 144 * Member function for element lookup.
157 */ 145 */
158 void *(*at)( 146 void *(*at)(const struct cx_list_s *list, size_t index);
159 const struct cx_list_s *list,
160 size_t index
161 );
162 147
163 /** 148 /**
164 * Member function for finding and optionally removing an element. 149 * Member function for finding and optionally removing an element.
165 */ 150 */
166 size_t (*find_remove)( 151 size_t (*find_remove)(struct cx_list_s *list, const void *elem, bool remove);
167 struct cx_list_s *list,
168 const void *elem,
169 bool remove
170 );
171 152
172 /** 153 /**
173 * Member function for sorting the list. 154 * Member function for sorting the list.
174 * 155 *
175 * @see cx_list_default_sort() 156 * @see cx_list_default_sort()
177 void (*sort)(struct cx_list_s *list); 158 void (*sort)(struct cx_list_s *list);
178 159
179 /** 160 /**
180 * Optional member function for comparing this list 161 * Optional member function for comparing this list
181 * to another list of the same type. 162 * to another list of the same type.
182 * If set to @c NULL, comparison won't be optimized. 163 * If set to @c NULL, the comparison won't be optimized.
183 */ 164 */
184 cx_attr_nonnull 165 int (*compare)(const struct cx_list_s *list, const struct cx_list_s *other);
185 int (*compare)(
186 const struct cx_list_s *list,
187 const struct cx_list_s *other
188 );
189 166
190 /** 167 /**
191 * Member function for reversing the order of the items. 168 * Member function for reversing the order of the items.
192 */ 169 */
193 void (*reverse)(struct cx_list_s *list); 170 void (*reverse)(struct cx_list_s *list);
194 171
195 /** 172 /**
196 * Member function for returning an iterator pointing to the specified index. 173 * Member function for returning an iterator pointing to the specified index.
197 */ 174 */
198 struct cx_iterator_s (*iterator)( 175 struct cx_iterator_s (*iterator)(const struct cx_list_s *list, size_t index, bool backward);
199 const struct cx_list_s *list,
200 size_t index,
201 bool backward
202 );
203 }; 176 };
177
178 /**
179 * Common type for all list implementations.
180 */
181 typedef struct cx_list_s CxList;
182
183 /**
184 * A shared instance of an empty list.
185 *
186 * Writing to that list is not allowed.
187 *
188 * You can use this as a placeholder for initializing CxList pointers
189 * for which you do not want to reserve memory right from the beginning.
190 */
191 CX_EXPORT extern CxList *const cxEmptyList;
204 192
205 /** 193 /**
206 * Default implementation of an array insert. 194 * Default implementation of an array insert.
207 * 195 *
208 * 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.
215 * @param data a pointer to the array of data to insert 203 * @param data a pointer to the array of data to insert
216 * @param n the number of elements to insert 204 * @param n the number of elements to insert
217 * @return the number of elements actually inserted 205 * @return the number of elements actually inserted
218 */ 206 */
219 cx_attr_nonnull 207 cx_attr_nonnull
220 cx_attr_export 208 CX_EXPORT size_t cx_list_default_insert_array(struct cx_list_s *list,
221 size_t cx_list_default_insert_array( 209 size_t index, const void *data, size_t n);
222 struct cx_list_s *list,
223 size_t index,
224 const void *data,
225 size_t n
226 );
227 210
228 /** 211 /**
229 * Default implementation of a sorted insert. 212 * Default implementation of a sorted insert.
230 * 213 *
231 * This function uses the array insert function to insert consecutive groups 214 * This function uses the array insert function to insert consecutive groups
240 * @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
241 * @param n the number of elements to insert 224 * @param n the number of elements to insert
242 * @return the number of elements actually inserted 225 * @return the number of elements actually inserted
243 */ 226 */
244 cx_attr_nonnull 227 cx_attr_nonnull
245 cx_attr_export 228 CX_EXPORT size_t cx_list_default_insert_sorted(struct cx_list_s *list,
246 size_t cx_list_default_insert_sorted( 229 const void *sorted_data, size_t n);
247 struct cx_list_s *list, 230
248 const void *sorted_data, 231 /**
249 size_t n 232 * Default implementation of an array insert where only elements are inserted when they don't exist in the list.
250 ); 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);
251 250
252 /** 251 /**
253 * Default unoptimized sort implementation. 252 * Default unoptimized sort implementation.
254 * 253 *
255 * 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
259 * version for your list. 258 * version for your list.
260 * 259 *
261 * @param list the list that shall be sorted 260 * @param list the list that shall be sorted
262 */ 261 */
263 cx_attr_nonnull 262 cx_attr_nonnull
264 cx_attr_export 263 CX_EXPORT void cx_list_default_sort(struct cx_list_s *list);
265 void cx_list_default_sort(struct cx_list_s *list);
266 264
267 /** 265 /**
268 * Default unoptimized swap implementation. 266 * Default unoptimized swap implementation.
269 * 267 *
270 * 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
276 * @retval zero success 274 * @retval zero success
277 * @retval non-zero when indices are out of bounds or memory 275 * @retval non-zero when indices are out of bounds or memory
278 * allocation for the temporary buffer fails 276 * allocation for the temporary buffer fails
279 */ 277 */
280 cx_attr_nonnull 278 cx_attr_nonnull
281 cx_attr_export 279 CX_EXPORT int cx_list_default_swap(struct cx_list_s *list, size_t i, size_t j);
282 int cx_list_default_swap(struct cx_list_s *list, size_t i, size_t j);
283 280
284 /** 281 /**
285 * Initializes a list struct. 282 * Initializes a list struct.
286 * 283 *
287 * 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.
288 * 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
289 * of your list, to set certain members correctly. 286 * of your list to set certain members correctly.
290 * 287 *
291 * This is particularly important when you want your list to support 288 * This is particularly important when you want your list to support
292 * #CX_STORE_POINTERS as @p elem_size. This function will wrap the list 289 * #CX_STORE_POINTERS as @p elem_size. This function will wrap the list
293 * class accordingly and make sure that you can implement your list as if 290 * class accordingly and make sure that you can implement your list as if
294 * it was only storing objects and the wrapper will automatically enable 291 * it was only storing objects, and the wrapper will automatically enable
295 * the feature of storing pointers. 292 * the feature of storing pointers.
296 * 293 *
297 * @par Example 294 * @par Example
298 * 295 *
299 * @code 296 * @code
324 * @param allocator the allocator for the elements 321 * @param allocator the allocator for the elements
325 * @param comparator a compare function for the elements 322 * @param comparator a compare function for the elements
326 * @param elem_size the size of one element 323 * @param elem_size the size of one element
327 */ 324 */
328 cx_attr_nonnull_arg(1, 2, 3) 325 cx_attr_nonnull_arg(1, 2, 3)
329 cx_attr_export 326 CX_EXPORT void cx_list_init(struct cx_list_s *list,
330 void cx_list_init( 327 struct cx_list_class_s *cl, const struct cx_allocator_s *allocator,
331 struct cx_list_s *list, 328 cx_compare_func comparator, size_t elem_size);
332 struct cx_list_class_s *cl,
333 const struct cx_allocator_s *allocator,
334 cx_compare_func comparator,
335 size_t elem_size
336 );
337
338 /**
339 * Common type for all list implementations.
340 */
341 typedef struct cx_list_s CxList;
342 329
343 /** 330 /**
344 * Returns the number of elements currently stored in the list. 331 * Returns the number of elements currently stored in the list.
345 * 332 *
346 * @param list the list 333 * @param list the list
347 * @return the number of currently stored elements 334 * @return the number of currently stored elements
348 */ 335 */
349 cx_attr_nonnull 336 cx_attr_nonnull
350 static inline size_t cxListSize(const CxList *list) { 337 CX_EXPORT size_t cxListSize(const CxList *list);
351 return list->collection.size;
352 }
353 338
354 /** 339 /**
355 * Adds an item to the end of the list. 340 * Adds an item to the end of the list.
356 * 341 *
357 * @param list the list 342 * @param list the list
358 * @param elem a pointer to the element to add 343 * @param elem a pointer to the element to add
359 * @retval zero success 344 * @retval zero success
360 * @retval non-zero memory allocation failure 345 * @retval non-zero memory allocation failure
361 * @see cxListAddArray() 346 * @see cxListAddArray()
362 */ 347 * @see cxListEmplace()
363 cx_attr_nonnull 348 */
364 static inline int cxListAdd( 349 cx_attr_nonnull
365 CxList *list, 350 CX_EXPORT int cxListAdd(CxList *list, const void *elem);
366 const void *elem
367 ) {
368 list->collection.sorted = false;
369 return list->cl->insert_element(list, list->collection.size, elem);
370 }
371 351
372 /** 352 /**
373 * Adds multiple items to the end of the list. 353 * Adds multiple items to the end of the list.
374 * 354 *
375 * This method is more efficient than invoking cxListAdd() multiple times. 355 * This method is more efficient than invoking cxListAdd() multiple times.
376 * 356 *
377 * 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
378 * less than @p n. 358 * less than @p n.
379 * 359 *
380 * 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
381 * be an array of pointers. 361 * be an array of pointers.
382 * 362 *
383 * @param list the list 363 * @param list the list
384 * @param array a pointer to the elements to add 364 * @param array a pointer to the elements to add
385 * @param n the number of elements to add 365 * @param n the number of elements to add
386 * @return the number of added elements 366 * @return the number of added elements
387 */ 367 * @see cxListEmplaceArray()
388 cx_attr_nonnull 368 */
389 static inline size_t cxListAddArray( 369 cx_attr_nonnull
390 CxList *list, 370 CX_EXPORT size_t cxListAddArray(CxList *list, const void *array, size_t n);
391 const void *array,
392 size_t n
393 ) {
394 list->collection.sorted = false;
395 return list->cl->insert_array(list, list->collection.size, array, n);
396 }
397 371
398 /** 372 /**
399 * Inserts an item at the specified index. 373 * Inserts an item at the specified index.
400 * 374 *
401 * 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().
402 * 376 *
403 * @param list the list 377 * @param list the list
404 * @param index the index the element shall have 378 * @param index the index the element shall have
405 * @param elem a pointer to the element to add 379 * @param elem a pointer to the element to add
406 * @retval zero success 380 * @retval zero success
407 * @retval non-zero memory allocation failure or the index is out of bounds 381 * @retval non-zero memory allocation failure or the index is out of bounds
408 * @see cxListInsertAfter() 382 * @see cxListInsertAfter()
409 * @see cxListInsertBefore() 383 * @see cxListInsertBefore()
410 */ 384 * @see cxListEmplaceAt()
411 cx_attr_nonnull 385 */
412 static inline int cxListInsert( 386 cx_attr_nonnull
413 CxList *list, 387 CX_EXPORT int cxListInsert(CxList *list, size_t index, const void *elem);
414 size_t index, 388
415 const void *elem 389 /**
416 ) { 390 * Allocates memory for an element at the specified index and returns a pointer to that memory.
417 list->collection.sorted = false; 391 *
418 return list->cl->insert_element(list, index, elem); 392 * @remark When the list is storing pointers, this will return a @c void**.
419 } 393 *
394 * @param list the list
395 * @param index the index where to emplace the element
396 * @return a pointer to the allocated memory; @c NULL when the operation fails, or the index is out-of-bounds
397 * @see cxListEmplace()
398 * @see cxListEmplaceArrayAt()
399 * @see cxListInsert()
400 */
401 cx_attr_nonnull
402 CX_EXPORT void *cxListEmplaceAt(CxList *list, size_t index);
403
404 /**
405 * Allocates memory for an element at the end of the list and returns a pointer to that memory.
406 *
407 * @remark When the list is storing pointers, this will return a @c void**.
408 *
409 * @param list the list
410 * @return a pointer to the allocated memory; @c NULL when the operation fails, or the index is out-of-bounds
411 * @see cxListEmplaceAt()
412 * @see cxListAdd()
413 */
414 cx_attr_nonnull
415 CX_EXPORT void *cxListEmplace(CxList *list);
416
417 /**
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);
420 455
421 /** 456 /**
422 * Inserts an item into a sorted list. 457 * Inserts an item into a sorted list.
423 * 458 *
424 * If the list is not sorted already, the behavior is undefined. 459 * If the list is not sorted already, the behavior is undefined.
427 * @param elem a pointer to the element to add 462 * @param elem a pointer to the element to add
428 * @retval zero success 463 * @retval zero success
429 * @retval non-zero memory allocation failure 464 * @retval non-zero memory allocation failure
430 */ 465 */
431 cx_attr_nonnull 466 cx_attr_nonnull
432 static inline int cxListInsertSorted( 467 CX_EXPORT int cxListInsertSorted(CxList *list, const void *elem);
433 CxList *list, 468
434 const void *elem 469 /**
435 ) { 470 * Inserts an item into a list if it does not exist.
436 list->collection.sorted = true; // guaranteed by definition 471 *
437 const void *data = list->collection.store_pointer ? &elem : elem; 472 * If the list is not sorted already, this function will check all elements
438 return list->cl->insert_sorted(list, data, 1) == 0; 473 * and append the new element when it was not found.
439 } 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);
440 484
441 /** 485 /**
442 * Inserts multiple items to the list at the specified index. 486 * Inserts multiple items to the list at the specified index.
443 * If @p index equals the list size, this is effectively cxListAddArray(). 487 * If the @p index equals the list size, this is effectively cxListAddArray().
444 * 488 *
445 * This method is usually more efficient than invoking cxListInsert() 489 * This method is usually more efficient than invoking cxListInsert()
446 * multiple times. 490 * multiple times.
447 * 491 *
448 * 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
449 * less than @p n. 493 * less than @p n.
450 * 494 *
451 * 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
452 * be an array of pointers. 496 * be an array of pointers.
453 * 497 *
454 * @param list the list 498 * @param list the list
455 * @param index the index where to add the elements 499 * @param index the index where to add the elements
456 * @param array a pointer to the elements to add 500 * @param array a pointer to the elements to add
457 * @param n the number of elements to add 501 * @param n the number of elements to add
458 * @return the number of added elements 502 * @return the number of added elements
459 */ 503 * @see cxListEmplaceArrayAt()
460 cx_attr_nonnull 504 */
461 static inline size_t cxListInsertArray( 505 cx_attr_nonnull
462 CxList *list, 506 CX_EXPORT size_t cxListInsertArray(CxList *list, size_t index, const void *array, size_t n);
463 size_t index,
464 const void *array,
465 size_t n
466 ) {
467 list->collection.sorted = false;
468 return list->cl->insert_array(list, index, array, n);
469 }
470 507
471 /** 508 /**
472 * Inserts a sorted array into a sorted list. 509 * Inserts a sorted array into a sorted list.
473 * 510 *
474 * This method is usually more efficient than inserting each element separately, 511 * This method is usually more efficient than inserting each element separately
475 * because consecutive chunks of sorted data are inserted in one pass. 512 * because consecutive chunks of sorted data are inserted in one pass.
476 * 513 *
477 * 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
478 * less than @p n. 515 * less than @p n.
479 * 516 *
480 * 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
481 * be an array of pointers. 518 * be an array of pointers.
482 * 519 *
483 * If the list is not sorted already, the behavior is undefined. 520 * If the list is not sorted already, the behavior is undefined.
484 * 521 *
485 * @param list the list 522 * @param list the list
486 * @param array a pointer to the elements to add 523 * @param array a pointer to the elements to add
487 * @param n the number of elements to add 524 * @param n the number of elements to add
488 * @return the number of added elements 525 * @return the number of added elements
489 */ 526 */
490 cx_attr_nonnull 527 cx_attr_nonnull
491 static inline size_t cxListInsertSortedArray( 528 CX_EXPORT size_t cxListInsertSortedArray(CxList *list, const void *array, size_t n);
492 CxList *list, 529
493 const void *array, 530 /**
494 size_t n 531 * Inserts an array into a list, skipping duplicates.
495 ) { 532 *
496 list->collection.sorted = true; // guaranteed by definition 533 * The @p list does not need to be sorted (in contrast to cxListInsertSortedArray()).
497 return list->cl->insert_sorted(list, array, n); 534 * But it is strongly recommended to use this function only on sorted lists,
498 } 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);
499 564
500 /** 565 /**
501 * Inserts an element after the current location of the specified iterator. 566 * Inserts an element after the current location of the specified iterator.
502 * 567 *
503 * The used iterator remains operational, but all other active iterators should 568 * The used iterator remains operational, but all other active iterators should
512 * @retval non-zero memory allocation failure 577 * @retval non-zero memory allocation failure
513 * @see cxListInsert() 578 * @see cxListInsert()
514 * @see cxListInsertBefore() 579 * @see cxListInsertBefore()
515 */ 580 */
516 cx_attr_nonnull 581 cx_attr_nonnull
517 static inline int cxListInsertAfter( 582 CX_EXPORT int cxListInsertAfter(CxIterator *iter, const void *elem);
518 CxIterator *iter,
519 const void *elem
520 ) {
521 CxList* list = (CxList*)iter->src_handle.m;
522 list->collection.sorted = false;
523 return list->cl->insert_iter(iter, elem, 0);
524 }
525 583
526 /** 584 /**
527 * Inserts an element before the current location of the specified iterator. 585 * Inserts an element before the current location of the specified iterator.
528 * 586 *
529 * The used iterator remains operational, but all other active iterators should 587 * The used iterator remains operational, but all other active iterators should
538 * @retval non-zero memory allocation failure 596 * @retval non-zero memory allocation failure
539 * @see cxListInsert() 597 * @see cxListInsert()
540 * @see cxListInsertAfter() 598 * @see cxListInsertAfter()
541 */ 599 */
542 cx_attr_nonnull 600 cx_attr_nonnull
543 static inline int cxListInsertBefore( 601 CX_EXPORT int cxListInsertBefore(CxIterator *iter, const void *elem);
544 CxIterator *iter,
545 const void *elem
546 ) {
547 CxList* list = (CxList*)iter->src_handle.m;
548 list->collection.sorted = false;
549 return list->cl->insert_iter(iter, elem, 1);
550 }
551 602
552 /** 603 /**
553 * Removes the element at the specified index. 604 * Removes the element at the specified index.
554 * 605 *
555 * If an element destructor function is specified, it is called before 606 * If an element destructor function is specified, it is called before
559 * @param index the index of the element 610 * @param index the index of the element
560 * @retval zero success 611 * @retval zero success
561 * @retval non-zero index out of bounds 612 * @retval non-zero index out of bounds
562 */ 613 */
563 cx_attr_nonnull 614 cx_attr_nonnull
564 static inline int cxListRemove( 615 CX_EXPORT int cxListRemove(CxList *list, size_t index);
565 CxList *list,
566 size_t index
567 ) {
568 return list->cl->remove(list, index, 1, NULL) == 0;
569 }
570 616
571 /** 617 /**
572 * Removes and returns the element at the specified index. 618 * Removes and returns the element at the specified index.
573 * 619 *
574 * 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
575 * @p targetbuf which MUST be large enough to hold the removed element. 621 * @p targetbuf which MUST be large enough to hold the removed element.
622 * If the list is storing pointers, only the pointer is copied to @p targetbuf.
576 * 623 *
577 * @param list the list 624 * @param list the list
578 * @param index the index of the element 625 * @param index the index of the element
579 * @param targetbuf a buffer where to copy the element 626 * @param targetbuf a buffer where to copy the element
580 * @retval zero success 627 * @retval zero success
581 * @retval non-zero index out of bounds 628 * @retval non-zero index out of bounds
582 */ 629 */
583 cx_attr_nonnull 630 cx_attr_nonnull cx_attr_access_w(3)
584 cx_attr_access_w(3) 631 CX_EXPORT int cxListRemoveAndGet(CxList *list, size_t index, void *targetbuf);
585 static inline int cxListRemoveAndGet( 632
586 CxList *list, 633 /**
587 size_t index, 634 * Removes and returns the first element of the list.
588 void *targetbuf 635 *
589 ) { 636 * No destructor is called, and instead the element is copied to the
590 return list->cl->remove(list, index, 1, targetbuf) == 0; 637 * @p targetbuf which MUST be large enough to hold the removed element.
591 } 638 * If the list is storing pointers, only the pointer is copied to @p targetbuf.
639 *
640 * @param list the list
641 * @param targetbuf a buffer where to copy the element
642 * @retval zero success
643 * @retval non-zero the list is empty
644 * @see cxListPopFront()
645 * @see cxListRemoveAndGetLast()
646 */
647 cx_attr_nonnull cx_attr_access_w(2)
648 CX_EXPORT int cxListRemoveAndGetFirst(CxList *list, void *targetbuf);
649
650 /**
651 * Removes and returns the first element of the list.
652 *
653 * Alias for cxListRemoveAndGetFirst().
654 *
655 * No destructor is called, and instead the element is copied to the
656 * @p targetbuf which MUST be large enough to hold the removed element.
657 * If the list is storing pointers, only the pointer is copied to @p targetbuf.
658 *
659 * @param list (@c CxList*) the list
660 * @param targetbuf (@c void*) a buffer where to copy the element
661 * @retval zero success
662 * @retval non-zero the list is empty
663 * @see cxListRemoveAndGetFirst()
664 * @see cxListPop()
665 */
666 #define cxListPopFront(list, targetbuf) cxListRemoveAndGetFirst((list), (targetbuf))
667
668
669 /**
670 * Removes and returns the last element of the list.
671 *
672 * No destructor is called, and instead the element is copied to the
673 * @p targetbuf which MUST be large enough to hold the removed element.
674 * If the list is storing pointers, only the pointer is copied to @p targetbuf.
675 *
676 * @param list the list
677 * @param targetbuf a buffer where to copy the element
678 * @retval zero success
679 * @retval non-zero the list is empty
680 */
681 cx_attr_nonnull cx_attr_access_w(2)
682 CX_EXPORT int cxListRemoveAndGetLast(CxList *list, void *targetbuf);
683
684 /**
685 * Removes and returns the last element of the list.
686 *
687 * Alias for cxListRemoveAndGetLast().
688 *
689 * No destructor is called, and instead the element is copied to the
690 * @p targetbuf which MUST be large enough to hold the removed element.
691 * If the list is storing pointers, only the pointer is copied to @p targetbuf.
692 *
693 * @param list (@c CxList*) the list
694 * @param targetbuf (@c void*) a buffer where to copy the element
695 * @retval zero success
696 * @retval non-zero the list is empty
697 * @see cxListRemoveAndGetLast()
698 * @see cxListPopFront()
699 */
700 #define cxListPop(list, targetbuf) cxListRemoveAndGetLast((list), (targetbuf))
592 701
593 /** 702 /**
594 * Removes multiple element starting at the specified index. 703 * Removes multiple element starting at the specified index.
595 * 704 *
596 * If an element destructor function is specified, it is called for each 705 * If an element destructor function is specified, it is called for each
597 * element. It is guaranteed that the destructor is called before removing 706 * element. It is guaranteed that the destructor is called before removing
598 * the element, however, due to possible optimizations it is neither guaranteed 707 * the element. However, due to possible optimizations, it is neither guaranteed
599 * that the destructors are invoked for all elements before starting to remove 708 * that the destructors are invoked for all elements before starting to remove
600 * them, nor that the element is removed immediately after the destructor call 709 * them, nor that the element is removed immediately after the destructor call
601 * before proceeding to the next element. 710 * before proceeding to the next element.
602 * 711 *
603 * @param list the list 712 * @param list the list
604 * @param index the index of the element 713 * @param index the index of the element
605 * @param num the number of elements to remove 714 * @param num the number of elements to remove
606 * @return the actual number of removed elements 715 * @return the actual number of removed elements
607 */ 716 */
608 cx_attr_nonnull 717 cx_attr_nonnull
609 static inline size_t cxListRemoveArray( 718 CX_EXPORT size_t cxListRemoveArray(CxList *list, size_t index, size_t num);
610 CxList *list, 719
611 size_t index, 720 /**
612 size_t num 721 * Removes and returns multiple elements starting at the specified index.
613 ) { 722 *
614 return list->cl->remove(list, index, num, NULL); 723 * No destructor is called, and instead the elements are copied to the
615 }
616
617 /**
618 * Removes and returns multiple element starting at the specified index.
619 *
620 * No destructor is called and instead the elements are copied to the
621 * @p targetbuf which MUST be large enough to hold all removed elements. 724 * @p targetbuf which MUST be large enough to hold all removed elements.
725 * If the list is storing pointers, @p targetbuf is expected to be an array of pointers.
622 * 726 *
623 * @param list the list 727 * @param list the list
624 * @param index the index of the element 728 * @param index the index of the element
625 * @param num the number of elements to remove 729 * @param num the number of elements to remove
626 * @param targetbuf a buffer where to copy the elements 730 * @param targetbuf a buffer where to copy the elements
627 * @return the actual number of removed elements 731 * @return the actual number of removed elements
628 */ 732 */
629 cx_attr_nonnull 733 cx_attr_nonnull cx_attr_access_w(4)
630 cx_attr_access_w(4) 734 CX_EXPORT size_t cxListRemoveArrayAndGet(CxList *list, size_t index, size_t num, void *targetbuf);
631 static inline size_t cxListRemoveArrayAndGet(
632 CxList *list,
633 size_t index,
634 size_t num,
635 void *targetbuf
636 ) {
637 return list->cl->remove(list, index, num, targetbuf);
638 }
639 735
640 /** 736 /**
641 * Removes all elements from this list. 737 * Removes all elements from this list.
642 * 738 *
643 * If element destructor functions are specified, they are called for each 739 * If element destructor functions are specified, they are called for each
644 * element before removing them. 740 * element before removing them.
645 * 741 *
646 * @param list the list 742 * @param list the list
647 */ 743 */
648 cx_attr_nonnull 744 cx_attr_nonnull
649 static inline void cxListClear(CxList *list) { 745 CX_EXPORT void cxListClear(CxList *list);
650 list->collection.sorted = true; // empty lists are always sorted
651 list->cl->clear(list);
652 }
653 746
654 /** 747 /**
655 * Swaps two items in the list. 748 * Swaps two items in the list.
656 * 749 *
657 * Implementations should only allocate temporary memory for the swap, if 750 * Implementations should only allocate temporary memory for the swap if
658 * it is necessary. 751 * it is necessary.
659 * 752 *
660 * @param list the list 753 * @param list the list
661 * @param i the index of the first element 754 * @param i the index of the first element
662 * @param j the index of the second element 755 * @param j the index of the second element
663 * @retval zero success 756 * @retval zero success
664 * @retval non-zero one of the indices is out of bounds 757 * @retval non-zero one of the indices is out of bounds,
665 * or the swap needed extra memory but allocation failed 758 * or the swap needed extra memory, but allocation failed
666 */ 759 */
667 cx_attr_nonnull 760 cx_attr_nonnull
668 static inline int cxListSwap( 761 CX_EXPORT int cxListSwap(CxList *list, size_t i, size_t j);
669 CxList *list,
670 size_t i,
671 size_t j
672 ) {
673 list->collection.sorted = false;
674 return list->cl->swap(list, i, j);
675 }
676 762
677 /** 763 /**
678 * Returns a pointer to the element at the specified index. 764 * Returns a pointer to the element at the specified index.
765 *
766 * If the list is storing pointers, returns the pointer stored at the specified index.
679 * 767 *
680 * @param list the list 768 * @param list the list
681 * @param index the index of the element 769 * @param index the index of the element
682 * @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
683 */ 771 */
684 cx_attr_nonnull 772 cx_attr_nonnull
685 static inline void *cxListAt( 773 CX_EXPORT void *cxListAt(const CxList *list, size_t index);
686 const CxList *list, 774
687 size_t index 775 /**
688 ) { 776 * Returns a pointer to the first element.
689 return list->cl->at(list, index); 777 *
690 } 778 * If the list is storing pointers, returns the first pointer stored in the list.
779 *
780 * @param list the list
781 * @return a pointer to the first element or @c NULL if the list is empty
782 */
783 cx_attr_nonnull
784 CX_EXPORT void *cxListFirst(const CxList *list);
785
786 /**
787 * Returns a pointer to the last element.
788 *
789 * If the list is storing pointers, returns the last pointer stored in the list.
790 *
791 * @param list the list
792 * @return a pointer to the last element or @c NULL if the list is empty
793 */
794 cx_attr_nonnull
795 CX_EXPORT void *cxListLast(const CxList *list);
796
797 /**
798 * Sets the element at the specified index in the list.
799 *
800 * This overwrites the element in-place without calling any destructor
801 * on the overwritten element.
802 *
803 * @param list the list to set the element in
804 * @param index the index to set the element at
805 * @param elem element to set
806 * @retval zero on success
807 * @retval non-zero when index is out of bounds
808 */
809 cx_attr_nonnull
810 CX_EXPORT int cxListSet(CxList *list, size_t index, const void *elem);
691 811
692 /** 812 /**
693 * Returns an iterator pointing to the item at the specified index. 813 * Returns an iterator pointing to the item at the specified index.
694 * 814 *
695 * The returned iterator is position-aware. 815 * The returned iterator is position-aware.
696 * 816 *
697 * 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.
698 * 818 *
699 * @param list the list 819 * @param list the list
700 * @param index the index where the iterator shall point at 820 * @param index the index where the iterator shall point at
701 * @return a new iterator 821 * @return a new iterator
702 */ 822 */
703 cx_attr_nonnull
704 cx_attr_nodiscard 823 cx_attr_nodiscard
705 static inline CxIterator cxListIteratorAt( 824 CX_EXPORT CxIterator cxListIteratorAt(const CxList *list, size_t index);
706 const CxList *list,
707 size_t index
708 ) {
709 return list->cl->iterator(list, index, false);
710 }
711 825
712 /** 826 /**
713 * 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.
714 * 828 *
715 * The returned iterator is position-aware. 829 * The returned iterator is position-aware.
716 * 830 *
717 * 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.
718 * 832 *
719 * @param list the list 833 * @param list the list
720 * @param index the index where the iterator shall point at 834 * @param index the index where the iterator shall point at
721 * @return a new iterator 835 * @return a new iterator
722 */ 836 */
723 cx_attr_nonnull
724 cx_attr_nodiscard 837 cx_attr_nodiscard
725 static inline CxIterator cxListBackwardsIteratorAt( 838 CX_EXPORT CxIterator cxListBackwardsIteratorAt(const CxList *list, size_t index);
726 const CxList *list, 839
727 size_t index 840 /**
728 ) { 841 * Returns an iterator pointing to the first item of the list.
729 return list->cl->iterator(list, index, true);
730 }
731
732 /**
733 * Returns a mutating iterator pointing to the item at the specified index.
734 * 842 *
735 * The returned iterator is position-aware. 843 * The returned iterator is position-aware.
736 * 844 *
737 * 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.
738 * 846 *
739 * @param list the list 847 * @param list the list
740 * @param index the index where the iterator shall point at
741 * @return a new iterator 848 * @return a new iterator
742 */ 849 */
743 cx_attr_nonnull
744 cx_attr_nodiscard 850 cx_attr_nodiscard
745 cx_attr_export 851 CX_EXPORT CxIterator cxListIterator(const CxList *list);
746 CxIterator cxListMutIteratorAt( 852
747 CxList *list, 853 /**
748 size_t index 854 * Returns a backwards iterator pointing to the last item of the list.
749 );
750
751 /**
752 * Returns a mutating backwards iterator pointing to the item at the
753 * specified index.
754 * 855 *
755 * The returned iterator is position-aware. 856 * The returned iterator is position-aware.
756 * 857 *
757 * 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.
758 * 859 *
759 * @param list the list 860 * @param list the list
760 * @param index the index where the iterator shall point at
761 * @return a new iterator 861 * @return a new iterator
762 */ 862 */
763 cx_attr_nonnull
764 cx_attr_nodiscard 863 cx_attr_nodiscard
765 cx_attr_export 864 CX_EXPORT CxIterator cxListBackwardsIterator(const CxList *list);
766 CxIterator cxListMutBackwardsIteratorAt(
767 CxList *list,
768 size_t index
769 );
770
771 /**
772 * Returns an iterator pointing to the first item of the list.
773 *
774 * The returned iterator is position-aware.
775 *
776 * If the list is empty, a past-the-end iterator will be returned.
777 *
778 * @param list the list
779 * @return a new iterator
780 */
781 cx_attr_nonnull
782 cx_attr_nodiscard
783 static inline CxIterator cxListIterator(const CxList *list) {
784 return list->cl->iterator(list, 0, false);
785 }
786
787 /**
788 * Returns a mutating iterator pointing to the first item of the list.
789 *
790 * The returned iterator is position-aware.
791 *
792 * If the list is empty, a past-the-end iterator will be returned.
793 *
794 * @param list the list
795 * @return a new iterator
796 */
797 cx_attr_nonnull
798 cx_attr_nodiscard
799 static inline CxIterator cxListMutIterator(CxList *list) {
800 return cxListMutIteratorAt(list, 0);
801 }
802
803
804 /**
805 * Returns a backwards iterator pointing to the last item of the list.
806 *
807 * The returned iterator is position-aware.
808 *
809 * If the list is empty, a past-the-end iterator will be returned.
810 *
811 * @param list the list
812 * @return a new iterator
813 */
814 cx_attr_nonnull
815 cx_attr_nodiscard
816 static inline CxIterator cxListBackwardsIterator(const CxList *list) {
817 return list->cl->iterator(list, list->collection.size - 1, true);
818 }
819
820 /**
821 * Returns a mutating backwards iterator pointing to the last item of the list.
822 *
823 * The returned iterator is position-aware.
824 *
825 * If the list is empty, a past-the-end iterator will be returned.
826 *
827 * @param list the list
828 * @return a new iterator
829 */
830 cx_attr_nonnull
831 cx_attr_nodiscard
832 static inline CxIterator cxListMutBackwardsIterator(CxList *list) {
833 return cxListMutBackwardsIteratorAt(list, list->collection.size - 1);
834 }
835 865
836 /** 866 /**
837 * Returns the index of the first element that equals @p elem. 867 * Returns the index of the first element that equals @p elem.
838 * 868 *
839 * Determining equality is performed by the list's comparator function. 869 * Determining equality is performed by the list's comparator function.
840 * 870 *
841 * @param list the list 871 * @param list the list
842 * @param elem the element to find 872 * @param elem the element to find
843 * @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
844 * @see cxListIndexValid() 874 * @see cxListIndexValid()
845 */ 875 * @see cxListContains()
846 cx_attr_nonnull 876 */
847 cx_attr_nodiscard 877 cx_attr_nonnull cx_attr_nodiscard
848 static inline size_t cxListFind( 878 CX_EXPORT size_t cxListFind(const CxList *list, const void *elem);
849 const CxList *list, 879
850 const void *elem 880 /**
851 ) { 881 * Checks if the list contains the specified element.
852 return list->cl->find_remove((CxList*)list, elem, false); 882 *
853 } 883 * The elements are compared with the list's comparator function.
884 *
885 * @param list the list
886 * @param elem the element to find
887 * @retval true if the element is contained
888 * @retval false if the element is not contained
889 * @see cxListFind()
890 */
891 cx_attr_nonnull cx_attr_nodiscard
892 CX_EXPORT bool cxListContains(const CxList* list, const void* elem);
854 893
855 /** 894 /**
856 * Checks if the specified index is within bounds. 895 * Checks if the specified index is within bounds.
857 * 896 *
858 * @param list the list 897 * @param list the list
859 * @param index the index 898 * @param index the index
860 * @retval true if the index is within bounds 899 * @retval true if the index is within bounds
861 * @retval false if the index is out of bounds 900 * @retval false if the index is out of bounds
862 */ 901 */
863 cx_attr_nonnull 902 cx_attr_nonnull cx_attr_nodiscard
864 cx_attr_nodiscard 903 CX_EXPORT bool cxListIndexValid(const CxList *list, size_t index);
865 static inline bool cxListIndexValid(const CxList *list, size_t index) {
866 return index < list->collection.size;
867 }
868 904
869 /** 905 /**
870 * 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.
871 * 907 *
872 * Determining equality is performed by the list's comparator function. 908 * Determining equality is performed by the list's comparator function.
876 * @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
877 * when the element is not found or could not be removed 913 * when the element is not found or could not be removed
878 * @see cxListIndexValid() 914 * @see cxListIndexValid()
879 */ 915 */
880 cx_attr_nonnull 916 cx_attr_nonnull
881 static inline size_t cxListFindRemove( 917 CX_EXPORT size_t cxListFindRemove(CxList *list, const void *elem);
882 CxList *list,
883 const void *elem
884 ) {
885 return list->cl->find_remove(list, elem, true);
886 }
887 918
888 /** 919 /**
889 * Sorts the list. 920 * Sorts the list.
890 * 921 *
891 * @remark The underlying sort algorithm is implementation defined. 922 * @remark The underlying sort algorithm is implementation defined.
892 * 923 *
893 * @param list the list 924 * @param list the list
894 */ 925 */
895 cx_attr_nonnull 926 cx_attr_nonnull
896 static inline void cxListSort(CxList *list) { 927 CX_EXPORT void cxListSort(CxList *list);
897 list->cl->sort(list);
898 list->collection.sorted = true;
899 }
900 928
901 /** 929 /**
902 * Reverses the order of the items. 930 * Reverses the order of the items.
903 * 931 *
904 * @param list the list 932 * @param list the list
905 */ 933 */
906 cx_attr_nonnull 934 cx_attr_nonnull
907 static inline void cxListReverse(CxList *list) { 935 CX_EXPORT void cxListReverse(CxList *list);
908 // still sorted, but not according to the cmp_func
909 list->collection.sorted = false;
910 list->cl->reverse(list);
911 }
912 936
913 /** 937 /**
914 * Compares a list to another list of the same type. 938 * Compares a list to another list of the same type.
915 * 939 *
916 * First, the list sizes are compared. 940 * First, the list sizes are compared.
917 * If they match, the lists are compared element-wise. 941 * If they match, the lists are compared element-wise.
918 * 942 *
919 * @param list the list 943 * @param list the list
920 * @param other the list to compare to 944 * @param other the list to compare to
921 * @retval zero both lists are equal element wise 945 * @retval zero both lists are equal element wise
922 * @retval negative the first list is smaller 946 * @retval negative the first list is smaller,
923 * 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
924 * @retval positive the first list is larger 948 * @retval positive the first list is larger
925 * 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
926 */ 950 */
927 cx_attr_nonnull 951 cx_attr_nonnull cx_attr_nodiscard
928 cx_attr_nodiscard 952 CX_EXPORT int cxListCompare(const CxList *list, const CxList *other);
929 cx_attr_export
930 int cxListCompare(
931 const CxList *list,
932 const CxList *other
933 );
934 953
935 /** 954 /**
936 * Deallocates the memory of the specified list structure. 955 * Deallocates the memory of the specified list structure.
937 * 956 *
938 * Also calls the content destructor functions for each element, if specified. 957 * Also calls the content destructor functions for each element, if specified.
939 * 958 *
940 * @param list the list which shall be freed 959 * @param list the list that shall be freed
941 */ 960 */
942 cx_attr_export 961 CX_EXPORT void cxListFree(CxList *list);
943 void cxListFree(CxList *list); 962
944 963
945 /** 964 /**
946 * A shared instance of an empty list. 965 * Performs a deep clone of one list into another.
947 * 966 *
948 * Writing to that list is not allowed. 967 * If the destination list already contains elements, the cloned elements
949 * 968 * are appended to that list.
950 * You can use this is a placeholder for initializing CxList pointers 969 *
951 * for which you do not want to reserve memory right from the beginning. 970 * @attention If the cloned elements need to be destroyed by a destructor
952 */ 971 * function, you must make sure that the destination list also uses this
953 cx_attr_export 972 * destructor function.
954 extern CxList *const cxEmptyList; 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);
955 1056
956 1057
957 #ifdef __cplusplus 1058 #ifdef __cplusplus
958 } // extern "C" 1059 } // extern "C"
959 #endif 1060 #endif

mercurial