src/cx/iterator.h

changeset 1429
6e0c3a8a914a
parent 1426
3a89b31f0724
--- a/src/cx/iterator.h	Fri Oct 17 15:04:56 2025 +0200
+++ b/src/cx/iterator.h	Fri Oct 17 16:53:24 2025 +0200
@@ -62,7 +62,6 @@
      * Original implementation in case the function needs to be wrapped.
      */
     void *(*current_impl)(const void *);
-
     /**
      * Advances the iterator.
      *
@@ -76,7 +75,7 @@
     /**
      * Indicates whether this iterator may remove elements.
      */
-    bool mutating;
+    bool allow_remove;
     /**
      * Internal flag for removing the current element when advancing.
      */
@@ -112,16 +111,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 +139,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 +172,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,18 +211,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_EXPORT CxIterator cxIterator(const void *array,
-        size_t elem_size, size_t elem_count);
+        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
@@ -244,54 +249,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_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_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_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"

mercurial