ucx/cx/list.h

changeset 440
7c4b9cba09ca
parent 324
ce13a778654a
equal deleted inserted replaced
439:bf7084544cb1 440:7c4b9cba09ca
24 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 24 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
25 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 25 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
26 * POSSIBILITY OF SUCH DAMAGE. 26 * POSSIBILITY OF SUCH DAMAGE.
27 */ 27 */
28 /** 28 /**
29 * \file list.h 29 * @file list.h
30 * \brief Interface for list implementations. 30 * @brief Interface for list implementations.
31 * \author Mike Becker 31 * @author Mike Becker
32 * \author Olaf Wintermann 32 * @author Olaf Wintermann
33 * \copyright 2-Clause BSD License 33 * @copyright 2-Clause BSD License
34 */ 34 */
35 35
36 #ifndef UCX_LIST_H 36 #ifndef UCX_LIST_H
37 #define UCX_LIST_H 37 #define UCX_LIST_H
38 38
50 50
51 /** 51 /**
52 * Structure for holding the base data of a list. 52 * Structure for holding the base data of a list.
53 */ 53 */
54 struct cx_list_s { 54 struct cx_list_s {
55 /**
56 * Common members for collections.
57 */
55 CX_COLLECTION_BASE; 58 CX_COLLECTION_BASE;
56 /** 59 /**
57 * The list class definition. 60 * The list class definition.
58 */ 61 */
59 const cx_list_class *cl; 62 const cx_list_class *cl;
69 struct cx_list_class_s { 72 struct cx_list_class_s {
70 /** 73 /**
71 * Destructor function. 74 * Destructor function.
72 * 75 *
73 * Implementations SHALL invoke the content destructor functions if provided 76 * Implementations SHALL invoke the content destructor functions if provided
74 * and SHALL deallocate the list memory. 77 * and SHALL deallocate the entire list memory.
75 */ 78 */
76 void (*destructor)(struct cx_list_s *list); 79 void (*deallocate)(struct cx_list_s *list);
77 80
78 /** 81 /**
79 * Member function for inserting a single element. 82 * Member function for inserting a single element.
80 * Implementors SHOULD see to performant implementations for corner cases. 83 * Implementors SHOULD see to performant implementations for corner cases.
81 */ 84 */
86 ); 89 );
87 90
88 /** 91 /**
89 * Member function for inserting multiple elements. 92 * Member function for inserting multiple elements.
90 * Implementors SHOULD see to performant implementations for corner cases. 93 * Implementors SHOULD see to performant implementations for corner cases.
94 *
91 * @see cx_list_default_insert_array() 95 * @see cx_list_default_insert_array()
92 */ 96 */
93 size_t (*insert_array)( 97 size_t (*insert_array)(
94 struct cx_list_s *list, 98 struct cx_list_s *list,
95 size_t index, 99 size_t index,
116 const void *elem, 120 const void *elem,
117 int prepend 121 int prepend
118 ); 122 );
119 123
120 /** 124 /**
121 * Member function for removing an element. 125 * Member function for removing elements.
122 */ 126 *
123 int (*remove)( 127 * Implementations SHALL check if @p targetbuf is set and copy the elements
128 * to the buffer without invoking any destructor.
129 * When @p targetbuf is not set, the destructors SHALL be invoked.
130 *
131 * The function SHALL return the actual number of elements removed, which
132 * might be lower than @p num when going out of bounds.
133 */
134 size_t (*remove)(
124 struct cx_list_s *list, 135 struct cx_list_s *list,
125 size_t index 136 size_t index,
137 size_t num,
138 void *targetbuf
126 ); 139 );
127 140
128 /** 141 /**
129 * Member function for removing all elements. 142 * Member function for removing all elements.
130 */ 143 */
131 void (*clear)(struct cx_list_s *list); 144 void (*clear)(struct cx_list_s *list);
132 145
133 /** 146 /**
134 * Member function for swapping two elements. 147 * Member function for swapping two elements.
148 *
135 * @see cx_list_default_swap() 149 * @see cx_list_default_swap()
136 */ 150 */
137 int (*swap)( 151 int (*swap)(
138 struct cx_list_s *list, 152 struct cx_list_s *list,
139 size_t i, 153 size_t i,
156 const void *elem, 170 const void *elem,
157 bool remove 171 bool remove
158 ); 172 );
159 173
160 /** 174 /**
161 * Member function for sorting the list in-place. 175 * Member function for sorting the list.
176 *
162 * @see cx_list_default_sort() 177 * @see cx_list_default_sort()
163 */ 178 */
164 void (*sort)(struct cx_list_s *list); 179 void (*sort)(struct cx_list_s *list);
165 180
166 /** 181 /**
167 * Optional member function for comparing this list 182 * Optional member function for comparing this list
168 * to another list of the same type. 183 * to another list of the same type.
169 * If set to \c NULL, comparison won't be optimized. 184 * If set to @c NULL, comparison won't be optimized.
170 */ 185 */
186 cx_attr_nonnull
171 int (*compare)( 187 int (*compare)(
172 const struct cx_list_s *list, 188 const struct cx_list_s *list,
173 const struct cx_list_s *other 189 const struct cx_list_s *other
174 ); 190 );
175 191
200 * @param index the index where to insert the data 216 * @param index the index where to insert the data
201 * @param data a pointer to the array of data to insert 217 * @param data a pointer to the array of data to insert
202 * @param n the number of elements to insert 218 * @param n the number of elements to insert
203 * @return the number of elements actually inserted 219 * @return the number of elements actually inserted
204 */ 220 */
205 __attribute__((__nonnull__)) 221 cx_attr_nonnull
206 size_t cx_list_default_insert_array( 222 size_t cx_list_default_insert_array(
207 struct cx_list_s *list, 223 struct cx_list_s *list,
208 size_t index, 224 size_t index,
209 const void *data, 225 const void *data,
210 size_t n 226 size_t n
214 * Default implementation of a sorted insert. 230 * Default implementation of a sorted insert.
215 * 231 *
216 * This function uses the array insert function to insert consecutive groups 232 * This function uses the array insert function to insert consecutive groups
217 * of sorted data. 233 * of sorted data.
218 * 234 *
219 * The source data \em must already be sorted wrt. the list's compare function. 235 * The source data @em must already be sorted wrt. the list's compare function.
220 * 236 *
221 * Use this in your own list class if you do not want to implement an optimized 237 * Use this in your own list class if you do not want to implement an optimized
222 * version for your list. 238 * version for your list.
223 * 239 *
224 * @param list the list 240 * @param list the list
225 * @param sorted_data a pointer to the array of pre-sorted data to insert 241 * @param sorted_data a pointer to the array of pre-sorted data to insert
226 * @param n the number of elements to insert 242 * @param n the number of elements to insert
227 * @return the number of elements actually inserted 243 * @return the number of elements actually inserted
228 */ 244 */
229 __attribute__((__nonnull__)) 245 cx_attr_nonnull
230 size_t cx_list_default_insert_sorted( 246 size_t cx_list_default_insert_sorted(
231 struct cx_list_s *list, 247 struct cx_list_s *list,
232 const void *sorted_data, 248 const void *sorted_data,
233 size_t n 249 size_t n
234 ); 250 );
242 * Use this in your own list class if you do not want to implement an optimized 258 * Use this in your own list class if you do not want to implement an optimized
243 * version for your list. 259 * version for your list.
244 * 260 *
245 * @param list the list that shall be sorted 261 * @param list the list that shall be sorted
246 */ 262 */
247 __attribute__((__nonnull__)) 263 cx_attr_nonnull
248 void cx_list_default_sort(struct cx_list_s *list); 264 void cx_list_default_sort(struct cx_list_s *list);
249 265
250 /** 266 /**
251 * Default unoptimized swap implementation. 267 * Default unoptimized swap implementation.
252 * 268 *
254 * version for your list. 270 * version for your list.
255 * 271 *
256 * @param list the list in which to swap 272 * @param list the list in which to swap
257 * @param i index of one element 273 * @param i index of one element
258 * @param j index of the other element 274 * @param j index of the other element
259 * @return zero on success, non-zero when indices are out of bounds or memory 275 * @retval zero success
276 * @retval non-zero when indices are out of bounds or memory
260 * allocation for the temporary buffer fails 277 * allocation for the temporary buffer fails
261 */ 278 */
262 __attribute__((__nonnull__)) 279 cx_attr_nonnull
263 int cx_list_default_swap(struct cx_list_s *list, size_t i, size_t j); 280 int cx_list_default_swap(struct cx_list_s *list, size_t i, size_t j);
264 281
265 /** 282 /**
266 * Common type for all list implementations. 283 * Common type for all list implementations.
267 */ 284 */
274 * within this list. 291 * within this list.
275 * 292 *
276 * @param list the list 293 * @param list the list
277 * @see cxListStorePointers() 294 * @see cxListStorePointers()
278 */ 295 */
279 __attribute__((__nonnull__)) 296 cx_attr_nonnull
280 void cxListStoreObjects(CxList *list); 297 void cxListStoreObjects(CxList *list);
281 298
282 /** 299 /**
283 * Advises the list to only store pointers to the objects. 300 * Advises the list to only store pointers to the objects.
284 * 301 *
289 * objects is undefined. 306 * objects is undefined.
290 * 307 *
291 * @param list the list 308 * @param list the list
292 * @see cxListStoreObjects() 309 * @see cxListStoreObjects()
293 */ 310 */
294 __attribute__((__nonnull__)) 311 cx_attr_nonnull
295 void cxListStorePointers(CxList *list); 312 void cxListStorePointers(CxList *list);
296 313
297 /** 314 /**
298 * Returns true, if this list is storing pointers instead of the actual data. 315 * Returns true, if this list is storing pointers instead of the actual data.
299 * 316 *
300 * @param list 317 * @param list
301 * @return true, if this list is storing pointers 318 * @return true, if this list is storing pointers
302 * @see cxListStorePointers() 319 * @see cxListStorePointers()
303 */ 320 */
304 __attribute__((__nonnull__)) 321 cx_attr_nonnull
305 static inline bool cxListIsStoringPointers(const CxList *list) { 322 static inline bool cxListIsStoringPointers(const CxList *list) {
306 return list->collection.store_pointer; 323 return list->collection.store_pointer;
307 } 324 }
308 325
309 /** 326 /**
310 * Returns the number of elements currently stored in the list. 327 * Returns the number of elements currently stored in the list.
311 * 328 *
312 * @param list the list 329 * @param list the list
313 * @return the number of currently stored elements 330 * @return the number of currently stored elements
314 */ 331 */
315 __attribute__((__nonnull__)) 332 cx_attr_nonnull
316 static inline size_t cxListSize(const CxList *list) { 333 static inline size_t cxListSize(const CxList *list) {
317 return list->collection.size; 334 return list->collection.size;
318 } 335 }
319 336
320 /** 337 /**
321 * Adds an item to the end of the list. 338 * Adds an item to the end of the list.
322 * 339 *
323 * @param list the list 340 * @param list the list
324 * @param elem a pointer to the element to add 341 * @param elem a pointer to the element to add
325 * @return zero on success, non-zero on memory allocation failure 342 * @retval zero success
343 * @retval non-zero memory allocation failure
326 * @see cxListAddArray() 344 * @see cxListAddArray()
327 */ 345 */
328 __attribute__((__nonnull__)) 346 cx_attr_nonnull
329 static inline int cxListAdd( 347 static inline int cxListAdd(
330 CxList *list, 348 CxList *list,
331 const void *elem 349 const void *elem
332 ) { 350 ) {
333 return list->cl->insert_element(list, list->collection.size, elem); 351 return list->cl->insert_element(list, list->collection.size, elem);
337 * Adds multiple items to the end of the list. 355 * Adds multiple items to the end of the list.
338 * 356 *
339 * This method is more efficient than invoking cxListAdd() multiple times. 357 * This method is more efficient than invoking cxListAdd() multiple times.
340 * 358 *
341 * If there is not enough memory to add all elements, the returned value is 359 * If there is not enough memory to add all elements, the returned value is
342 * less than \p n. 360 * less than @p n.
343 * 361 *
344 * If this list is storing pointers instead of objects \p array is expected to 362 * If this list is storing pointers instead of objects @p array is expected to
345 * be an array of pointers. 363 * be an array of pointers.
346 * 364 *
347 * @param list the list 365 * @param list the list
348 * @param array a pointer to the elements to add 366 * @param array a pointer to the elements to add
349 * @param n the number of elements to add 367 * @param n the number of elements to add
350 * @return the number of added elements 368 * @return the number of added elements
351 */ 369 */
352 __attribute__((__nonnull__)) 370 cx_attr_nonnull
353 static inline size_t cxListAddArray( 371 static inline size_t cxListAddArray(
354 CxList *list, 372 CxList *list,
355 const void *array, 373 const void *array,
356 size_t n 374 size_t n
357 ) { 375 ) {
359 } 377 }
360 378
361 /** 379 /**
362 * Inserts an item at the specified index. 380 * Inserts an item at the specified index.
363 * 381 *
364 * If \p index equals the list \c size, this is effectively cxListAdd(). 382 * If @p index equals the list @c size, this is effectively cxListAdd().
365 * 383 *
366 * @param list the list 384 * @param list the list
367 * @param index the index the element shall have 385 * @param index the index the element shall have
368 * @param elem a pointer to the element to add 386 * @param elem a pointer to the element to add
369 * @return zero on success, non-zero on memory allocation failure 387 * @retval zero success
370 * or when the index is out of bounds 388 * @retval non-zero memory allocation failure or the index is out of bounds
371 * @see cxListInsertAfter() 389 * @see cxListInsertAfter()
372 * @see cxListInsertBefore() 390 * @see cxListInsertBefore()
373 */ 391 */
374 __attribute__((__nonnull__)) 392 cx_attr_nonnull
375 static inline int cxListInsert( 393 static inline int cxListInsert(
376 CxList *list, 394 CxList *list,
377 size_t index, 395 size_t index,
378 const void *elem 396 const void *elem
379 ) { 397 ) {
383 /** 401 /**
384 * Inserts an item into a sorted list. 402 * Inserts an item into a sorted list.
385 * 403 *
386 * @param list the list 404 * @param list the list
387 * @param elem a pointer to the element to add 405 * @param elem a pointer to the element to add
388 * @return zero on success, non-zero on memory allocation failure 406 * @retval zero success
389 */ 407 * @retval non-zero memory allocation failure
390 __attribute__((__nonnull__)) 408 */
409 cx_attr_nonnull
391 static inline int cxListInsertSorted( 410 static inline int cxListInsertSorted(
392 CxList *list, 411 CxList *list,
393 const void *elem 412 const void *elem
394 ) { 413 ) {
395 const void *data = list->collection.store_pointer ? &elem : elem; 414 const void *data = list->collection.store_pointer ? &elem : elem;
396 return list->cl->insert_sorted(list, data, 1) == 0; 415 return list->cl->insert_sorted(list, data, 1) == 0;
397 } 416 }
398 417
399 /** 418 /**
400 * Inserts multiple items to the list at the specified index. 419 * Inserts multiple items to the list at the specified index.
401 * If \p index equals the list size, this is effectively cxListAddArray(). 420 * If @p index equals the list size, this is effectively cxListAddArray().
402 * 421 *
403 * This method is usually more efficient than invoking cxListInsert() 422 * This method is usually more efficient than invoking cxListInsert()
404 * multiple times. 423 * multiple times.
405 * 424 *
406 * If there is not enough memory to add all elements, the returned value is 425 * If there is not enough memory to add all elements, the returned value is
407 * less than \p n. 426 * less than @p n.
408 * 427 *
409 * If this list is storing pointers instead of objects \p array is expected to 428 * If this list is storing pointers instead of objects @p array is expected to
410 * be an array of pointers. 429 * be an array of pointers.
411 * 430 *
412 * @param list the list 431 * @param list the list
413 * @param index the index where to add the elements 432 * @param index the index where to add the elements
414 * @param array a pointer to the elements to add 433 * @param array a pointer to the elements to add
415 * @param n the number of elements to add 434 * @param n the number of elements to add
416 * @return the number of added elements 435 * @return the number of added elements
417 */ 436 */
418 __attribute__((__nonnull__)) 437 cx_attr_nonnull
419 static inline size_t cxListInsertArray( 438 static inline size_t cxListInsertArray(
420 CxList *list, 439 CxList *list,
421 size_t index, 440 size_t index,
422 const void *array, 441 const void *array,
423 size_t n 442 size_t n
430 * 449 *
431 * This method is usually more efficient than inserting each element separately, 450 * This method is usually more efficient than inserting each element separately,
432 * because consecutive chunks of sorted data are inserted in one pass. 451 * because consecutive chunks of sorted data are inserted in one pass.
433 * 452 *
434 * If there is not enough memory to add all elements, the returned value is 453 * If there is not enough memory to add all elements, the returned value is
435 * less than \p n. 454 * less than @p n.
436 * 455 *
437 * If this list is storing pointers instead of objects \p array is expected to 456 * If this list is storing pointers instead of objects @p array is expected to
438 * be an array of pointers. 457 * be an array of pointers.
439 * 458 *
440 * @param list the list 459 * @param list the list
441 * @param array a pointer to the elements to add 460 * @param array a pointer to the elements to add
442 * @param n the number of elements to add 461 * @param n the number of elements to add
443 * @return the number of added elements 462 * @return the number of added elements
444 */ 463 */
445 __attribute__((__nonnull__)) 464 cx_attr_nonnull
446 static inline size_t cxListInsertSortedArray( 465 static inline size_t cxListInsertSortedArray(
447 CxList *list, 466 CxList *list,
448 const void *array, 467 const void *array,
449 size_t n 468 size_t n
450 ) { 469 ) {
455 * Inserts an element after the current location of the specified iterator. 474 * Inserts an element after the current location of the specified iterator.
456 * 475 *
457 * The used iterator remains operational, but all other active iterators should 476 * The used iterator remains operational, but all other active iterators should
458 * be considered invalidated. 477 * be considered invalidated.
459 * 478 *
460 * If \p iter is not a list iterator, the behavior is undefined. 479 * If @p iter is not a list iterator, the behavior is undefined.
461 * If \p iter is a past-the-end iterator, the new element gets appended to the list. 480 * If @p iter is a past-the-end iterator, the new element gets appended to the list.
462 * 481 *
463 * @param iter an iterator 482 * @param iter an iterator
464 * @param elem the element to insert 483 * @param elem the element to insert
465 * @return zero on success, non-zero on memory allocation failure 484 * @retval zero success
485 * @retval non-zero memory allocation failure
466 * @see cxListInsert() 486 * @see cxListInsert()
467 * @see cxListInsertBefore() 487 * @see cxListInsertBefore()
468 */ 488 */
469 __attribute__((__nonnull__)) 489 cx_attr_nonnull
470 static inline int cxListInsertAfter( 490 static inline int cxListInsertAfter(
471 CxIterator *iter, 491 CxIterator *iter,
472 const void *elem 492 const void *elem
473 ) { 493 ) {
474 return ((struct cx_list_s *) iter->src_handle.m)->cl->insert_iter(iter, elem, 0); 494 return ((struct cx_list_s *) iter->src_handle.m)->cl->insert_iter(iter, elem, 0);
478 * Inserts an element before the current location of the specified iterator. 498 * Inserts an element before the current location of the specified iterator.
479 * 499 *
480 * The used iterator remains operational, but all other active iterators should 500 * The used iterator remains operational, but all other active iterators should
481 * be considered invalidated. 501 * be considered invalidated.
482 * 502 *
483 * If \p iter is not a list iterator, the behavior is undefined. 503 * If @p iter is not a list iterator, the behavior is undefined.
484 * If \p iter is a past-the-end iterator, the new element gets appended to the list. 504 * If @p iter is a past-the-end iterator, the new element gets appended to the list.
485 * 505 *
486 * @param iter an iterator 506 * @param iter an iterator
487 * @param elem the element to insert 507 * @param elem the element to insert
488 * @return zero on success, non-zero on memory allocation failure 508 * @retval zero success
509 * @retval non-zero memory allocation failure
489 * @see cxListInsert() 510 * @see cxListInsert()
490 * @see cxListInsertAfter() 511 * @see cxListInsertAfter()
491 */ 512 */
492 __attribute__((__nonnull__)) 513 cx_attr_nonnull
493 static inline int cxListInsertBefore( 514 static inline int cxListInsertBefore(
494 CxIterator *iter, 515 CxIterator *iter,
495 const void *elem 516 const void *elem
496 ) { 517 ) {
497 return ((struct cx_list_s *) iter->src_handle.m)->cl->insert_iter(iter, elem, 1); 518 return ((struct cx_list_s *) iter->src_handle.m)->cl->insert_iter(iter, elem, 1);
503 * If an element destructor function is specified, it is called before 524 * If an element destructor function is specified, it is called before
504 * removing the element. 525 * removing the element.
505 * 526 *
506 * @param list the list 527 * @param list the list
507 * @param index the index of the element 528 * @param index the index of the element
508 * @return zero on success, non-zero if the index is out of bounds 529 * @retval zero success
509 */ 530 * @retval non-zero index out of bounds
510 __attribute__((__nonnull__)) 531 */
532 cx_attr_nonnull
511 static inline int cxListRemove( 533 static inline int cxListRemove(
512 CxList *list, 534 CxList *list,
513 size_t index 535 size_t index
514 ) { 536 ) {
515 return list->cl->remove(list, index); 537 return list->cl->remove(list, index, 1, NULL) == 0;
538 }
539
540 /**
541 * Removes and returns the element at the specified index.
542 *
543 * No destructor is called and instead the element is copied to the
544 * @p targetbuf which MUST be large enough to hold the removed element.
545 *
546 * @param list the list
547 * @param index the index of the element
548 * @param targetbuf a buffer where to copy the element
549 * @retval zero success
550 * @retval non-zero index out of bounds
551 */
552 cx_attr_nonnull
553 cx_attr_access_w(3)
554 static inline int cxListRemoveAndGet(
555 CxList *list,
556 size_t index,
557 void *targetbuf
558 ) {
559 return list->cl->remove(list, index, 1, targetbuf) == 0;
560 }
561
562 /**
563 * Removes multiple element starting at the specified index.
564 *
565 * If an element destructor function is specified, it is called for each
566 * element. It is guaranteed that the destructor is called before removing
567 * the element, however, due to possible optimizations it is neither guaranteed
568 * that the destructors are invoked for all elements before starting to remove
569 * them, nor that the element is removed immediately after the destructor call
570 * before proceeding to the next element.
571 *
572 * @param list the list
573 * @param index the index of the element
574 * @param num the number of elements to remove
575 * @return the actual number of removed elements
576 */
577 cx_attr_nonnull
578 static inline size_t cxListRemoveArray(
579 CxList *list,
580 size_t index,
581 size_t num
582 ) {
583 return list->cl->remove(list, index, num, NULL);
584 }
585
586 /**
587 * Removes and returns multiple element starting at the specified index.
588 *
589 * No destructor is called and instead the elements are copied to the
590 * @p targetbuf which MUST be large enough to hold all removed elements.
591 *
592 * @param list the list
593 * @param index the index of the element
594 * @param num the number of elements to remove
595 * @param targetbuf a buffer where to copy the elements
596 * @return the actual number of removed elements
597 */
598 cx_attr_nonnull
599 cx_attr_access_w(4)
600 static inline size_t cxListRemoveArrayAndGet(
601 CxList *list,
602 size_t index,
603 size_t num,
604 void *targetbuf
605 ) {
606 return list->cl->remove(list, index, num, targetbuf);
516 } 607 }
517 608
518 /** 609 /**
519 * Removes all elements from this list. 610 * Removes all elements from this list.
520 * 611 *
521 * If an element destructor function is specified, it is called for each 612 * If element destructor functions are specified, they are called for each
522 * element before removing them. 613 * element before removing them.
523 * 614 *
524 * @param list the list 615 * @param list the list
525 */ 616 */
526 __attribute__((__nonnull__)) 617 cx_attr_nonnull
527 static inline void cxListClear(CxList *list) { 618 static inline void cxListClear(CxList *list) {
528 list->cl->clear(list); 619 list->cl->clear(list);
529 } 620 }
530 621
531 /** 622 /**
535 * it is necessary. 626 * it is necessary.
536 * 627 *
537 * @param list the list 628 * @param list the list
538 * @param i the index of the first element 629 * @param i the index of the first element
539 * @param j the index of the second element 630 * @param j the index of the second element
540 * @return zero on success, non-zero if one of the indices is out of bounds 631 * @retval zero success
541 */ 632 * @retval non-zero one of the indices is out of bounds
542 __attribute__((__nonnull__)) 633 * or the swap needed extra memory but allocation failed
634 */
635 cx_attr_nonnull
543 static inline int cxListSwap( 636 static inline int cxListSwap(
544 CxList *list, 637 CxList *list,
545 size_t i, 638 size_t i,
546 size_t j 639 size_t j
547 ) { 640 ) {
551 /** 644 /**
552 * Returns a pointer to the element at the specified index. 645 * Returns a pointer to the element at the specified index.
553 * 646 *
554 * @param list the list 647 * @param list the list
555 * @param index the index of the element 648 * @param index the index of the element
556 * @return a pointer to the element or \c NULL if the index is out of bounds 649 * @return a pointer to the element or @c NULL if the index is out of bounds
557 */ 650 */
558 __attribute__((__nonnull__)) 651 cx_attr_nonnull
559 static inline void *cxListAt( 652 static inline void *cxListAt(
560 CxList *list, 653 const CxList *list,
561 size_t index 654 size_t index
562 ) { 655 ) {
563 return list->cl->at(list, index); 656 return list->cl->at(list, index);
564 } 657 }
565 658
572 * 665 *
573 * @param list the list 666 * @param list the list
574 * @param index the index where the iterator shall point at 667 * @param index the index where the iterator shall point at
575 * @return a new iterator 668 * @return a new iterator
576 */ 669 */
577 __attribute__((__nonnull__, __warn_unused_result__)) 670 cx_attr_nonnull
671 cx_attr_nodiscard
578 static inline CxIterator cxListIteratorAt( 672 static inline CxIterator cxListIteratorAt(
579 const CxList *list, 673 const CxList *list,
580 size_t index 674 size_t index
581 ) { 675 ) {
582 return list->cl->iterator(list, index, false); 676 return list->cl->iterator(list, index, false);
591 * 685 *
592 * @param list the list 686 * @param list the list
593 * @param index the index where the iterator shall point at 687 * @param index the index where the iterator shall point at
594 * @return a new iterator 688 * @return a new iterator
595 */ 689 */
596 __attribute__((__nonnull__, __warn_unused_result__)) 690 cx_attr_nonnull
691 cx_attr_nodiscard
597 static inline CxIterator cxListBackwardsIteratorAt( 692 static inline CxIterator cxListBackwardsIteratorAt(
598 const CxList *list, 693 const CxList *list,
599 size_t index 694 size_t index
600 ) { 695 ) {
601 return list->cl->iterator(list, index, true); 696 return list->cl->iterator(list, index, true);
610 * 705 *
611 * @param list the list 706 * @param list the list
612 * @param index the index where the iterator shall point at 707 * @param index the index where the iterator shall point at
613 * @return a new iterator 708 * @return a new iterator
614 */ 709 */
615 __attribute__((__nonnull__, __warn_unused_result__)) 710 cx_attr_nonnull
711 cx_attr_nodiscard
616 CxIterator cxListMutIteratorAt( 712 CxIterator cxListMutIteratorAt(
617 CxList *list, 713 CxList *list,
618 size_t index 714 size_t index
619 ); 715 );
620 716
628 * 724 *
629 * @param list the list 725 * @param list the list
630 * @param index the index where the iterator shall point at 726 * @param index the index where the iterator shall point at
631 * @return a new iterator 727 * @return a new iterator
632 */ 728 */
633 __attribute__((__nonnull__, __warn_unused_result__)) 729 cx_attr_nonnull
730 cx_attr_nodiscard
634 CxIterator cxListMutBackwardsIteratorAt( 731 CxIterator cxListMutBackwardsIteratorAt(
635 CxList *list, 732 CxList *list,
636 size_t index 733 size_t index
637 ); 734 );
638 735
644 * If the list is empty, a past-the-end iterator will be returned. 741 * If the list is empty, a past-the-end iterator will be returned.
645 * 742 *
646 * @param list the list 743 * @param list the list
647 * @return a new iterator 744 * @return a new iterator
648 */ 745 */
649 __attribute__((__nonnull__, __warn_unused_result__)) 746 cx_attr_nonnull
747 cx_attr_nodiscard
650 static inline CxIterator cxListIterator(const CxList *list) { 748 static inline CxIterator cxListIterator(const CxList *list) {
651 return list->cl->iterator(list, 0, false); 749 return list->cl->iterator(list, 0, false);
652 } 750 }
653 751
654 /** 752 /**
659 * If the list is empty, a past-the-end iterator will be returned. 757 * If the list is empty, a past-the-end iterator will be returned.
660 * 758 *
661 * @param list the list 759 * @param list the list
662 * @return a new iterator 760 * @return a new iterator
663 */ 761 */
664 __attribute__((__nonnull__, __warn_unused_result__)) 762 cx_attr_nonnull
763 cx_attr_nodiscard
665 static inline CxIterator cxListMutIterator(CxList *list) { 764 static inline CxIterator cxListMutIterator(CxList *list) {
666 return cxListMutIteratorAt(list, 0); 765 return cxListMutIteratorAt(list, 0);
667 } 766 }
668 767
669 768
675 * If the list is empty, a past-the-end iterator will be returned. 774 * If the list is empty, a past-the-end iterator will be returned.
676 * 775 *
677 * @param list the list 776 * @param list the list
678 * @return a new iterator 777 * @return a new iterator
679 */ 778 */
680 __attribute__((__nonnull__, __warn_unused_result__)) 779 cx_attr_nonnull
780 cx_attr_nodiscard
681 static inline CxIterator cxListBackwardsIterator(const CxList *list) { 781 static inline CxIterator cxListBackwardsIterator(const CxList *list) {
682 return list->cl->iterator(list, list->collection.size - 1, true); 782 return list->cl->iterator(list, list->collection.size - 1, true);
683 } 783 }
684 784
685 /** 785 /**
690 * If the list is empty, a past-the-end iterator will be returned. 790 * If the list is empty, a past-the-end iterator will be returned.
691 * 791 *
692 * @param list the list 792 * @param list the list
693 * @return a new iterator 793 * @return a new iterator
694 */ 794 */
695 __attribute__((__nonnull__, __warn_unused_result__)) 795 cx_attr_nonnull
796 cx_attr_nodiscard
696 static inline CxIterator cxListMutBackwardsIterator(CxList *list) { 797 static inline CxIterator cxListMutBackwardsIterator(CxList *list) {
697 return cxListMutBackwardsIteratorAt(list, list->collection.size - 1); 798 return cxListMutBackwardsIteratorAt(list, list->collection.size - 1);
698 } 799 }
699 800
700 /** 801 /**
701 * Returns the index of the first element that equals \p elem. 802 * Returns the index of the first element that equals @p elem.
702 * 803 *
703 * Determining equality is performed by the list's comparator function. 804 * Determining equality is performed by the list's comparator function.
704 * 805 *
705 * @param list the list 806 * @param list the list
706 * @param elem the element to find 807 * @param elem the element to find
707 * @return the index of the element or a negative 808 * @return the index of the element or a negative
708 * value when the element is not found 809 * value when the element is not found
709 */ 810 */
710 __attribute__((__nonnull__)) 811 cx_attr_nonnull
812 cx_attr_nodiscard
711 static inline ssize_t cxListFind( 813 static inline ssize_t cxListFind(
712 const CxList *list, 814 const CxList *list,
713 const void *elem 815 const void *elem
714 ) { 816 ) {
715 return list->cl->find_remove((CxList*)list, elem, false); 817 return list->cl->find_remove((CxList*)list, elem, false);
716 } 818 }
717 819
718 /** 820 /**
719 * Removes and returns the index of the first element that equals \p elem. 821 * Removes and returns the index of the first element that equals @p elem.
720 * 822 *
721 * Determining equality is performed by the list's comparator function. 823 * Determining equality is performed by the list's comparator function.
722 * 824 *
723 * @param list the list 825 * @param list the list
724 * @param elem the element to find and remove 826 * @param elem the element to find and remove
725 * @return the index of the now removed element or a negative 827 * @return the index of the now removed element or a negative
726 * value when the element is not found or could not be removed 828 * value when the element is not found or could not be removed
727 */ 829 */
728 __attribute__((__nonnull__)) 830 cx_attr_nonnull
729 static inline ssize_t cxListFindRemove( 831 static inline ssize_t cxListFindRemove(
730 CxList *list, 832 CxList *list,
731 const void *elem 833 const void *elem
732 ) { 834 ) {
733 return list->cl->find_remove(list, elem, true); 835 return list->cl->find_remove(list, elem, true);
734 } 836 }
735 837
736 /** 838 /**
737 * Sorts the list in-place. 839 * Sorts the list.
738 * 840 *
739 * \remark The underlying sort algorithm is implementation defined. 841 * @remark The underlying sort algorithm is implementation defined.
740 * 842 *
741 * @param list the list 843 * @param list the list
742 */ 844 */
743 __attribute__((__nonnull__)) 845 cx_attr_nonnull
744 static inline void cxListSort(CxList *list) { 846 static inline void cxListSort(CxList *list) {
745 list->cl->sort(list); 847 list->cl->sort(list);
746 } 848 }
747 849
748 /** 850 /**
749 * Reverses the order of the items. 851 * Reverses the order of the items.
750 * 852 *
751 * @param list the list 853 * @param list the list
752 */ 854 */
753 __attribute__((__nonnull__)) 855 cx_attr_nonnull
754 static inline void cxListReverse(CxList *list) { 856 static inline void cxListReverse(CxList *list) {
755 list->cl->reverse(list); 857 list->cl->reverse(list);
756 } 858 }
757 859
758 /** 860 /**
761 * First, the list sizes are compared. 863 * First, the list sizes are compared.
762 * If they match, the lists are compared element-wise. 864 * If they match, the lists are compared element-wise.
763 * 865 *
764 * @param list the list 866 * @param list the list
765 * @param other the list to compare to 867 * @param other the list to compare to
766 * @return zero, if both lists are equal element wise, 868 * @retval zero both lists are equal element wise
767 * negative if the first list is smaller, positive if the first list is larger 869 * @retval negative the first list is smaller
768 */ 870 * or the first non-equal element in the first list is smaller
769 __attribute__((__nonnull__)) 871 * @retval positive the first list is larger
872 * or the first non-equal element in the first list is larger
873 */
874 cx_attr_nonnull
875 cx_attr_nodiscard
770 int cxListCompare( 876 int cxListCompare(
771 const CxList *list, 877 const CxList *list,
772 const CxList *other 878 const CxList *other
773 ); 879 );
774 880
775 /** 881 /**
776 * Deallocates the memory of the specified list structure. 882 * Deallocates the memory of the specified list structure.
777 * 883 *
778 * Also calls content a destructor function, depending on the configuration 884 * Also calls the content destructor functions for each element, if specified.
779 * in CxList.content_destructor_type. 885 *
780 * 886 * @param list the list which shall be freed
781 * This function itself is a destructor function for the CxList. 887 */
782 * 888 void cxListFree(CxList *list);
783 * @param list the list which shall be destroyed
784 */
785 __attribute__((__nonnull__))
786 void cxListDestroy(CxList *list);
787 889
788 /** 890 /**
789 * A shared instance of an empty list. 891 * A shared instance of an empty list.
790 * 892 *
791 * Writing to that list is undefined. 893 * Writing to that list is not allowed.
792 */ 894 *
793 extern CxList * const cxEmptyList; 895 * You can use this is a placeholder for initializing CxList pointers
896 * for which you do not want to reserve memory right from the beginning.
897 */
898 extern CxList *const cxEmptyList;
794 899
795 900
796 #ifdef __cplusplus 901 #ifdef __cplusplus
797 } // extern "C" 902 } // extern "C"
798 #endif 903 #endif

mercurial