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