--- a/ucx/cx/iterator.h Sun Oct 19 21:20:08 2025 +0200 +++ b/ucx/cx/iterator.h Mon Nov 10 21:52:51 2025 +0100 @@ -50,7 +50,10 @@ * True if the iterator points to valid data. */ bool (*valid)(const void *); - + /** + * Original implementation in case the function needs to be wrapped. + */ + bool (*valid_impl)(const void *); /** * Returns a pointer to the current element. * @@ -62,7 +65,6 @@ * Original implementation in case the function needs to be wrapped. */ void *(*current_impl)(const void *); - /** * Advances the iterator. * @@ -76,7 +78,7 @@ /** * Indicates whether this iterator may remove elements. */ - bool mutating; + bool allow_remove; /** * Internal flag for removing the current element when advancing. */ @@ -112,16 +114,7 @@ /** * Handle for the source collection, if any. */ - union { - /** - * Access for mutating iterators. - */ - void *m; - /** - * Access for normal iterators. - */ - const void *c; - } src_handle; + void *src_handle; /** * If the iterator is position-aware, contains the index of the element in the underlying collection. @@ -149,7 +142,7 @@ * to be "position-aware", which means that they keep track of the current index within the collection. * * @note Objects that are pointed to by an iterator are always mutable through that iterator. However, - * any concurrent mutation of the collection other than by this iterator makes this iterator invalid, + * any concurrent mutation of the collection other than by this iterator makes this iterator obsolete, * and it must not be used anymore. */ typedef struct cx_iterator_s CxIterator; @@ -182,13 +175,12 @@ #define cxIteratorNext(iter) (iter).base.next(&iter) /** - * Flags the current element for removal if this iterator is mutating. - * - * Does nothing for non-mutating iterators. + * Flags the current element for removal if the iterator allows it. * * @param iter the iterator + * @return @c true if removal is allowed, @c false otherwise */ -#define cxIteratorFlagRemoval(iter) (iter).base.remove |= (iter).base.mutating +#define cxIteratorFlagRemoval(iter) ((iter).base.remove = (iter).base.allow_remove) /** * Obtains a reference to an arbitrary iterator. @@ -222,22 +214,34 @@ * use cxIteratorPtr() to create an iterator which directly * yields the stored pointers. * + * While the iterator is in use, the array may only be altered by removing + * elements through #cxIteratorFlagRemoval(). Every other change to the array + * will bring this iterator to an undefined state. + * + * When @p remove_keeps_order is set to @c false, removing an element will only + * move the last element to the position of the removed element, instead of + * moving all subsequent elements by one. Usually, when the order of elements is + * not important, this parameter should be set to @c false. + * * @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 + * @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 cxIteratorPtr() */ cx_attr_nodiscard -cx_attr_export -CxIterator cxIterator( - const void *array, - size_t elem_size, - size_t elem_count -); +CX_EXPORT CxIterator cxIterator(const void *array, + size_t elem_size, size_t elem_count, bool remove_keeps_order); /** - * Creates a mutating iterator for the specified plain array. + * 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 (on the other + * hand, an iterator created with cxIterator() would return the + * addresses of those pointers within the array). * * While the iterator is in use, the array may only be altered by removing * elements through #cxIteratorFlagRemoval(). Every other change to the array @@ -248,67 +252,16 @@ * moving all subsequent elements by one. Usually, when the order of elements is * not important, this parameter should be set to @c false. * - * The @p array can be @c NULL, in which case the iterator will be immediately - * initialized such that #cxIteratorValid() returns @c false. - * - * - * @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 - * @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 - */ -cx_attr_nodiscard -cx_attr_export -CxIterator cxMutIterator( - void *array, - size_t elem_size, - size_t elem_count, - 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 (on the other - * hand, 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 -cx_attr_export -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() + * @see cxIterator() */ cx_attr_nodiscard -cx_attr_export -CxIterator cxMutIteratorPtr( - void *array, - size_t elem_count, - bool remove_keeps_order -); +CX_EXPORT CxIterator cxIteratorPtr(const void *array, size_t elem_count, + bool remove_keeps_order); #ifdef __cplusplus } // extern "C"