docs/Writerside/topics/iterator.h.md

changeset 1613
75a8c63db7c7
parent 1607
0ecb13118cac
equal deleted inserted replaced
1612:db1f645d2378 1613:75a8c63db7c7
6 Creating an iterator is as simple as creating a `CxIterator` struct and setting the fields in a meaningful way. 6 Creating an iterator is as simple as creating a `CxIterator` struct and setting the fields in a meaningful way.
7 The UCX collections provide various functions to create such iterators. 7 The UCX collections provide various functions to create such iterators.
8 8
9 If the predefined fields are not enough (or introduce too much bloat) for your use case, 9 If the predefined fields are not enough (or introduce too much bloat) for your use case,
10 you can alternatively create your own iterator structure 10 you can alternatively create your own iterator structure
11 and place the `CX_ITERATOR_BASE` macro as first member of that structure. 11 and place the `CX_ITERATOR_BASE` macro as the first member of that structure.
12 12
13 ```C 13 ```C
14 #include <cx/iterator.h> 14 #include <cx/iterator.h>
15 15
16 struct my_fancy_iterator_s { 16 struct my_fancy_iterator_s {
34 ``` 34 ```
35 35
36 The `cxIterator()` function creates an iterator over the elements of `array` where 36 The `cxIterator()` function creates an iterator over the elements of `array` where
37 each element is `elem_size` bytes large and the array contains a total of `elem_count` elements. 37 each element is `elem_size` bytes large and the array contains a total of `elem_count` elements.
38 38
39 The `cxIteratorPtr()` on the other hand assumes `sizeof(void*)` as the `elem_size` and automatically dereferences the pointers to the array elements. 39 The `cxIteratorPtr()`, on the other hand, assumes `sizeof(void*)` as the `elem_size` and automatically dereferences the pointers to the array elements.
40 That means, values returned by the iterator created with `cxIteratorPtr()` are the pointers stored in the array, 40 That means, values returned by the iterator created with `cxIteratorPtr()` are the pointers stored in the array,
41 while iterators created `cxIterator()` yield the pointers to the elements in the array. 41 while iterators created `cxIterator()` yield the pointers to the elements in the array.
42 42
43 Iterators created with the above functions are not allowed to remove elements because they are unable to update the size of the array they are iterating over. 43 Iterators created with the above functions are not allowed to remove elements because they are unable to update the size of the array they are iterating over.
44 44
86 ## Removing Elements via Iterators 86 ## Removing Elements via Iterators
87 87
88 Usually an iterator is not mutating the collection it is iterating over. 88 Usually an iterator is not mutating the collection it is iterating over.
89 But sometimes it is desirable to remove an element from the collection while iterating over it. 89 But sometimes it is desirable to remove an element from the collection while iterating over it.
90 90
91 For this purpose, most collections allow to use `cxIteratorFlagRemoval()`, which instructs the iterator to remove 91 For this purpose, most collections allow using `cxIteratorFlagRemoval()`, which instructs the iterator to remove
92 the current element from the collection on the next call to `cxIteratorNext()`. 92 the current element from the collection on the next call to `cxIteratorNext()`.
93 If you are implementing your own iterator, it is up to you to implement this behavior. 93 If you are implementing your own iterator, it is up to you to implement this behavior.
94 94
95 ## Passing Iterators to Functions 95 ## Passing Iterators to Functions
96 96
97 To eliminate the need of memory management for iterators, the structures are usually used by value. 97 To eliminate the need of memory management for iterators, the structures are usually passed by value.
98 This does not come with additional costs because iteration is implemented entirely by using macros.
99
100 However, sometimes it is necessary to pass an iterator to another function. 98 However, sometimes it is necessary to pass an iterator to another function.
99
101 To make that possible in a generalized way, such functions should accept a `CxIteratorBase*` pointer 100 To make that possible in a generalized way, such functions should accept a `CxIteratorBase*` pointer
102 which can be obtained with the `cxIteratorRef()` macro on the calling site. 101 which can be obtained with the `cxIteratorRef()` macro on the calling site.
103 102
104 In the following example, elements from a list are inserted into a tree: 103 In the following example, elements from a list are inserted into a tree:
105 104
109 108
110 CxIterator iter = cxListIterator(list); 109 CxIterator iter = cxListIterator(list);
111 cxTreeInsertIter(tree, cxIteratorRef(iter), cxListSize(list)); 110 cxTreeInsertIter(tree, cxIteratorRef(iter), cxListSize(list));
112 ``` 111 ```
113 112
114 > This is the reason, why `CX_ITERATOR_BASE` must be the first member of any iterator structure. 113 > This is the reason why `CX_ITERATOR_BASE` must be the first member of any iterator structure.
115 > Otherwise, the address taken by `cxIteratorRef()` would not equal the address of the iterator. 114 > Otherwise, the address taken by `cxIteratorRef()` would not equal the address of the iterator.
116 {style="note"} 115 {style="note"}
117 116
118 ## Custom Iterators 117 ## Custom Iterators
119 118
192 191
193 return iter; 192 return iter;
194 } 193 }
195 ``` 194 ```
196 195
197 > Note, that the behavior of `current` is undefined when `valid` returns `false`. 196 > Note that the behavior of `current` is undefined when `valid` returns `false`.
198 > That means, on the one hand, `current` does not need to check for validity of the iterator, 197 > That means, on the one hand, `current` does not need to check for validity of the iterator,
199 > but on the other hand, it is forbidden to invoke `current` when `valid` would return `false`. 198 > but on the other hand, it is forbidden to invoke `current` when `valid` would return `false`.
200 {style="note"} 199 {style="note"}
201 200
202 > If performance matters in your application, it is recommended that you indeed create specialized iterators 201 > If performance matters in your application, it is recommended that you indeed create specialized iterators

mercurial