src/cx/iterator.h

changeset 853
d4baf4dd55c3
parent 852
16e2a3391e88
child 854
fe0d69d72bcd
     1.1 --- a/src/cx/iterator.h	Thu May 23 18:21:36 2024 +0200
     1.2 +++ b/src/cx/iterator.h	Thu May 23 19:29:14 2024 +0200
     1.3 @@ -38,68 +38,64 @@
     1.4  
     1.5  #include "common.h"
     1.6  
     1.7 +#define CX_ITERATOR_BASE \
     1.8 +    /** \
     1.9 +     * True iff the iterator points to valid data. \
    1.10 +     */ \
    1.11 +    __attribute__ ((__nonnull__)) \
    1.12 +    bool (*valid)(void const *); \
    1.13 +    /** \
    1.14 +     * Returns a pointer to the current element. \
    1.15 +     * \
    1.16 +     * When valid returns false, the behavior of this function is undefined. \
    1.17 +     */ \
    1.18 +    __attribute__ ((__nonnull__)) \
    1.19 +    void *(*current)(void const *); \
    1.20 +    /** \
    1.21 +     * Original implementation in case the function needs to be wrapped. \
    1.22 +     */ \
    1.23 +    __attribute__ ((__nonnull__)) \
    1.24 +    void *(*current_impl)(void const *); \
    1.25 +    /** \
    1.26 +     * Advances the iterator. \
    1.27 +     * \
    1.28 +     * When valid returns false, the behavior of this function is undefined. \
    1.29 +     */ \
    1.30 +    __attribute__ ((__nonnull__)) \
    1.31 +    void (*next)(void *); \
    1.32 +    /** \
    1.33 +     * Indicates whether this iterator may remove elements. \
    1.34 +     */ \
    1.35 +    bool mutating; \
    1.36 +    /** \
    1.37 +     * Internal flag for removing the current element when advancing. \
    1.38 +     */ \
    1.39 +    bool remove;
    1.40 +
    1.41  /**
    1.42 - * The base of mutating and non-mutating iterators.
    1.43 + * Internal iterator struct - use CxIterator.
    1.44   */
    1.45 -struct cx_iterator_base_s {
    1.46 -    /**
    1.47 -     * True iff the iterator points to valid data.
    1.48 -     */
    1.49 -    __attribute__ ((__nonnull__))
    1.50 -    bool (*valid)(void const *);
    1.51 +struct cx_iterator_s {
    1.52 +    CX_ITERATOR_BASE
    1.53  
    1.54      /**
    1.55 -     * Returns a pointer to the current element.
    1.56 -     *
    1.57 -     * When valid returns false, the behavior of this function is undefined.
    1.58 -     */
    1.59 -    __attribute__ ((__nonnull__))
    1.60 -    void *(*current)(void const *);
    1.61 -
    1.62 -    /**
    1.63 -     * Original implementation in case the function needs to be wrapped.
    1.64 -     */
    1.65 -    __attribute__ ((__nonnull__))
    1.66 -    void *(*current_impl)(void const *);
    1.67 -
    1.68 -    /**
    1.69 -     * Advances the iterator.
    1.70 -     *
    1.71 -     * When valid returns false, the behavior of this function is undefined.
    1.72 -     */
    1.73 -    __attribute__ ((__nonnull__))
    1.74 -    void (*next)(void *);
    1.75 -
    1.76 -    /**
    1.77 -     * Indicates whether this iterator may remove elements.
    1.78 -     */
    1.79 -    bool mutating;
    1.80 -
    1.81 -    /**
    1.82 -     * Internal flag for removing the current element when advancing.
    1.83 -     */
    1.84 -    bool remove;
    1.85 -};
    1.86 -
    1.87 -/**
    1.88 - * Internal iterator struct - use CxMutIterator.
    1.89 - */
    1.90 -struct cx_mut_iterator_s {
    1.91 -
    1.92 -    /**
    1.93 -     * The base properties of this iterator.
    1.94 -     */
    1.95 -    struct cx_iterator_base_s base;
    1.96 -
    1.97 -    /**
    1.98 -     * Handle for the current element, if required.
    1.99 +     * Handle for the current element.
   1.100       */
   1.101      void *elem_handle;
   1.102  
   1.103      /**
   1.104       * Handle for the source collection, if any.
   1.105       */
   1.106 -    void *src_handle;
   1.107 +    union {
   1.108 +        /**
   1.109 +         * Access for mutating iterators.
   1.110 +         */
   1.111 +        void *m;
   1.112 +        /**
   1.113 +         * Access for normal iterators.
   1.114 +         */
   1.115 +        void const *c;
   1.116 +    } src_handle;
   1.117  
   1.118      /**
   1.119       * Field for storing a key-value pair.
   1.120 @@ -141,91 +137,15 @@
   1.121  };
   1.122  
   1.123  /**
   1.124 - * Mutating iterator value type.
   1.125 + * Iterator type.
   1.126   *
   1.127 - * An iterator points to a certain element in an (possibly unbounded) chain of elements.
   1.128 - * Iterators that are based on collections (which have a defined "first" element), are supposed
   1.129 - * to be "position-aware", which means that they keep track of the current index within the collection.
   1.130 - *
   1.131 - * @note Objects that are pointed to by an iterator are mutable through that iterator. However, if the
   1.132 - * iterator is based on a collection and the underlying collection is mutated by other means than this iterator
   1.133 - * (e.g. elements added or removed), the iterator becomes invalid (regardless of what cxIteratorValid() returns)
   1.134 - * and MUST be re-obtained from the collection.
   1.135 - *
   1.136 - * @see CxIterator
   1.137 - */
   1.138 -typedef struct cx_mut_iterator_s CxMutIterator;
   1.139 -
   1.140 -/**
   1.141 - * Internal iterator struct - use CxIterator.
   1.142 - */
   1.143 -struct cx_iterator_s {
   1.144 -
   1.145 -    /**
   1.146 -     * The base properties of this iterator.
   1.147 -     */
   1.148 -    struct cx_iterator_base_s base;
   1.149 -
   1.150 -    /**
   1.151 -     * Handle for the current element, if required.
   1.152 -     */
   1.153 -    void *elem_handle;
   1.154 -
   1.155 -    /**
   1.156 -     * Handle for the source collection, if any.
   1.157 -     */
   1.158 -    void const *src_handle;
   1.159 -
   1.160 -    /**
   1.161 -     * Field for storing a key-value pair.
   1.162 -     * May be used by iterators that iterate over k/v-collections.
   1.163 -     */
   1.164 -    struct {
   1.165 -        /**
   1.166 -         * A pointer to the key.
   1.167 -         */
   1.168 -        void const *key;
   1.169 -        /**
   1.170 -         * A pointer to the value.
   1.171 -         */
   1.172 -        void *value;
   1.173 -    } kv_data;
   1.174 -
   1.175 -    /**
   1.176 -     * Field for storing a slot number.
   1.177 -     * May be used by iterators that iterate over multi-bucket collections.
   1.178 -     */
   1.179 -    size_t slot;
   1.180 -
   1.181 -    /**
   1.182 -     * If the iterator is position-aware, contains the index of the element in the underlying collection.
   1.183 -     * Otherwise, this field is usually uninitialized.
   1.184 -     */
   1.185 -    size_t index;
   1.186 -
   1.187 -    /**
   1.188 -     * The size of an individual element.
   1.189 -     */
   1.190 -    size_t elem_size;
   1.191 -
   1.192 -    /**
   1.193 -     * May contain the total number of elements, if known.
   1.194 -     * Shall be set to \c SIZE_MAX when the total number is unknown during iteration.
   1.195 -     */
   1.196 -    size_t elem_count;
   1.197 -};
   1.198 -
   1.199 -/**
   1.200 - * Iterator value type.
   1.201   * An iterator points to a certain element in a (possibly unbounded) chain of elements.
   1.202   * Iterators that are based on collections (which have a defined "first" element), are supposed
   1.203   * to be "position-aware", which means that they keep track of the current index within the collection.
   1.204   *
   1.205   * @note Objects that are pointed to by an iterator are always mutable through that iterator. However,
   1.206 - * this iterator cannot mutate the collection itself (add or remove elements) and any mutation of the
   1.207 - * collection by other means makes this iterator invalid (regardless of what cxIteratorValid() returns).
   1.208 - *
   1.209 - * @see CxMutIterator
   1.210 + * any concurrent mutation of the collection other than by this iterator makes this iterator invalid
   1.211 + * and it must not be used anymore.
   1.212   */
   1.213  typedef struct cx_iterator_s CxIterator;
   1.214  
   1.215 @@ -237,7 +157,7 @@
   1.216   * @param iter the iterator
   1.217   * @return true iff the iterator points to valid data
   1.218   */
   1.219 -#define cxIteratorValid(iter) (iter).base.valid(&(iter))
   1.220 +#define cxIteratorValid(iter) (iter).valid(&(iter))
   1.221  
   1.222  /**
   1.223   * Returns a pointer to the current element.
   1.224 @@ -247,21 +167,21 @@
   1.225   * @param iter the iterator
   1.226   * @return a pointer to the current element
   1.227   */
   1.228 -#define cxIteratorCurrent(iter) (iter).base.current(&iter)
   1.229 +#define cxIteratorCurrent(iter) (iter).current(&iter)
   1.230  
   1.231  /**
   1.232   * Advances the iterator to the next element.
   1.233   *
   1.234   * @param iter the iterator
   1.235   */
   1.236 -#define cxIteratorNext(iter) (iter).base.next(&iter)
   1.237 +#define cxIteratorNext(iter) (iter).next(&iter)
   1.238  
   1.239  /**
   1.240   * Flags the current element for removal, if this iterator is mutating.
   1.241   *
   1.242   * @param iter the iterator
   1.243   */
   1.244 -#define cxIteratorFlagRemoval(iter) (iter).base.remove |= (iter).base.mutating
   1.245 +#define cxIteratorFlagRemoval(iter) (iter).remove |= (iter).mutating
   1.246  
   1.247  /**
   1.248   * Loops over an iterator.
   1.249 @@ -316,7 +236,7 @@
   1.250   * @return an iterator for the specified array
   1.251   */
   1.252  __attribute__((__warn_unused_result__))
   1.253 -CxMutIterator cxMutIterator(
   1.254 +CxIterator cxMutIterator(
   1.255          void *array,
   1.256          size_t elem_size,
   1.257          size_t elem_count,

mercurial