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 |
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 /** |
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 /** |
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 /** |