src/cx/iterator.h

changeset 630
ac5e7f789048
parent 628
1e2be40f0cb5
child 641
d402fead3386
equal deleted inserted replaced
629:6c81ee4f11ad 630:ac5e7f789048
38 #define UCX_ITERATOR_H 38 #define UCX_ITERATOR_H
39 39
40 #include "common.h" 40 #include "common.h"
41 41
42 /** 42 /**
43 * Internal iterator struct - use CxIterator. 43 * The base of mutating and non-mutating iterators.
44 */ 44 */
45 struct cx_iterator_s { 45 struct cx_iterator_base_s {
46 /** 46 /**
47 * True iff the iterator points to valid data. 47 * True iff the iterator points to valid data.
48 */ 48 */
49 __attribute__ ((__nonnull__)) 49 __attribute__ ((__nonnull__))
50 bool (*valid)(struct cx_iterator_s const *); 50 bool (*valid)(void const *);
51 51
52 /** 52 /**
53 * Returns a pointer to the current element. 53 * Returns a pointer to the current element.
54 */ 54 */
55 __attribute__ ((__nonnull__)) 55 __attribute__ ((__nonnull__))
56 void *(*current)(struct cx_iterator_s const *); 56 void *(*current)(void const *);
57 57
58 /** 58 /**
59 * Advances the iterator. 59 * Advances the iterator.
60 */ 60 */
61 __attribute__ ((__nonnull__)) 61 __attribute__ ((__nonnull__))
62 void (*next)(struct cx_iterator_s *); 62 void (*next)(void *);
63
64 /**
65 * Flag current element for removal, if possible.
66 */
67 __attribute__ ((__nonnull__))
68 bool (*flag_removal)(void *);
69
70 /**
71 * Indicates whether this iterator is muting.
72 */
73 bool mutating;
74
75 /**
76 * Internal flag for removing the current element when advancing.
77 */
78 bool remove;
79 };
80
81 /**
82 * Internal iterator struct - use CxMutIterator.
83 */
84 struct cx_mut_iterator_s {
85
86 /**
87 * The base properties of this iterator.
88 */
89 struct cx_iterator_base_s base;
63 90
64 /** 91 /**
65 * Handle for the current element, if required. 92 * Handle for the current element, if required.
66 */ 93 */
67 void *elem_handle; 94 void *elem_handle;
77 */ 104 */
78 struct { 105 struct {
79 /** 106 /**
80 * A pointer to the key. 107 * A pointer to the key.
81 */ 108 */
82 void *key; 109 void const *key;
83 /** 110 /**
84 * A pointer to the value. 111 * A pointer to the value.
85 */ 112 */
86 void *value; 113 void *value;
87 } kv_data; 114 } kv_data;
95 /** 122 /**
96 * If the iterator is position-aware, contains the index of the element in the underlying collection. 123 * If the iterator is position-aware, contains the index of the element in the underlying collection.
97 * Otherwise, this field is usually uninitialized. 124 * Otherwise, this field is usually uninitialized.
98 */ 125 */
99 size_t index; 126 size_t index;
100 127 };
101 /** 128
102 * Users may set this to true, if the current element shall be removed from the underlying collection 129 /**
103 * when the iterator advances. 130 * Mutating iterator value type.
104 * Has no effect on iterators that are not based on a collection. 131 *
105 */ 132 * An iterator points to a certain element in an (possibly unbounded) chain of elements.
106 bool remove; 133 * Iterators that are based on collections (which have a defined "first" element), are supposed
134 * to be "position-aware", which means that they keep track of the current index within the collection.
135 *
136 * @note Objects that are pointed to by an iterator are mutable through that iterator. However, if the
137 * iterator is based on a collection and the underlying collection is mutated by other means than this iterator
138 * (e.g. elements added or removed), the iterator becomes invalid (regardless of what cxIteratorValid() returns)
139 * and MUST be re-obtained from the collection.
140 *
141 * @see CxIterator
142 */
143 typedef struct cx_mut_iterator_s CxMutIterator;
144
145 /**
146 * Internal iterator struct - use CxIterator.
147 */
148 struct cx_iterator_s {
149
150 /**
151 * The base properties of this iterator.
152 */
153 struct cx_iterator_base_s base;
154
155 /**
156 * Handle for the current element, if required.
157 */
158 void *elem_handle;
159
160 /**
161 * Handle for the source collection, if any.
162 */
163 void const *src_handle;
164
165 /**
166 * Field for storing a key-value pair.
167 * May be used by iterators that iterate over k/v-collections.
168 */
169 struct {
170 /**
171 * A pointer to the key.
172 */
173 void const *key;
174 /**
175 * A pointer to the value.
176 */
177 void *value;
178 } kv_data;
179
180 /**
181 * Field for storing a slot number.
182 * May be used by iterators that iterate over multi-bucket collections.
183 */
184 size_t slot;
185
186 /**
187 * If the iterator is position-aware, contains the index of the element in the underlying collection.
188 * Otherwise, this field is usually uninitialized.
189 */
190 size_t index;
107 }; 191 };
108 192
109 /** 193 /**
110 * Iterator value type. 194 * Iterator value type.
111 * An iterator points to a certain element in an (possibly unbounded) chain of elements. 195 * An iterator points to a certain element in an (possibly unbounded) chain of elements.
112 * Iterators that are based on collections (which have a defined "first" element), are supposed 196 * Iterators that are based on collections (which have a defined "first" element), are supposed
113 * to be "position-aware", which means that they keep track of the current index within the collection. 197 * to be "position-aware", which means that they keep track of the current index within the collection.
114 * 198 *
115 * @note Objects that are pointed to by an iterator are mutable through that iterator. However, if the 199 * @note Objects that are pointed to by an iterator are always mutable through that iterator. However,
116 * iterator is based on a collection and the underlying collection is mutated (elements added or removed), 200 * this iterator cannot mutate the collection itself (add or remove elements) and any mutation of the
117 * the iterator becomes invalid (regardless of what cxIteratorValid() returns) and MUST be re-obtained 201 * collection by other means make this iterator invalid (regardless of what cxIteratorValid() returns).
118 * from the collection. 202 *
203 * @see CxMutIterator
119 */ 204 */
120 typedef struct cx_iterator_s CxIterator; 205 typedef struct cx_iterator_s CxIterator;
121 206
122 /** 207 /**
123 * Checks if the iterator points to valid data. 208 * Checks if the iterator points to valid data.
124 * 209 *
125 * This is especially false for past-the-end iterators. 210 * This is especially false for past-the-end iterators.
126 * 211 *
127 * @param iter a pointer to the iterator 212 * @param iter the iterator
128 * @return true iff the iterator points to valid data 213 * @return true iff the iterator points to valid data
129 */ 214 */
130 __attribute__ ((__nonnull__)) 215 #define cxIteratorValid(iter) (iter).base.valid(&(iter))
131 static inline bool cxIteratorValid(CxIterator const *iter) {
132 return iter->valid(iter);
133 }
134 216
135 /** 217 /**
136 * Returns a pointer to the current element. 218 * Returns a pointer to the current element.
137 * 219 *
138 * The behavior is undefined if this iterator is invalid. 220 * The behavior is undefined if this iterator is invalid.
139 * 221 *
140 * @param iter a pointer to the iterator 222 * @param iter the iterator
141 * @return a pointer to the current element 223 * @return a pointer to the current element
142 */ 224 */
143 __attribute__ ((__nonnull__)) 225 #define cxIteratorCurrent(iter) (iter).base.current(&iter)
144 static inline void *cxIteratorCurrent(CxIterator const *iter) {
145 return iter->current(iter);
146 }
147 226
148 /** 227 /**
149 * Advances the iterator to the next element. 228 * Advances the iterator to the next element.
150 * 229 *
151 * @param iter a pointer to the iterator 230 * @param iter the iterator
152 */ 231 */
153 __attribute__ ((__nonnull__)) 232 #define cxIteratorNext(iter) (iter).base.next(&iter)
154 static inline void cxIteratorNext(CxIterator *iter) { 233
155 iter->next(iter); 234 /**
156 } 235 * Flags the current element for removal.
236 *
237 * @param iter the iterator
238 * @return false if this iterator cannot remove the element
239 */
240 #define cxIteratorFlagRemoval(iter) (iter).base.flag_removal(&iter)
157 241
158 /** 242 /**
159 * Loops over an iterator. 243 * Loops over an iterator.
160 * @param type the type of the elements 244 * @param type the type of the elements
161 * @param elem the name of the iteration variable 245 * @param elem the name of the iteration variable
162 * @param iter the iterator 246 * @param iter the iterator
163 */ 247 */
164 #define cx_foreach(type, elem, iter) \ 248 #define cx_foreach(type, elem, iter) \
165 for (type elem; cxIteratorValid(&iter) && (elem = (type)cxIteratorCurrent(&iter)) != NULL ; cxIteratorNext(&iter)) // NOLINT(bugprone-macro-parentheses) 249 for (type elem; cxIteratorValid(iter) && (elem = (type)cxIteratorCurrent(iter)) != NULL ; cxIteratorNext(iter))
166 250
167 #endif // UCX_ITERATOR_H 251 #endif // UCX_ITERATOR_H

mercurial