ucx/cx/list.h

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

mercurial