ucx/cx/list.h

changeset 852
83fdf679df99
parent 816
839fefbdedc7
equal deleted inserted replaced
850:bbe2925eb590 852:83fdf679df99
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 cx_list_class const *cl; 62 const cx_list_class *cl;
60 /** 63 /**
61 * The actual implementation in case the list class is delegating. 64 * The actual implementation in case the list class is delegating.
62 */ 65 */
63 cx_list_class const *climpl; 66 const cx_list_class *climpl;
64 }; 67 };
65 68
66 /** 69 /**
67 * The class definition for arbitrary lists. 70 * The class definition for arbitrary lists.
68 */ 71 */
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, if an allocator is provided. 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 */
82 int (*insert_element)( 85 int (*insert_element)(
83 struct cx_list_s *list, 86 struct cx_list_s *list,
84 size_t index, 87 size_t index,
85 void const *data 88 const void *data
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 *
95 * @see cx_list_default_insert_array()
91 */ 96 */
92 size_t (*insert_array)( 97 size_t (*insert_array)(
93 struct cx_list_s *list, 98 struct cx_list_s *list,
94 size_t index, 99 size_t index,
95 void const *data, 100 const void *data,
96 size_t n 101 size_t n
97 ); 102 );
98 103
99 /** 104 /**
105 * Member function for inserting sorted elements into a sorted list.
106 *
107 * @see cx_list_default_insert_sorted()
108 */
109 size_t (*insert_sorted)(
110 struct cx_list_s *list,
111 const void *sorted_data,
112 size_t n
113 );
114
115 /**
100 * Member function for inserting an element relative to an iterator position. 116 * Member function for inserting an element relative to an iterator position.
101 */ 117 */
102 int (*insert_iter)( 118 int (*insert_iter)(
103 struct cx_iterator_s *iter, 119 struct cx_iterator_s *iter,
104 void const *elem, 120 const void *elem,
105 int prepend 121 int prepend
106 ); 122 );
107 123
108 /** 124 /**
109 * Member function for removing an element. 125 * Member function for removing elements.
110 */ 126 *
111 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)(
112 struct cx_list_s *list, 135 struct cx_list_s *list,
113 size_t index 136 size_t index,
137 size_t num,
138 void *targetbuf
114 ); 139 );
115 140
116 /** 141 /**
117 * Member function for removing all elements. 142 * Member function for removing all elements.
118 */ 143 */
119 void (*clear)(struct cx_list_s *list); 144 void (*clear)(struct cx_list_s *list);
120 145
121 /** 146 /**
122 * Member function for swapping two elements. 147 * Member function for swapping two elements.
148 *
149 * @see cx_list_default_swap()
123 */ 150 */
124 int (*swap)( 151 int (*swap)(
125 struct cx_list_s *list, 152 struct cx_list_s *list,
126 size_t i, 153 size_t i,
127 size_t j 154 size_t j
129 156
130 /** 157 /**
131 * Member function for element lookup. 158 * Member function for element lookup.
132 */ 159 */
133 void *(*at)( 160 void *(*at)(
134 struct cx_list_s const *list, 161 const struct cx_list_s *list,
135 size_t index 162 size_t index
136 ); 163 );
137 164
138 /** 165 /**
139 * Member function for finding and optionally removing an element. 166 * Member function for finding and optionally removing an element.
140 */ 167 */
141 ssize_t (*find_remove)( 168 ssize_t (*find_remove)(
142 struct cx_list_s *list, 169 struct cx_list_s *list,
143 void const *elem, 170 const void *elem,
144 bool remove 171 bool remove
145 ); 172 );
146 173
147 /** 174 /**
148 * Member function for sorting the list in-place. 175 * Member function for sorting the list.
176 *
177 * @see cx_list_default_sort()
149 */ 178 */
150 void (*sort)(struct cx_list_s *list); 179 void (*sort)(struct cx_list_s *list);
151 180
152 /** 181 /**
153 * Member function for comparing this list to another list of the same type. 182 * Optional member function for comparing this list
154 */ 183 * to another list of the same type.
184 * If set to @c NULL, comparison won't be optimized.
185 */
186 cx_attr_nonnull
155 int (*compare)( 187 int (*compare)(
156 struct cx_list_s const *list, 188 const struct cx_list_s *list,
157 struct cx_list_s const *other 189 const struct cx_list_s *other
158 ); 190 );
159 191
160 /** 192 /**
161 * Member function for reversing the order of the items. 193 * Member function for reversing the order of the items.
162 */ 194 */
164 196
165 /** 197 /**
166 * Member function for returning an iterator pointing to the specified index. 198 * Member function for returning an iterator pointing to the specified index.
167 */ 199 */
168 struct cx_iterator_s (*iterator)( 200 struct cx_iterator_s (*iterator)(
169 struct cx_list_s const *list, 201 const struct cx_list_s *list,
170 size_t index, 202 size_t index,
171 bool backward 203 bool backward
172 ); 204 );
173 }; 205 };
174 206
175 /** 207 /**
208 * Default implementation of an array insert.
209 *
210 * This function uses the element insert function for each element of the array.
211 *
212 * Use this in your own list class if you do not want to implement an optimized
213 * version for your list.
214 *
215 * @param list the list
216 * @param index the index where to insert the data
217 * @param data a pointer to the array of data to insert
218 * @param n the number of elements to insert
219 * @return the number of elements actually inserted
220 */
221 cx_attr_nonnull
222 size_t cx_list_default_insert_array(
223 struct cx_list_s *list,
224 size_t index,
225 const void *data,
226 size_t n
227 );
228
229 /**
230 * Default implementation of a sorted insert.
231 *
232 * This function uses the array insert function to insert consecutive groups
233 * of sorted data.
234 *
235 * The source data @em must already be sorted wrt. the list's compare function.
236 *
237 * Use this in your own list class if you do not want to implement an optimized
238 * version for your list.
239 *
240 * @param list the list
241 * @param sorted_data a pointer to the array of pre-sorted data to insert
242 * @param n the number of elements to insert
243 * @return the number of elements actually inserted
244 */
245 cx_attr_nonnull
246 size_t cx_list_default_insert_sorted(
247 struct cx_list_s *list,
248 const void *sorted_data,
249 size_t n
250 );
251
252 /**
253 * Default unoptimized sort implementation.
254 *
255 * This function will copy all data to an array, sort the array with standard
256 * qsort, and then copy the data back to the list memory.
257 *
258 * Use this in your own list class if you do not want to implement an optimized
259 * version for your list.
260 *
261 * @param list the list that shall be sorted
262 */
263 cx_attr_nonnull
264 void cx_list_default_sort(struct cx_list_s *list);
265
266 /**
267 * Default unoptimized swap implementation.
268 *
269 * Use this in your own list class if you do not want to implement an optimized
270 * version for your list.
271 *
272 * @param list the list in which to swap
273 * @param i index of one element
274 * @param j index of the other element
275 * @retval zero success
276 * @retval non-zero when indices are out of bounds or memory
277 * allocation for the temporary buffer fails
278 */
279 cx_attr_nonnull
280 int cx_list_default_swap(struct cx_list_s *list, size_t i, size_t j);
281
282 /**
176 * Common type for all list implementations. 283 * Common type for all list implementations.
177 */ 284 */
178 typedef struct cx_list_s CxList; 285 typedef struct cx_list_s CxList;
179 286
180 /** 287 /**
184 * within this list. 291 * within this list.
185 * 292 *
186 * @param list the list 293 * @param list the list
187 * @see cxListStorePointers() 294 * @see cxListStorePointers()
188 */ 295 */
189 __attribute__((__nonnull__)) 296 cx_attr_nonnull
190 void cxListStoreObjects(CxList *list); 297 void cxListStoreObjects(CxList *list);
191 298
192 /** 299 /**
193 * Advises the list to only store pointers to the objects. 300 * Advises the list to only store pointers to the objects.
194 * 301 *
199 * objects is undefined. 306 * objects is undefined.
200 * 307 *
201 * @param list the list 308 * @param list the list
202 * @see cxListStoreObjects() 309 * @see cxListStoreObjects()
203 */ 310 */
204 __attribute__((__nonnull__)) 311 cx_attr_nonnull
205 void cxListStorePointers(CxList *list); 312 void cxListStorePointers(CxList *list);
206 313
207 /** 314 /**
208 * 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.
209 * 316 *
210 * @param list 317 * @param list
211 * @return true, if this list is storing pointers 318 * @return true, if this list is storing pointers
212 * @see cxListStorePointers() 319 * @see cxListStorePointers()
213 */ 320 */
214 __attribute__((__nonnull__)) 321 cx_attr_nonnull
215 static inline bool cxListIsStoringPointers(CxList const *list) { 322 static inline bool cxListIsStoringPointers(const CxList *list) {
216 return list->collection.store_pointer; 323 return list->collection.store_pointer;
217 } 324 }
218 325
219 /** 326 /**
220 * Returns the number of elements currently stored in the list. 327 * Returns the number of elements currently stored in the list.
221 * 328 *
222 * @param list the list 329 * @param list the list
223 * @return the number of currently stored elements 330 * @return the number of currently stored elements
224 */ 331 */
225 __attribute__((__nonnull__)) 332 cx_attr_nonnull
226 static inline size_t cxListSize(CxList const *list) { 333 static inline size_t cxListSize(const CxList *list) {
227 return list->collection.size; 334 return list->collection.size;
228 } 335 }
229 336
230 /** 337 /**
231 * Adds an item to the end of the list. 338 * Adds an item to the end of the list.
232 * 339 *
233 * @param list the list 340 * @param list the list
234 * @param elem a pointer to the element to add 341 * @param elem a pointer to the element to add
235 * @return zero on success, non-zero on memory allocation failure 342 * @retval zero success
343 * @retval non-zero memory allocation failure
236 * @see cxListAddArray() 344 * @see cxListAddArray()
237 */ 345 */
238 __attribute__((__nonnull__)) 346 cx_attr_nonnull
239 static inline int cxListAdd( 347 static inline int cxListAdd(
240 CxList *list, 348 CxList *list,
241 void const *elem 349 const void *elem
242 ) { 350 ) {
243 return list->cl->insert_element(list, list->collection.size, elem); 351 return list->cl->insert_element(list, list->collection.size, elem);
244 } 352 }
245 353
246 /** 354 /**
247 * Adds multiple items to the end of the list. 355 * Adds multiple items to the end of the list.
248 * 356 *
249 * This method is more efficient than invoking cxListAdd() multiple times. 357 * This method is more efficient than invoking cxListAdd() multiple times.
250 * 358 *
251 * 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
252 * less than \p n. 360 * less than @p n.
253 * 361 *
254 * 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
255 * be an array of pointers. 363 * be an array of pointers.
256 * 364 *
257 * @param list the list 365 * @param list the list
258 * @param array a pointer to the elements to add 366 * @param array a pointer to the elements to add
259 * @param n the number of elements to add 367 * @param n the number of elements to add
260 * @return the number of added elements 368 * @return the number of added elements
261 */ 369 */
262 __attribute__((__nonnull__)) 370 cx_attr_nonnull
263 static inline size_t cxListAddArray( 371 static inline size_t cxListAddArray(
264 CxList *list, 372 CxList *list,
265 void const *array, 373 const void *array,
266 size_t n 374 size_t n
267 ) { 375 ) {
268 return list->cl->insert_array(list, list->collection.size, array, n); 376 return list->cl->insert_array(list, list->collection.size, array, n);
269 } 377 }
270 378
271 /** 379 /**
272 * Inserts an item at the specified index. 380 * Inserts an item at the specified index.
273 * 381 *
274 * 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().
275 * 383 *
276 * @param list the list 384 * @param list the list
277 * @param index the index the element shall have 385 * @param index the index the element shall have
278 * @param elem a pointer to the element to add 386 * @param elem a pointer to the element to add
279 * @return zero on success, non-zero on memory allocation failure 387 * @retval zero success
280 * or when the index is out of bounds 388 * @retval non-zero memory allocation failure or the index is out of bounds
281 * @see cxListInsertAfter() 389 * @see cxListInsertAfter()
282 * @see cxListInsertBefore() 390 * @see cxListInsertBefore()
283 */ 391 */
284 __attribute__((__nonnull__)) 392 cx_attr_nonnull
285 static inline int cxListInsert( 393 static inline int cxListInsert(
286 CxList *list, 394 CxList *list,
287 size_t index, 395 size_t index,
288 void const *elem 396 const void *elem
289 ) { 397 ) {
290 return list->cl->insert_element(list, index, elem); 398 return list->cl->insert_element(list, index, elem);
291 } 399 }
292 400
293 /** 401 /**
402 * Inserts an item into a sorted list.
403 *
404 * @param list the list
405 * @param elem a pointer to the element to add
406 * @retval zero success
407 * @retval non-zero memory allocation failure
408 */
409 cx_attr_nonnull
410 static inline int cxListInsertSorted(
411 CxList *list,
412 const void *elem
413 ) {
414 const void *data = list->collection.store_pointer ? &elem : elem;
415 return list->cl->insert_sorted(list, data, 1) == 0;
416 }
417
418 /**
294 * Inserts multiple items to the list at the specified index. 419 * Inserts multiple items to the list at the specified index.
295 * If \p index equals the list size, this is effectively cxListAddArray(). 420 * If @p index equals the list size, this is effectively cxListAddArray().
296 * 421 *
297 * This method is usually more efficient than invoking cxListInsert() 422 * This method is usually more efficient than invoking cxListInsert()
298 * multiple times. 423 * multiple times.
299 * 424 *
300 * 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
301 * less than \p n. 426 * less than @p n.
302 * 427 *
303 * 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
304 * be an array of pointers. 429 * be an array of pointers.
305 * 430 *
306 * @param list the list 431 * @param list the list
307 * @param index the index where to add the elements 432 * @param index the index where to add the elements
308 * @param array a pointer to the elements to add 433 * @param array a pointer to the elements to add
309 * @param n the number of elements to add 434 * @param n the number of elements to add
310 * @return the number of added elements 435 * @return the number of added elements
311 */ 436 */
312 __attribute__((__nonnull__)) 437 cx_attr_nonnull
313 static inline size_t cxListInsertArray( 438 static inline size_t cxListInsertArray(
314 CxList *list, 439 CxList *list,
315 size_t index, 440 size_t index,
316 void const *array, 441 const void *array,
317 size_t n 442 size_t n
318 ) { 443 ) {
319 return list->cl->insert_array(list, index, array, n); 444 return list->cl->insert_array(list, index, array, n);
445 }
446
447 /**
448 * Inserts a sorted array into a sorted list.
449 *
450 * This method is usually more efficient than inserting each element separately,
451 * because consecutive chunks of sorted data are inserted in one pass.
452 *
453 * If there is not enough memory to add all elements, the returned value is
454 * less than @p n.
455 *
456 * If this list is storing pointers instead of objects @p array is expected to
457 * be an array of pointers.
458 *
459 * @param list the list
460 * @param array a pointer to the elements to add
461 * @param n the number of elements to add
462 * @return the number of added elements
463 */
464 cx_attr_nonnull
465 static inline size_t cxListInsertSortedArray(
466 CxList *list,
467 const void *array,
468 size_t n
469 ) {
470 return list->cl->insert_sorted(list, array, n);
320 } 471 }
321 472
322 /** 473 /**
323 * Inserts an element after the current location of the specified iterator. 474 * Inserts an element after the current location of the specified iterator.
324 * 475 *
325 * The used iterator remains operational, but all other active iterators should 476 * The used iterator remains operational, but all other active iterators should
326 * be considered invalidated. 477 * be considered invalidated.
327 * 478 *
328 * 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.
329 * 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.
330 * 481 *
331 * @param iter an iterator 482 * @param iter an iterator
332 * @param elem the element to insert 483 * @param elem the element to insert
333 * @return zero on success, non-zero on memory allocation failure 484 * @retval zero success
485 * @retval non-zero memory allocation failure
334 * @see cxListInsert() 486 * @see cxListInsert()
335 * @see cxListInsertBefore() 487 * @see cxListInsertBefore()
336 */ 488 */
337 __attribute__((__nonnull__)) 489 cx_attr_nonnull
338 static inline int cxListInsertAfter( 490 static inline int cxListInsertAfter(
339 CxIterator *iter, 491 CxIterator *iter,
340 void const *elem 492 const void *elem
341 ) { 493 ) {
342 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);
343 } 495 }
344 496
345 /** 497 /**
346 * Inserts an element before the current location of the specified iterator. 498 * Inserts an element before the current location of the specified iterator.
347 * 499 *
348 * The used iterator remains operational, but all other active iterators should 500 * The used iterator remains operational, but all other active iterators should
349 * be considered invalidated. 501 * be considered invalidated.
350 * 502 *
351 * 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.
352 * 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.
353 * 505 *
354 * @param iter an iterator 506 * @param iter an iterator
355 * @param elem the element to insert 507 * @param elem the element to insert
356 * @return zero on success, non-zero on memory allocation failure 508 * @retval zero success
509 * @retval non-zero memory allocation failure
357 * @see cxListInsert() 510 * @see cxListInsert()
358 * @see cxListInsertAfter() 511 * @see cxListInsertAfter()
359 */ 512 */
360 __attribute__((__nonnull__)) 513 cx_attr_nonnull
361 static inline int cxListInsertBefore( 514 static inline int cxListInsertBefore(
362 CxIterator *iter, 515 CxIterator *iter,
363 void const *elem 516 const void *elem
364 ) { 517 ) {
365 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);
366 } 519 }
367 520
368 /** 521 /**
371 * If an element destructor function is specified, it is called before 524 * If an element destructor function is specified, it is called before
372 * removing the element. 525 * removing the element.
373 * 526 *
374 * @param list the list 527 * @param list the list
375 * @param index the index of the element 528 * @param index the index of the element
376 * @return zero on success, non-zero if the index is out of bounds 529 * @retval zero success
377 */ 530 * @retval non-zero index out of bounds
378 __attribute__((__nonnull__)) 531 */
532 cx_attr_nonnull
379 static inline int cxListRemove( 533 static inline int cxListRemove(
380 CxList *list, 534 CxList *list,
381 size_t index 535 size_t index
382 ) { 536 ) {
383 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);
384 } 607 }
385 608
386 /** 609 /**
387 * Removes all elements from this list. 610 * Removes all elements from this list.
388 * 611 *
389 * If an element destructor function is specified, it is called for each 612 * If element destructor functions are specified, they are called for each
390 * element before removing them. 613 * element before removing them.
391 * 614 *
392 * @param list the list 615 * @param list the list
393 */ 616 */
394 __attribute__((__nonnull__)) 617 cx_attr_nonnull
395 static inline void cxListClear(CxList *list) { 618 static inline void cxListClear(CxList *list) {
396 list->cl->clear(list); 619 list->cl->clear(list);
397 } 620 }
398 621
399 /** 622 /**
403 * it is necessary. 626 * it is necessary.
404 * 627 *
405 * @param list the list 628 * @param list the list
406 * @param i the index of the first element 629 * @param i the index of the first element
407 * @param j the index of the second element 630 * @param j the index of the second element
408 * @return zero on success, non-zero if one of the indices is out of bounds 631 * @retval zero success
409 */ 632 * @retval non-zero one of the indices is out of bounds
410 __attribute__((__nonnull__)) 633 * or the swap needed extra memory but allocation failed
634 */
635 cx_attr_nonnull
411 static inline int cxListSwap( 636 static inline int cxListSwap(
412 CxList *list, 637 CxList *list,
413 size_t i, 638 size_t i,
414 size_t j 639 size_t j
415 ) { 640 ) {
419 /** 644 /**
420 * Returns a pointer to the element at the specified index. 645 * Returns a pointer to the element at the specified index.
421 * 646 *
422 * @param list the list 647 * @param list the list
423 * @param index the index of the element 648 * @param index the index of the element
424 * @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
425 */ 650 */
426 __attribute__((__nonnull__)) 651 cx_attr_nonnull
427 static inline void *cxListAt( 652 static inline void *cxListAt(
428 CxList *list, 653 const CxList *list,
429 size_t index 654 size_t index
430 ) { 655 ) {
431 return list->cl->at(list, index); 656 return list->cl->at(list, index);
432 } 657 }
433 658
440 * 665 *
441 * @param list the list 666 * @param list the list
442 * @param index the index where the iterator shall point at 667 * @param index the index where the iterator shall point at
443 * @return a new iterator 668 * @return a new iterator
444 */ 669 */
445 __attribute__((__nonnull__, __warn_unused_result__)) 670 cx_attr_nonnull
671 cx_attr_nodiscard
446 static inline CxIterator cxListIteratorAt( 672 static inline CxIterator cxListIteratorAt(
447 CxList const *list, 673 const CxList *list,
448 size_t index 674 size_t index
449 ) { 675 ) {
450 return list->cl->iterator(list, index, false); 676 return list->cl->iterator(list, index, false);
451 } 677 }
452 678
459 * 685 *
460 * @param list the list 686 * @param list the list
461 * @param index the index where the iterator shall point at 687 * @param index the index where the iterator shall point at
462 * @return a new iterator 688 * @return a new iterator
463 */ 689 */
464 __attribute__((__nonnull__, __warn_unused_result__)) 690 cx_attr_nonnull
691 cx_attr_nodiscard
465 static inline CxIterator cxListBackwardsIteratorAt( 692 static inline CxIterator cxListBackwardsIteratorAt(
466 CxList const *list, 693 const CxList *list,
467 size_t index 694 size_t index
468 ) { 695 ) {
469 return list->cl->iterator(list, index, true); 696 return list->cl->iterator(list, index, true);
470 } 697 }
471 698
478 * 705 *
479 * @param list the list 706 * @param list the list
480 * @param index the index where the iterator shall point at 707 * @param index the index where the iterator shall point at
481 * @return a new iterator 708 * @return a new iterator
482 */ 709 */
483 __attribute__((__nonnull__, __warn_unused_result__)) 710 cx_attr_nonnull
711 cx_attr_nodiscard
484 CxIterator cxListMutIteratorAt( 712 CxIterator cxListMutIteratorAt(
485 CxList *list, 713 CxList *list,
486 size_t index 714 size_t index
487 ); 715 );
488 716
496 * 724 *
497 * @param list the list 725 * @param list the list
498 * @param index the index where the iterator shall point at 726 * @param index the index where the iterator shall point at
499 * @return a new iterator 727 * @return a new iterator
500 */ 728 */
501 __attribute__((__nonnull__, __warn_unused_result__)) 729 cx_attr_nonnull
730 cx_attr_nodiscard
502 CxIterator cxListMutBackwardsIteratorAt( 731 CxIterator cxListMutBackwardsIteratorAt(
503 CxList *list, 732 CxList *list,
504 size_t index 733 size_t index
505 ); 734 );
506 735
512 * 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.
513 * 742 *
514 * @param list the list 743 * @param list the list
515 * @return a new iterator 744 * @return a new iterator
516 */ 745 */
517 __attribute__((__nonnull__, __warn_unused_result__)) 746 cx_attr_nonnull
518 static inline CxIterator cxListIterator(CxList const *list) { 747 cx_attr_nodiscard
748 static inline CxIterator cxListIterator(const CxList *list) {
519 return list->cl->iterator(list, 0, false); 749 return list->cl->iterator(list, 0, false);
520 } 750 }
521 751
522 /** 752 /**
523 * Returns a mutating iterator pointing to the first item of the list. 753 * Returns a mutating iterator pointing to the first item of the list.
527 * 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.
528 * 758 *
529 * @param list the list 759 * @param list the list
530 * @return a new iterator 760 * @return a new iterator
531 */ 761 */
532 __attribute__((__nonnull__, __warn_unused_result__)) 762 cx_attr_nonnull
763 cx_attr_nodiscard
533 static inline CxIterator cxListMutIterator(CxList *list) { 764 static inline CxIterator cxListMutIterator(CxList *list) {
534 return cxListMutIteratorAt(list, 0); 765 return cxListMutIteratorAt(list, 0);
535 } 766 }
536 767
537 768
543 * 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.
544 * 775 *
545 * @param list the list 776 * @param list the list
546 * @return a new iterator 777 * @return a new iterator
547 */ 778 */
548 __attribute__((__nonnull__, __warn_unused_result__)) 779 cx_attr_nonnull
549 static inline CxIterator cxListBackwardsIterator(CxList const *list) { 780 cx_attr_nodiscard
781 static inline CxIterator cxListBackwardsIterator(const CxList *list) {
550 return list->cl->iterator(list, list->collection.size - 1, true); 782 return list->cl->iterator(list, list->collection.size - 1, true);
551 } 783 }
552 784
553 /** 785 /**
554 * Returns a mutating backwards iterator pointing to the last item of the list. 786 * Returns a mutating backwards iterator pointing to the last item of the list.
558 * 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.
559 * 791 *
560 * @param list the list 792 * @param list the list
561 * @return a new iterator 793 * @return a new iterator
562 */ 794 */
563 __attribute__((__nonnull__, __warn_unused_result__)) 795 cx_attr_nonnull
796 cx_attr_nodiscard
564 static inline CxIterator cxListMutBackwardsIterator(CxList *list) { 797 static inline CxIterator cxListMutBackwardsIterator(CxList *list) {
565 return cxListMutBackwardsIteratorAt(list, list->collection.size - 1); 798 return cxListMutBackwardsIteratorAt(list, list->collection.size - 1);
566 } 799 }
567 800
568 /** 801 /**
569 * Returns the index of the first element that equals \p elem. 802 * Returns the index of the first element that equals @p elem.
570 * 803 *
571 * Determining equality is performed by the list's comparator function. 804 * Determining equality is performed by the list's comparator function.
572 * 805 *
573 * @param list the list 806 * @param list the list
574 * @param elem the element to find 807 * @param elem the element to find
575 * @return the index of the element or a negative 808 * @return the index of the element or a negative
576 * value when the element is not found 809 * value when the element is not found
577 */ 810 */
578 __attribute__((__nonnull__)) 811 cx_attr_nonnull
812 cx_attr_nodiscard
579 static inline ssize_t cxListFind( 813 static inline ssize_t cxListFind(
580 CxList const *list, 814 const CxList *list,
581 void const *elem 815 const void *elem
582 ) { 816 ) {
583 return list->cl->find_remove((CxList*)list, elem, false); 817 return list->cl->find_remove((CxList*)list, elem, false);
584 } 818 }
585 819
586 /** 820 /**
587 * 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.
588 * 822 *
589 * Determining equality is performed by the list's comparator function. 823 * Determining equality is performed by the list's comparator function.
590 * 824 *
591 * @param list the list 825 * @param list the list
592 * @param elem the element to find and remove 826 * @param elem the element to find and remove
593 * @return the index of the now removed element or a negative 827 * @return the index of the now removed element or a negative
594 * 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
595 */ 829 */
596 __attribute__((__nonnull__)) 830 cx_attr_nonnull
597 static inline ssize_t cxListFindRemove( 831 static inline ssize_t cxListFindRemove(
598 CxList *list, 832 CxList *list,
599 void const *elem 833 const void *elem
600 ) { 834 ) {
601 return list->cl->find_remove(list, elem, true); 835 return list->cl->find_remove(list, elem, true);
602 } 836 }
603 837
604 /** 838 /**
605 * Sorts the list in-place. 839 * Sorts the list.
606 * 840 *
607 * \remark The underlying sort algorithm is implementation defined. 841 * @remark The underlying sort algorithm is implementation defined.
608 * 842 *
609 * @param list the list 843 * @param list the list
610 */ 844 */
611 __attribute__((__nonnull__)) 845 cx_attr_nonnull
612 static inline void cxListSort(CxList *list) { 846 static inline void cxListSort(CxList *list) {
613 list->cl->sort(list); 847 list->cl->sort(list);
614 } 848 }
615 849
616 /** 850 /**
617 * Reverses the order of the items. 851 * Reverses the order of the items.
618 * 852 *
619 * @param list the list 853 * @param list the list
620 */ 854 */
621 __attribute__((__nonnull__)) 855 cx_attr_nonnull
622 static inline void cxListReverse(CxList *list) { 856 static inline void cxListReverse(CxList *list) {
623 list->cl->reverse(list); 857 list->cl->reverse(list);
624 } 858 }
625 859
626 /** 860 /**
629 * First, the list sizes are compared. 863 * First, the list sizes are compared.
630 * If they match, the lists are compared element-wise. 864 * If they match, the lists are compared element-wise.
631 * 865 *
632 * @param list the list 866 * @param list the list
633 * @param other the list to compare to 867 * @param other the list to compare to
634 * @return zero, if both lists are equal element wise, 868 * @retval zero both lists are equal element wise
635 * negative if the first list is smaller, positive if the first list is larger 869 * @retval negative the first list is smaller
636 */ 870 * or the first non-equal element in the first list is smaller
637 __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
638 int cxListCompare( 876 int cxListCompare(
639 CxList const *list, 877 const CxList *list,
640 CxList const *other 878 const CxList *other
641 ); 879 );
642 880
643 /** 881 /**
644 * Deallocates the memory of the specified list structure. 882 * Deallocates the memory of the specified list structure.
645 * 883 *
646 * Also calls content a destructor function, depending on the configuration 884 * Also calls the content destructor functions for each element, if specified.
647 * in CxList.content_destructor_type. 885 *
648 * 886 * @param list the list which shall be freed
649 * This function itself is a destructor function for the CxList. 887 */
650 * 888 void cxListFree(CxList *list);
651 * @param list the list which shall be destroyed
652 */
653 __attribute__((__nonnull__))
654 void cxListDestroy(CxList *list);
655 889
656 /** 890 /**
657 * A shared instance of an empty list. 891 * A shared instance of an empty list.
658 * 892 *
659 * Writing to that list is undefined. 893 * Writing to that list is not allowed.
660 */ 894 *
661 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;
662 899
663 900
664 #ifdef __cplusplus 901 #ifdef __cplusplus
665 } // extern "C" 902 } // extern "C"
666 #endif 903 #endif

mercurial