| 36 #ifndef UCX_ITERATOR_H |
36 #ifndef UCX_ITERATOR_H |
| 37 #define UCX_ITERATOR_H |
37 #define UCX_ITERATOR_H |
| 38 |
38 |
| 39 #include "common.h" |
39 #include "common.h" |
| 40 |
40 |
| |
41 #ifdef __cplusplus |
| |
42 extern "C" { |
| |
43 #endif |
| |
44 |
| |
45 /** |
| |
46 * Common data for all iterators. |
| |
47 */ |
| 41 struct cx_iterator_base_s { |
48 struct cx_iterator_base_s { |
| 42 /** |
49 /** |
| 43 * True iff the iterator points to valid data. |
50 * True iff the iterator points to valid data. |
| 44 */ |
51 */ |
| 45 __attribute__ ((__nonnull__)) |
52 cx_attr_nonnull |
| 46 bool (*valid)(void const *); |
53 bool (*valid)(const void *); |
| 47 |
54 |
| 48 /** |
55 /** |
| 49 * Returns a pointer to the current element. |
56 * Returns a pointer to the current element. |
| 50 * |
57 * |
| 51 * When valid returns false, the behavior of this function is undefined. |
58 * When valid returns false, the behavior of this function is undefined. |
| 52 */ |
59 */ |
| 53 __attribute__ ((__nonnull__)) |
60 cx_attr_nonnull |
| 54 void *(*current)(void const *); |
61 cx_attr_nodiscard |
| |
62 void *(*current)(const void *); |
| 55 |
63 |
| 56 /** |
64 /** |
| 57 * Original implementation in case the function needs to be wrapped. |
65 * Original implementation in case the function needs to be wrapped. |
| 58 */ |
66 */ |
| 59 __attribute__ ((__nonnull__)) |
67 cx_attr_nonnull |
| 60 void *(*current_impl)(void const *); |
68 cx_attr_nodiscard |
| |
69 void *(*current_impl)(const void *); |
| 61 |
70 |
| 62 /** |
71 /** |
| 63 * Advances the iterator. |
72 * Advances the iterator. |
| 64 * |
73 * |
| 65 * When valid returns false, the behavior of this function is undefined. |
74 * When valid returns false, the behavior of this function is undefined. |
| 66 */ |
75 */ |
| 67 __attribute__ ((__nonnull__)) |
76 cx_attr_nonnull |
| 68 void (*next)(void *); |
77 void (*next)(void *); |
| 69 /** |
78 /** |
| 70 * Indicates whether this iterator may remove elements. |
79 * Indicates whether this iterator may remove elements. |
| 71 */ |
80 */ |
| 72 bool mutating; |
81 bool mutating; |
| 76 bool remove; |
85 bool remove; |
| 77 }; |
86 }; |
| 78 |
87 |
| 79 /** |
88 /** |
| 80 * Declares base attributes for an iterator. |
89 * Declares base attributes for an iterator. |
| |
90 * Must be the first member of an iterator structure. |
| 81 */ |
91 */ |
| 82 #define CX_ITERATOR_BASE struct cx_iterator_base_s base |
92 #define CX_ITERATOR_BASE struct cx_iterator_base_s base |
| 83 |
93 |
| 84 /** |
94 /** |
| 85 * Internal iterator struct - use CxIterator. |
95 * Internal iterator struct - use CxIterator. |
| 86 */ |
96 */ |
| 87 struct cx_iterator_s { |
97 struct cx_iterator_s { |
| |
98 /** |
| |
99 * Inherited common data for all iterators. |
| |
100 */ |
| 88 CX_ITERATOR_BASE; |
101 CX_ITERATOR_BASE; |
| 89 |
102 |
| 90 /** |
103 /** |
| 91 * Handle for the current element. |
104 * Handle for the current element. |
| 92 */ |
105 */ |
| 191 * @param iter the iterator |
204 * @param iter the iterator |
| 192 */ |
205 */ |
| 193 #define cxIteratorFlagRemoval(iter) (iter).base.remove |= (iter).base.mutating |
206 #define cxIteratorFlagRemoval(iter) (iter).base.remove |= (iter).base.mutating |
| 194 |
207 |
| 195 /** |
208 /** |
| |
209 * Obtains a reference to an arbitrary iterator. |
| |
210 * |
| |
211 * This is useful for APIs that expect some iterator as an argument. |
| |
212 * |
| |
213 * @param iter the iterator |
| |
214 */ |
| |
215 #define cxIteratorRef(iter) &((iter).base) |
| |
216 |
| |
217 /** |
| 196 * Loops over an iterator. |
218 * Loops over an iterator. |
| 197 * @param type the type of the elements |
219 * @param type the type of the elements |
| 198 * @param elem the name of the iteration variable |
220 * @param elem the name of the iteration variable |
| 199 * @param iter the iterator |
221 * @param iter the iterator |
| 200 */ |
222 */ |
| 206 * Creates an iterator for the specified plain array. |
228 * Creates an iterator for the specified plain array. |
| 207 * |
229 * |
| 208 * The \p array can be \c NULL in which case the iterator will be immediately |
230 * The \p array can be \c NULL in which case the iterator will be immediately |
| 209 * initialized such that #cxIteratorValid() returns \c false. |
231 * initialized such that #cxIteratorValid() returns \c false. |
| 210 * |
232 * |
| |
233 * This iterator yields the addresses of the array elements. |
| |
234 * If you want to iterator over an array of pointers, you can |
| |
235 * use cxIteratorPtr() to create an iterator which directly |
| |
236 * yields the stored pointers. |
| 211 * |
237 * |
| 212 * @param array a pointer to the array (can be \c NULL) |
238 * @param array a pointer to the array (can be \c NULL) |
| 213 * @param elem_size the size of one array element |
239 * @param elem_size the size of one array element |
| 214 * @param elem_count the number of elements in the array |
240 * @param elem_count the number of elements in the array |
| 215 * @return an iterator for the specified array |
241 * @return an iterator for the specified array |
| 216 */ |
242 * @see cxIteratorPtr() |
| 217 __attribute__((__warn_unused_result__)) |
243 */ |
| |
244 cx_attr_nodiscard |
| 218 CxIterator cxIterator( |
245 CxIterator cxIterator( |
| 219 void const *array, |
246 const void *array, |
| 220 size_t elem_size, |
247 size_t elem_size, |
| 221 size_t elem_count |
248 size_t elem_count |
| 222 ); |
249 ); |
| 223 |
250 |
| 224 /** |
251 /** |
| 242 * @param elem_count the number of elements in the array |
269 * @param elem_count the number of elements in the array |
| 243 * @param remove_keeps_order \c true if the order of elements must be preserved |
270 * @param remove_keeps_order \c true if the order of elements must be preserved |
| 244 * when removing an element |
271 * when removing an element |
| 245 * @return an iterator for the specified array |
272 * @return an iterator for the specified array |
| 246 */ |
273 */ |
| 247 __attribute__((__warn_unused_result__)) |
274 cx_attr_nodiscard |
| 248 CxIterator cxMutIterator( |
275 CxIterator cxMutIterator( |
| 249 void *array, |
276 void *array, |
| 250 size_t elem_size, |
277 size_t elem_size, |
| 251 size_t elem_count, |
278 size_t elem_count, |
| 252 bool remove_keeps_order |
279 bool remove_keeps_order |
| 253 ); |
280 ); |
| 254 |
281 |
| |
282 /** |
| |
283 * Creates an iterator for the specified plain pointer array. |
| |
284 * |
| |
285 * This iterator assumes that every element in the array is a pointer |
| |
286 * and yields exactly those pointers during iteration (while in contrast |
| |
287 * an iterator created with cxIterator() would return the addresses |
| |
288 * of those pointers within the array). |
| |
289 * |
| |
290 * @param array a pointer to the array (can be \c NULL) |
| |
291 * @param elem_count the number of elements in the array |
| |
292 * @return an iterator for the specified array |
| |
293 * @see cxIterator() |
| |
294 */ |
| |
295 cx_attr_nodiscard |
| |
296 CxIterator cxIteratorPtr( |
| |
297 const void *array, |
| |
298 size_t elem_count |
| |
299 ); |
| |
300 |
| |
301 /** |
| |
302 * Creates a mutating iterator for the specified plain pointer array. |
| |
303 * |
| |
304 * This is the mutating variant of cxIteratorPtr(). See also |
| |
305 * cxMutIterator(). |
| |
306 * |
| |
307 * @param array a pointer to the array (can be \c NULL) |
| |
308 * @param elem_count the number of elements in the array |
| |
309 * @param remove_keeps_order \c true if the order of elements must be preserved |
| |
310 * when removing an element |
| |
311 * @return an iterator for the specified array |
| |
312 * @see cxMutIterator() |
| |
313 * @see cxIteratorPtr() |
| |
314 */ |
| |
315 cx_attr_nodiscard |
| |
316 CxIterator cxMutIteratorPtr( |
| |
317 void *array, |
| |
318 size_t elem_count, |
| |
319 bool remove_keeps_order |
| |
320 ); |
| |
321 |
| |
322 #ifdef __cplusplus |
| |
323 } // extern "C" |
| |
324 #endif |
| |
325 |
| 255 #endif // UCX_ITERATOR_H |
326 #endif // UCX_ITERATOR_H |