--- a/ucx/cx/iterator.h Fri Jan 03 21:40:57 2025 +0100 +++ b/ucx/cx/iterator.h Sat Jan 04 13:03:01 2025 +0100 @@ -38,33 +38,42 @@ #include "common.h" +#ifdef __cplusplus +extern "C" { +#endif + +/** + * Common data for all iterators. + */ struct cx_iterator_base_s { /** * True iff the iterator points to valid data. */ - __attribute__ ((__nonnull__)) - bool (*valid)(void const *); + cx_attr_nonnull + bool (*valid)(const void *); /** * Returns a pointer to the current element. * * When valid returns false, the behavior of this function is undefined. */ - __attribute__ ((__nonnull__)) - void *(*current)(void const *); + cx_attr_nonnull + cx_attr_nodiscard + void *(*current)(const void *); /** * Original implementation in case the function needs to be wrapped. */ - __attribute__ ((__nonnull__)) - void *(*current_impl)(void const *); + cx_attr_nonnull + cx_attr_nodiscard + void *(*current_impl)(const void *); /** * Advances the iterator. * * When valid returns false, the behavior of this function is undefined. */ - __attribute__ ((__nonnull__)) + cx_attr_nonnull void (*next)(void *); /** * Indicates whether this iterator may remove elements. @@ -78,6 +87,7 @@ /** * Declares base attributes for an iterator. + * Must be the first member of an iterator structure. */ #define CX_ITERATOR_BASE struct cx_iterator_base_s base @@ -85,6 +95,9 @@ * Internal iterator struct - use CxIterator. */ struct cx_iterator_s { + /** + * Inherited common data for all iterators. + */ CX_ITERATOR_BASE; /** @@ -103,7 +116,7 @@ /** * Access for normal iterators. */ - void const *c; + const void *c; } src_handle; /** @@ -114,7 +127,7 @@ /** * A pointer to the key. */ - void const *key; + const void *key; /** * A pointer to the value. */ @@ -193,6 +206,15 @@ #define cxIteratorFlagRemoval(iter) (iter).base.remove |= (iter).base.mutating /** + * Obtains a reference to an arbitrary iterator. + * + * This is useful for APIs that expect some iterator as an argument. + * + * @param iter the iterator + */ +#define cxIteratorRef(iter) &((iter).base) + +/** * Loops over an iterator. * @param type the type of the elements * @param elem the name of the iteration variable @@ -208,15 +230,20 @@ * The \p array can be \c NULL in which case the iterator will be immediately * initialized such that #cxIteratorValid() returns \c false. * + * This iterator yields the addresses of the array elements. + * If you want to iterator over an array of pointers, you can + * use cxIteratorPtr() to create an iterator which directly + * yields the stored pointers. * * @param array a pointer to the array (can be \c NULL) * @param elem_size the size of one array element * @param elem_count the number of elements in the array * @return an iterator for the specified array + * @see cxIteratorPtr() */ -__attribute__((__warn_unused_result__)) +cx_attr_nodiscard CxIterator cxIterator( - void const *array, + const void *array, size_t elem_size, size_t elem_count ); @@ -244,7 +271,7 @@ * when removing an element * @return an iterator for the specified array */ -__attribute__((__warn_unused_result__)) +cx_attr_nodiscard CxIterator cxMutIterator( void *array, size_t elem_size, @@ -252,4 +279,48 @@ bool remove_keeps_order ); +/** + * Creates an iterator for the specified plain pointer array. + * + * This iterator assumes that every element in the array is a pointer + * and yields exactly those pointers during iteration (while in contrast + * an iterator created with cxIterator() would return the addresses + * of those pointers within the array). + * + * @param array a pointer to the array (can be \c NULL) + * @param elem_count the number of elements in the array + * @return an iterator for the specified array + * @see cxIterator() + */ +cx_attr_nodiscard +CxIterator cxIteratorPtr( + const void *array, + size_t elem_count +); + +/** + * Creates a mutating iterator for the specified plain pointer array. + * + * This is the mutating variant of cxIteratorPtr(). See also + * cxMutIterator(). + * + * @param array a pointer to the array (can be \c NULL) + * @param elem_count the number of elements in the array + * @param remove_keeps_order \c true if the order of elements must be preserved + * when removing an element + * @return an iterator for the specified array + * @see cxMutIterator() + * @see cxIteratorPtr() + */ +cx_attr_nodiscard +CxIterator cxMutIteratorPtr( + void *array, + size_t elem_count, + bool remove_keeps_order +); + +#ifdef __cplusplus +} // extern "C" +#endif + #endif // UCX_ITERATOR_H