docs/Writerside/topics/iterator.h.md

changeset 1429
6e0c3a8a914a
parent 1424
563033aa998c
equal deleted inserted replaced
1428:0ac4aa1737fd 1429:6e0c3a8a914a
25 25
26 ```C 26 ```C
27 #include <cx/iterator.h> 27 #include <cx/iterator.h>
28 28
29 CxIterator cxIterator(const void *array, 29 CxIterator cxIterator(const void *array,
30 size_t elem_size, size_t elem_count); 30 size_t elem_size, size_t elem_count,
31 31 bool remove_keeps_order);
32 CxIterator cxMutIterator(void *array, 32
33 size_t elem_size, size_t elem_count, bool remove_keeps_order); 33 CxIterator cxIteratorPtr(const void *array,
34 34 size_t elem_count,
35 CxIterator cxIteratorPtr(const void *array, size_t elem_count);
36
37 CxIterator cxMutIteratorPtr(void *array, size_t elem_count,
38 bool remove_keeps_order); 35 bool remove_keeps_order);
39 ``` 36 ```
40 37
41 The `cxIterator()` function creates an iterator over the elements of `array` where 38 The `cxIterator()` function creates an iterator over the elements of `array` where
42 each element is `elem_size` bytes large and the array contains a total of `elem_count` elements. 39 each element is `elem_size` bytes large and the array contains a total of `elem_count` elements.
43 The `cxMutIterator()` function creates an equivalent [mutating iterator](#mutating-iterators). 40
44 41 The `cxIteratorPtr()` function is equivalent to `cxIterator()`, except it assumes `sizeof(void*)` as the `elem_size`.
45 The `cxIteratorPtr()` and `cxMutIteratorPtr()` functions are equivalent to
46 the `cxIteratorPtr()` and `cxMutIteratorPtr()`, except they assume `sizeof(void*)` as the `elem_size`.
47 42
48 The UCX collections also define functions for creating iterators over their items. 43 The UCX collections also define functions for creating iterators over their items.
49 You can read more about them in the respective Sections of the documentation. 44 You can read more about them in the respective Sections of the documentation.
50 45
51 ## Using an Iterator 46 ## Using an Iterator
84 > but they can also iterate over just the values or just the keys. 79 > but they can also iterate over just the values or just the keys.
85 > 80 >
86 > You should read the documentation of the function creating the iterator to learn 81 > You should read the documentation of the function creating the iterator to learn
87 > what exactly the iterator is iterating over. 82 > what exactly the iterator is iterating over.
88 83
89 ## Mutating Iterators 84 ## Removing Elements via Iterators
90 85
91 Usually an iterator is not mutating the collection it is iterating over. 86 Usually an iterator is not mutating the collection it is iterating over.
92 But sometimes it is desirable to remove an element from the collection while iterating over it. 87 But sometimes it is desirable to remove an element from the collection while iterating over it.
93 88
94 For this purpose, most collections allow the creation of a _mutating_ iterator. 89 For this purpose, most collections allow to use `cxIteratorFlagRemoval()`, which instructs the iterator to remove
95 On mutating iterators the `mutating` flag in the base structure is set to `true`, 90 the current element from the collection on the next call to `cxIteratorNext()`.
96 and it is allowed to call the `cxFlagForRemoval()` function, which instructs the iterator to remove
97 the current element from the collection on the next call to `cxIteratorNext()` and clear the flag afterward.
98 If you are implementing your own iterator, it is up to you to implement this behavior. 91 If you are implementing your own iterator, it is up to you to implement this behavior.
99 92
100 ## Passing Iterators to Functions 93 ## Passing Iterators to Functions
101 94
102 To eliminate the need of memory management for iterators, the structures are usually used by value. 95 To eliminate the need of memory management for iterators, the structures are usually used by value.
125 The base structure is defined as follows: 118 The base structure is defined as follows:
126 ```C 119 ```C
127 struct cx_iterator_base_s { 120 struct cx_iterator_base_s {
128 bool (*valid)(const void *); 121 bool (*valid)(const void *);
129 void *(*current)(const void *); 122 void *(*current)(const void *);
123 void (*next)(void *);
130 void *(*current_impl)(const void *); 124 void *(*current_impl)(const void *);
131 void (*next)(void *); 125 void (*next_impl)(void *);
132 bool mutating; 126 bool allow_remove;
133 bool remove; 127 bool remove;
134 }; 128 };
135 129
136 typedef struct cx_iterator_base_s CxIteratorBase; 130 typedef struct cx_iterator_base_s CxIteratorBase;
137 ``` 131 ```
138 132
139 The `valid` function indicates whether the iterator is currently pointing to an element in the collection. 133 The `valid` function indicates whether the iterator is currently pointing to an element in the collection.
140 The `current` function is supposed to return that element, 134 The `current` function is supposed to return that element,
141 and the `next` function shall advance the iterator to the next element. 135 and the `next` function shall advance the iterator to the next element.
142 The booleans `mutating` and `remove` are used for [mutating iterators](#mutating-iterators) as explained above. 136
143 137 The booleans `allow_remove` and `remove` are used for [removing elements](#removing-elements-via-iterators) as explained above.
144 Iterators may be wrapped in which case the original implementation can be stored in `current_impl` and 138 When an iterator is created, the `allow_remove` field is set to indicate if removal of elements is supported.
145 called by a wrapper implementation pointed to by `current`. 139 The `remove` field is set to indicate if the current element should be removed on the next call to `next()` (see `cxIteratorFlagRemoval()`).
140
141 Iterators may be wrapped in which case the original implementation can be stored in `current_impl` and `next_impl`.
142 They can then be called by a wrapper implementation pointed to by `current` and `next`, respectively.
146 This can be useful when you want to support the `store_pointer` field of the [](collection.h.md) API. 143 This can be useful when you want to support the `store_pointer` field of the [](collection.h.md) API.
147 144
148 A specialized, simple, and fast iterator over an array of a certain type 145 A specialized, simple, and fast iterator over an array of a certain type
149 that does not support mutation can be implemented as follows: 146 that does not support removing elements can be implemented as follows:
150 ```C 147 ```C
151 #include <cx/iterator.h> 148 #include <cx/iterator.h>
152 149
153 typedef struct my_foo_s { 150 typedef struct my_foo_s {
154 // ... your data ... 151 // ... your data ...
182 // base fields 179 // base fields
183 iter.base.valid = my_foo_iter_valid; 180 iter.base.valid = my_foo_iter_valid;
184 iter.base.current = my_foo_iter_current; 181 iter.base.current = my_foo_iter_current;
185 iter.base.next = my_foo_iter_next; 182 iter.base.next = my_foo_iter_next;
186 iter.base.remove = false; 183 iter.base.remove = false;
187 iter.base.mutating = false; 184 iter.base.allow_remove = false;
188 185
189 // custom fields 186 // custom fields
190 iter.index = 0; 187 iter.index = 0;
191 iter.elem_count = elem_count; 188 iter.elem_count = elem_count;
192 189

mercurial