src/cx/iterator.h

changeset 853
d4baf4dd55c3
parent 852
16e2a3391e88
child 854
fe0d69d72bcd
--- a/src/cx/iterator.h	Thu May 23 18:21:36 2024 +0200
+++ b/src/cx/iterator.h	Thu May 23 19:29:14 2024 +0200
@@ -38,68 +38,64 @@
 
 #include "common.h"
 
-/**
- * The base of mutating and non-mutating iterators.
- */
-struct cx_iterator_base_s {
-    /**
-     * True iff the iterator points to valid data.
-     */
-    __attribute__ ((__nonnull__))
-    bool (*valid)(void const *);
+#define CX_ITERATOR_BASE \
+    /** \
+     * True iff the iterator points to valid data. \
+     */ \
+    __attribute__ ((__nonnull__)) \
+    bool (*valid)(void const *); \
+    /** \
+     * Returns a pointer to the current element. \
+     * \
+     * When valid returns false, the behavior of this function is undefined. \
+     */ \
+    __attribute__ ((__nonnull__)) \
+    void *(*current)(void const *); \
+    /** \
+     * Original implementation in case the function needs to be wrapped. \
+     */ \
+    __attribute__ ((__nonnull__)) \
+    void *(*current_impl)(void const *); \
+    /** \
+     * Advances the iterator. \
+     * \
+     * When valid returns false, the behavior of this function is undefined. \
+     */ \
+    __attribute__ ((__nonnull__)) \
+    void (*next)(void *); \
+    /** \
+     * Indicates whether this iterator may remove elements. \
+     */ \
+    bool mutating; \
+    /** \
+     * Internal flag for removing the current element when advancing. \
+     */ \
+    bool remove;
 
-    /**
-     * Returns a pointer to the current element.
-     *
-     * When valid returns false, the behavior of this function is undefined.
-     */
-    __attribute__ ((__nonnull__))
-    void *(*current)(void const *);
-
-    /**
-     * Original implementation in case the function needs to be wrapped.
-     */
-    __attribute__ ((__nonnull__))
-    void *(*current_impl)(void const *);
+/**
+ * Internal iterator struct - use CxIterator.
+ */
+struct cx_iterator_s {
+    CX_ITERATOR_BASE
 
     /**
-     * Advances the iterator.
-     *
-     * When valid returns false, the behavior of this function is undefined.
-     */
-    __attribute__ ((__nonnull__))
-    void (*next)(void *);
-
-    /**
-     * Indicates whether this iterator may remove elements.
-     */
-    bool mutating;
-
-    /**
-     * Internal flag for removing the current element when advancing.
-     */
-    bool remove;
-};
-
-/**
- * Internal iterator struct - use CxMutIterator.
- */
-struct cx_mut_iterator_s {
-
-    /**
-     * The base properties of this iterator.
-     */
-    struct cx_iterator_base_s base;
-
-    /**
-     * Handle for the current element, if required.
+     * Handle for the current element.
      */
     void *elem_handle;
 
     /**
      * Handle for the source collection, if any.
      */
-    void *src_handle;
+    union {
+        /**
+         * Access for mutating iterators.
+         */
+        void *m;
+        /**
+         * Access for normal iterators.
+         */
+        void const *c;
+    } src_handle;
 
     /**
      * Field for storing a key-value pair.
@@ -141,91 +137,15 @@
 };
 
 /**
- * Mutating iterator value type.
- *
- * An iterator points to a certain element in an (possibly unbounded) chain of elements.
- * Iterators that are based on collections (which have a defined "first" element), are supposed
- * 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 mutable through that iterator. However, if the
- * iterator is based on a collection and the underlying collection is mutated by other means than this iterator
- * (e.g. elements added or removed), the iterator becomes invalid (regardless of what cxIteratorValid() returns)
- * and MUST be re-obtained from the collection.
+ * Iterator type.
  *
- * @see CxIterator
- */
-typedef struct cx_mut_iterator_s CxMutIterator;
-
-/**
- * Internal iterator struct - use CxIterator.
- */
-struct cx_iterator_s {
-
-    /**
-     * The base properties of this iterator.
-     */
-    struct cx_iterator_base_s base;
-
-    /**
-     * Handle for the current element, if required.
-     */
-    void *elem_handle;
-
-    /**
-     * Handle for the source collection, if any.
-     */
-    void const *src_handle;
-
-    /**
-     * Field for storing a key-value pair.
-     * May be used by iterators that iterate over k/v-collections.
-     */
-    struct {
-        /**
-         * A pointer to the key.
-         */
-        void const *key;
-        /**
-         * A pointer to the value.
-         */
-        void *value;
-    } kv_data;
-
-    /**
-     * Field for storing a slot number.
-     * May be used by iterators that iterate over multi-bucket collections.
-     */
-    size_t slot;
-
-    /**
-     * If the iterator is position-aware, contains the index of the element in the underlying collection.
-     * Otherwise, this field is usually uninitialized.
-     */
-    size_t index;
-
-    /**
-     * The size of an individual element.
-     */
-    size_t elem_size;
-
-    /**
-     * May contain the total number of elements, if known.
-     * Shall be set to \c SIZE_MAX when the total number is unknown during iteration.
-     */
-    size_t elem_count;
-};
-
-/**
- * Iterator value type.
  * An iterator points to a certain element in a (possibly unbounded) chain of elements.
  * Iterators that are based on collections (which have a defined "first" element), are supposed
  * 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,
- * this iterator cannot mutate the collection itself (add or remove elements) and any mutation of the
- * collection by other means makes this iterator invalid (regardless of what cxIteratorValid() returns).
- *
- * @see CxMutIterator
+ * any concurrent mutation of the collection other than by this iterator makes this iterator invalid
+ * and it must not be used anymore.
  */
 typedef struct cx_iterator_s CxIterator;
 
@@ -237,7 +157,7 @@
  * @param iter the iterator
  * @return true iff the iterator points to valid data
  */
-#define cxIteratorValid(iter) (iter).base.valid(&(iter))
+#define cxIteratorValid(iter) (iter).valid(&(iter))
 
 /**
  * Returns a pointer to the current element.
@@ -247,21 +167,21 @@
  * @param iter the iterator
  * @return a pointer to the current element
  */
-#define cxIteratorCurrent(iter) (iter).base.current(&iter)
+#define cxIteratorCurrent(iter) (iter).current(&iter)
 
 /**
  * Advances the iterator to the next element.
  *
  * @param iter the iterator
  */
-#define cxIteratorNext(iter) (iter).base.next(&iter)
+#define cxIteratorNext(iter) (iter).next(&iter)
 
 /**
  * Flags the current element for removal, if this iterator is mutating.
  *
  * @param iter the iterator
  */
-#define cxIteratorFlagRemoval(iter) (iter).base.remove |= (iter).base.mutating
+#define cxIteratorFlagRemoval(iter) (iter).remove |= (iter).mutating
 
 /**
  * Loops over an iterator.
@@ -316,7 +236,7 @@
  * @return an iterator for the specified array
  */
 __attribute__((__warn_unused_result__))
-CxMutIterator cxMutIterator(
+CxIterator cxMutIterator(
         void *array,
         size_t elem_size,
         size_t elem_count,

mercurial