Sun, 23 Nov 2025 13:15:19 +0100
optimize sorted insertion by using the infimum instead of the supremum
The reason is that the supremum returns the equal element with the smallest index, and we want the largest.
Therefore, we use the infimum, which already gives us the largest index when there are equal elements, and increase the index by one. The infimum is also guaranteed to exist in that case.
|
1143
0559812df10c
assign proper names to the documentation topics
Mike Becker <universe@uap-core.de>
parents:
1142
diff
changeset
|
1 | # Iterators |
| 1141 | 2 | |
|
1215
790ff923f375
add iterator documentation
Mike Becker <universe@uap-core.de>
parents:
1190
diff
changeset
|
3 | Iterators generalize the iteration over elements of an arbitrary collection. |
|
790ff923f375
add iterator documentation
Mike Becker <universe@uap-core.de>
parents:
1190
diff
changeset
|
4 | This allows iteration over arrays, lists, maps, trees, etc. in a unified way. |
|
1146
151c057faf7c
add marker to every incomplete page
Mike Becker <universe@uap-core.de>
parents:
1143
diff
changeset
|
5 | |
|
1215
790ff923f375
add iterator documentation
Mike Becker <universe@uap-core.de>
parents:
1190
diff
changeset
|
6 | Creating an iterator is as simple as creating a `CxIterator` struct and setting the fields in a meaningful way. |
|
790ff923f375
add iterator documentation
Mike Becker <universe@uap-core.de>
parents:
1190
diff
changeset
|
7 | The UCX collections provide various functions to create such iterators. |
| 1141 | 8 | |
|
1424
563033aa998c
fixes tons of typos and grammar issues across the documentation - fixes #667
Mike Becker <universe@uap-core.de>
parents:
1245
diff
changeset
|
9 | If the predefined fields are not enough (or introduce too much bloat) for your use case, |
|
1215
790ff923f375
add iterator documentation
Mike Becker <universe@uap-core.de>
parents:
1190
diff
changeset
|
10 | you can alternatively create your own iterator structure |
| 1141 | 11 | and place the `CX_ITERATOR_BASE` macro as first member of that structure. |
| 12 | ||
|
1215
790ff923f375
add iterator documentation
Mike Becker <universe@uap-core.de>
parents:
1190
diff
changeset
|
13 | ```C |
|
790ff923f375
add iterator documentation
Mike Becker <universe@uap-core.de>
parents:
1190
diff
changeset
|
14 | #include <cx/iterator.h> |
|
790ff923f375
add iterator documentation
Mike Becker <universe@uap-core.de>
parents:
1190
diff
changeset
|
15 | |
|
790ff923f375
add iterator documentation
Mike Becker <universe@uap-core.de>
parents:
1190
diff
changeset
|
16 | struct my_fancy_iterator_s { |
|
790ff923f375
add iterator documentation
Mike Becker <universe@uap-core.de>
parents:
1190
diff
changeset
|
17 | CX_ITERATOR_BASE; // the base members used by cx_foreach() |
|
790ff923f375
add iterator documentation
Mike Becker <universe@uap-core.de>
parents:
1190
diff
changeset
|
18 | // ... custom fields ... |
|
790ff923f375
add iterator documentation
Mike Becker <universe@uap-core.de>
parents:
1190
diff
changeset
|
19 | }; |
|
790ff923f375
add iterator documentation
Mike Becker <universe@uap-core.de>
parents:
1190
diff
changeset
|
20 | ``` |
|
790ff923f375
add iterator documentation
Mike Becker <universe@uap-core.de>
parents:
1190
diff
changeset
|
21 | |
|
1216
151c1b7d5d50
add missing documentation about creating iterators
Mike Becker <universe@uap-core.de>
parents:
1215
diff
changeset
|
22 | ## Creating an Iterator |
|
151c1b7d5d50
add missing documentation about creating iterators
Mike Becker <universe@uap-core.de>
parents:
1215
diff
changeset
|
23 | |
|
1245
721e2032fa25
define structure for array_list.h documentation
Mike Becker <universe@uap-core.de>
parents:
1216
diff
changeset
|
24 | The following functions create iterators over plain C arrays. |
|
1216
151c1b7d5d50
add missing documentation about creating iterators
Mike Becker <universe@uap-core.de>
parents:
1215
diff
changeset
|
25 | |
|
151c1b7d5d50
add missing documentation about creating iterators
Mike Becker <universe@uap-core.de>
parents:
1215
diff
changeset
|
26 | ```C |
|
151c1b7d5d50
add missing documentation about creating iterators
Mike Becker <universe@uap-core.de>
parents:
1215
diff
changeset
|
27 | #include <cx/iterator.h> |
|
1215
790ff923f375
add iterator documentation
Mike Becker <universe@uap-core.de>
parents:
1190
diff
changeset
|
28 | |
|
1216
151c1b7d5d50
add missing documentation about creating iterators
Mike Becker <universe@uap-core.de>
parents:
1215
diff
changeset
|
29 | CxIterator cxIterator(const void *array, |
|
1429
6e0c3a8a914a
remove the concept of "mutating iterators" - resolves #579
Mike Becker <universe@uap-core.de>
parents:
1424
diff
changeset
|
30 | size_t elem_size, size_t elem_count, |
|
6e0c3a8a914a
remove the concept of "mutating iterators" - resolves #579
Mike Becker <universe@uap-core.de>
parents:
1424
diff
changeset
|
31 | bool remove_keeps_order); |
|
6e0c3a8a914a
remove the concept of "mutating iterators" - resolves #579
Mike Becker <universe@uap-core.de>
parents:
1424
diff
changeset
|
32 | |
|
6e0c3a8a914a
remove the concept of "mutating iterators" - resolves #579
Mike Becker <universe@uap-core.de>
parents:
1424
diff
changeset
|
33 | CxIterator cxIteratorPtr(const void *array, |
|
6e0c3a8a914a
remove the concept of "mutating iterators" - resolves #579
Mike Becker <universe@uap-core.de>
parents:
1424
diff
changeset
|
34 | size_t elem_count, |
|
1216
151c1b7d5d50
add missing documentation about creating iterators
Mike Becker <universe@uap-core.de>
parents:
1215
diff
changeset
|
35 | bool remove_keeps_order); |
|
151c1b7d5d50
add missing documentation about creating iterators
Mike Becker <universe@uap-core.de>
parents:
1215
diff
changeset
|
36 | ``` |
|
1215
790ff923f375
add iterator documentation
Mike Becker <universe@uap-core.de>
parents:
1190
diff
changeset
|
37 | |
|
1216
151c1b7d5d50
add missing documentation about creating iterators
Mike Becker <universe@uap-core.de>
parents:
1215
diff
changeset
|
38 | The `cxIterator()` function creates an iterator over the elements of `array` where |
|
151c1b7d5d50
add missing documentation about creating iterators
Mike Becker <universe@uap-core.de>
parents:
1215
diff
changeset
|
39 | each element is `elem_size` bytes large and the array contains a total of `elem_count` elements. |
|
151c1b7d5d50
add missing documentation about creating iterators
Mike Becker <universe@uap-core.de>
parents:
1215
diff
changeset
|
40 | |
|
1429
6e0c3a8a914a
remove the concept of "mutating iterators" - resolves #579
Mike Becker <universe@uap-core.de>
parents:
1424
diff
changeset
|
41 | The `cxIteratorPtr()` function is equivalent to `cxIterator()`, except it assumes `sizeof(void*)` as the `elem_size`. |
|
1216
151c1b7d5d50
add missing documentation about creating iterators
Mike Becker <universe@uap-core.de>
parents:
1215
diff
changeset
|
42 | |
|
151c1b7d5d50
add missing documentation about creating iterators
Mike Becker <universe@uap-core.de>
parents:
1215
diff
changeset
|
43 | The UCX collections also define functions for creating iterators over their items. |
|
151c1b7d5d50
add missing documentation about creating iterators
Mike Becker <universe@uap-core.de>
parents:
1215
diff
changeset
|
44 | You can read more about them in the respective Sections of the documentation. |
|
1215
790ff923f375
add iterator documentation
Mike Becker <universe@uap-core.de>
parents:
1190
diff
changeset
|
45 | |
|
790ff923f375
add iterator documentation
Mike Becker <universe@uap-core.de>
parents:
1190
diff
changeset
|
46 | ## Using an Iterator |
|
790ff923f375
add iterator documentation
Mike Becker <universe@uap-core.de>
parents:
1190
diff
changeset
|
47 | |
|
790ff923f375
add iterator documentation
Mike Becker <universe@uap-core.de>
parents:
1190
diff
changeset
|
48 | The following macros work with arbitrary structures using `CX_ITERATOR_BASE` |
|
790ff923f375
add iterator documentation
Mike Becker <universe@uap-core.de>
parents:
1190
diff
changeset
|
49 | and invoke the respective function pointers `valid`, `current`, or `next`. |
|
790ff923f375
add iterator documentation
Mike Becker <universe@uap-core.de>
parents:
1190
diff
changeset
|
50 | ```C |
|
790ff923f375
add iterator documentation
Mike Becker <universe@uap-core.de>
parents:
1190
diff
changeset
|
51 | cxIteratorValid(iter) |
|
790ff923f375
add iterator documentation
Mike Becker <universe@uap-core.de>
parents:
1190
diff
changeset
|
52 | cxIteratorCurrent(iter) |
|
790ff923f375
add iterator documentation
Mike Becker <universe@uap-core.de>
parents:
1190
diff
changeset
|
53 | cxIteratorNext(iter) |
|
790ff923f375
add iterator documentation
Mike Becker <universe@uap-core.de>
parents:
1190
diff
changeset
|
54 | ``` |
|
790ff923f375
add iterator documentation
Mike Becker <universe@uap-core.de>
parents:
1190
diff
changeset
|
55 | |
|
790ff923f375
add iterator documentation
Mike Becker <universe@uap-core.de>
parents:
1190
diff
changeset
|
56 | You may use them for manual iterator, but usually you do not need them. |
|
790ff923f375
add iterator documentation
Mike Becker <universe@uap-core.de>
parents:
1190
diff
changeset
|
57 | Every iterator can be used with the `cx_foreach` macro. |
|
790ff923f375
add iterator documentation
Mike Becker <universe@uap-core.de>
parents:
1190
diff
changeset
|
58 | |
|
790ff923f375
add iterator documentation
Mike Becker <universe@uap-core.de>
parents:
1190
diff
changeset
|
59 | ```C |
|
790ff923f375
add iterator documentation
Mike Becker <universe@uap-core.de>
parents:
1190
diff
changeset
|
60 | #include <cx/iterator.h> |
|
790ff923f375
add iterator documentation
Mike Becker <universe@uap-core.de>
parents:
1190
diff
changeset
|
61 | |
|
790ff923f375
add iterator documentation
Mike Becker <universe@uap-core.de>
parents:
1190
diff
changeset
|
62 | // some custom array and its size |
|
790ff923f375
add iterator documentation
Mike Becker <universe@uap-core.de>
parents:
1190
diff
changeset
|
63 | MyData *array = // ... |
|
790ff923f375
add iterator documentation
Mike Becker <universe@uap-core.de>
parents:
1190
diff
changeset
|
64 | size_t size = // ... |
|
790ff923f375
add iterator documentation
Mike Becker <universe@uap-core.de>
parents:
1190
diff
changeset
|
65 | |
|
790ff923f375
add iterator documentation
Mike Becker <universe@uap-core.de>
parents:
1190
diff
changeset
|
66 | CxIterator iter = cxIterator(array, sizeof(MyData), size); |
|
790ff923f375
add iterator documentation
Mike Becker <universe@uap-core.de>
parents:
1190
diff
changeset
|
67 | cx_foreach(MyData*, elem, iter) { |
|
790ff923f375
add iterator documentation
Mike Becker <universe@uap-core.de>
parents:
1190
diff
changeset
|
68 | // .. do something with elem .. |
|
790ff923f375
add iterator documentation
Mike Becker <universe@uap-core.de>
parents:
1190
diff
changeset
|
69 | } |
|
790ff923f375
add iterator documentation
Mike Becker <universe@uap-core.de>
parents:
1190
diff
changeset
|
70 | ``` |
|
790ff923f375
add iterator documentation
Mike Becker <universe@uap-core.de>
parents:
1190
diff
changeset
|
71 | |
|
790ff923f375
add iterator documentation
Mike Becker <universe@uap-core.de>
parents:
1190
diff
changeset
|
72 | The macro takes three arguments: |
|
790ff923f375
add iterator documentation
Mike Becker <universe@uap-core.de>
parents:
1190
diff
changeset
|
73 | 1. the pointer-type of a pointer to an element, |
|
790ff923f375
add iterator documentation
Mike Becker <universe@uap-core.de>
parents:
1190
diff
changeset
|
74 | 2. the name of the variable you want to use for accessing the element, |
|
790ff923f375
add iterator documentation
Mike Becker <universe@uap-core.de>
parents:
1190
diff
changeset
|
75 | 3. and the iterator. |
|
790ff923f375
add iterator documentation
Mike Becker <universe@uap-core.de>
parents:
1190
diff
changeset
|
76 | |
|
1424
563033aa998c
fixes tons of typos and grammar issues across the documentation - fixes #667
Mike Becker <universe@uap-core.de>
parents:
1245
diff
changeset
|
77 | > An iterator does not necessarily need to iterate over the concrete elements of a collection. |
|
1215
790ff923f375
add iterator documentation
Mike Becker <universe@uap-core.de>
parents:
1190
diff
changeset
|
78 | > Map iterators, for example, can iterator over the key/value pairs, |
|
790ff923f375
add iterator documentation
Mike Becker <universe@uap-core.de>
parents:
1190
diff
changeset
|
79 | > but they can also iterate over just the values or just the keys. |
|
790ff923f375
add iterator documentation
Mike Becker <universe@uap-core.de>
parents:
1190
diff
changeset
|
80 | > |
|
790ff923f375
add iterator documentation
Mike Becker <universe@uap-core.de>
parents:
1190
diff
changeset
|
81 | > You should read the documentation of the function creating the iterator to learn |
|
790ff923f375
add iterator documentation
Mike Becker <universe@uap-core.de>
parents:
1190
diff
changeset
|
82 | > what exactly the iterator is iterating over. |
|
790ff923f375
add iterator documentation
Mike Becker <universe@uap-core.de>
parents:
1190
diff
changeset
|
83 | |
|
1429
6e0c3a8a914a
remove the concept of "mutating iterators" - resolves #579
Mike Becker <universe@uap-core.de>
parents:
1424
diff
changeset
|
84 | ## Removing Elements via Iterators |
|
1215
790ff923f375
add iterator documentation
Mike Becker <universe@uap-core.de>
parents:
1190
diff
changeset
|
85 | |
| 1141 | 86 | Usually an iterator is not mutating the collection it is iterating over. |
| 87 | But sometimes it is desirable to remove an element from the collection while iterating over it. | |
|
1215
790ff923f375
add iterator documentation
Mike Becker <universe@uap-core.de>
parents:
1190
diff
changeset
|
88 | |
|
1429
6e0c3a8a914a
remove the concept of "mutating iterators" - resolves #579
Mike Becker <universe@uap-core.de>
parents:
1424
diff
changeset
|
89 | For this purpose, most collections allow to use `cxIteratorFlagRemoval()`, which instructs the iterator to remove |
|
6e0c3a8a914a
remove the concept of "mutating iterators" - resolves #579
Mike Becker <universe@uap-core.de>
parents:
1424
diff
changeset
|
90 | the current element from the collection on the next call to `cxIteratorNext()`. |
| 1141 | 91 | If you are implementing your own iterator, it is up to you to implement this behavior. |
|
1142
9437530176bc
add symbols that need documentation as TODOs
Mike Becker <universe@uap-core.de>
parents:
1141
diff
changeset
|
92 | |
|
1215
790ff923f375
add iterator documentation
Mike Becker <universe@uap-core.de>
parents:
1190
diff
changeset
|
93 | ## Passing Iterators to Functions |
|
790ff923f375
add iterator documentation
Mike Becker <universe@uap-core.de>
parents:
1190
diff
changeset
|
94 | |
|
790ff923f375
add iterator documentation
Mike Becker <universe@uap-core.de>
parents:
1190
diff
changeset
|
95 | To eliminate the need of memory management for iterators, the structures are usually used by value. |
|
1424
563033aa998c
fixes tons of typos and grammar issues across the documentation - fixes #667
Mike Becker <universe@uap-core.de>
parents:
1245
diff
changeset
|
96 | This does not come with additional costs because iteration is implemented entirely by using macros. |
|
1215
790ff923f375
add iterator documentation
Mike Becker <universe@uap-core.de>
parents:
1190
diff
changeset
|
97 | |
|
790ff923f375
add iterator documentation
Mike Becker <universe@uap-core.de>
parents:
1190
diff
changeset
|
98 | However, sometimes it is necessary to pass an iterator to another function. |
|
790ff923f375
add iterator documentation
Mike Becker <universe@uap-core.de>
parents:
1190
diff
changeset
|
99 | To make that possible in a generalized way, such functions should accept a `CxIteratorBase*` pointer |
|
790ff923f375
add iterator documentation
Mike Becker <universe@uap-core.de>
parents:
1190
diff
changeset
|
100 | which can be obtained with the `cxIteratorRef()` macro on the calling site. |
|
790ff923f375
add iterator documentation
Mike Becker <universe@uap-core.de>
parents:
1190
diff
changeset
|
101 | |
|
790ff923f375
add iterator documentation
Mike Becker <universe@uap-core.de>
parents:
1190
diff
changeset
|
102 | In the following example, elements from a list are inserted into a tree: |
|
790ff923f375
add iterator documentation
Mike Becker <universe@uap-core.de>
parents:
1190
diff
changeset
|
103 | |
|
790ff923f375
add iterator documentation
Mike Becker <universe@uap-core.de>
parents:
1190
diff
changeset
|
104 | ```C |
|
790ff923f375
add iterator documentation
Mike Becker <universe@uap-core.de>
parents:
1190
diff
changeset
|
105 | CxList *list = // ... |
|
790ff923f375
add iterator documentation
Mike Becker <universe@uap-core.de>
parents:
1190
diff
changeset
|
106 | CxTree *tree = // ... |
|
790ff923f375
add iterator documentation
Mike Becker <universe@uap-core.de>
parents:
1190
diff
changeset
|
107 | |
|
790ff923f375
add iterator documentation
Mike Becker <universe@uap-core.de>
parents:
1190
diff
changeset
|
108 | CxIterator iter = cxListIterator(list); |
|
790ff923f375
add iterator documentation
Mike Becker <universe@uap-core.de>
parents:
1190
diff
changeset
|
109 | cxTreeInsertIter(tree, cxIteratorRef(iter), cxListSize(list)); |
|
790ff923f375
add iterator documentation
Mike Becker <universe@uap-core.de>
parents:
1190
diff
changeset
|
110 | ``` |
|
790ff923f375
add iterator documentation
Mike Becker <universe@uap-core.de>
parents:
1190
diff
changeset
|
111 | |
|
790ff923f375
add iterator documentation
Mike Becker <universe@uap-core.de>
parents:
1190
diff
changeset
|
112 | > This is the reason, why `CX_ITERATOR_BASE` must be the first member of any iterator structure. |
|
790ff923f375
add iterator documentation
Mike Becker <universe@uap-core.de>
parents:
1190
diff
changeset
|
113 | > Otherwise, the address taken by `cxIteratorRef()` would not equal the address of the iterator. |
|
790ff923f375
add iterator documentation
Mike Becker <universe@uap-core.de>
parents:
1190
diff
changeset
|
114 | {style="note"} |
|
790ff923f375
add iterator documentation
Mike Becker <universe@uap-core.de>
parents:
1190
diff
changeset
|
115 | |
|
790ff923f375
add iterator documentation
Mike Becker <universe@uap-core.de>
parents:
1190
diff
changeset
|
116 | ## Custom Iterators |
|
790ff923f375
add iterator documentation
Mike Becker <universe@uap-core.de>
parents:
1190
diff
changeset
|
117 | |
|
790ff923f375
add iterator documentation
Mike Becker <universe@uap-core.de>
parents:
1190
diff
changeset
|
118 | The base structure is defined as follows: |
|
790ff923f375
add iterator documentation
Mike Becker <universe@uap-core.de>
parents:
1190
diff
changeset
|
119 | ```C |
|
790ff923f375
add iterator documentation
Mike Becker <universe@uap-core.de>
parents:
1190
diff
changeset
|
120 | struct cx_iterator_base_s { |
|
790ff923f375
add iterator documentation
Mike Becker <universe@uap-core.de>
parents:
1190
diff
changeset
|
121 | bool (*valid)(const void *); |
|
1432
fb82e7a92258
add possibility to wrap valid function of an iterator (just for the sake of completeness)
Mike Becker <universe@uap-core.de>
parents:
1429
diff
changeset
|
122 | bool (*valid_impl)(const void *); |
|
1215
790ff923f375
add iterator documentation
Mike Becker <universe@uap-core.de>
parents:
1190
diff
changeset
|
123 | void *(*current)(const void *); |
|
1429
6e0c3a8a914a
remove the concept of "mutating iterators" - resolves #579
Mike Becker <universe@uap-core.de>
parents:
1424
diff
changeset
|
124 | void (*next)(void *); |
|
1215
790ff923f375
add iterator documentation
Mike Becker <universe@uap-core.de>
parents:
1190
diff
changeset
|
125 | void *(*current_impl)(const void *); |
|
1429
6e0c3a8a914a
remove the concept of "mutating iterators" - resolves #579
Mike Becker <universe@uap-core.de>
parents:
1424
diff
changeset
|
126 | void (*next_impl)(void *); |
|
6e0c3a8a914a
remove the concept of "mutating iterators" - resolves #579
Mike Becker <universe@uap-core.de>
parents:
1424
diff
changeset
|
127 | bool allow_remove; |
|
1215
790ff923f375
add iterator documentation
Mike Becker <universe@uap-core.de>
parents:
1190
diff
changeset
|
128 | bool remove; |
|
790ff923f375
add iterator documentation
Mike Becker <universe@uap-core.de>
parents:
1190
diff
changeset
|
129 | }; |
|
790ff923f375
add iterator documentation
Mike Becker <universe@uap-core.de>
parents:
1190
diff
changeset
|
130 | |
|
790ff923f375
add iterator documentation
Mike Becker <universe@uap-core.de>
parents:
1190
diff
changeset
|
131 | typedef struct cx_iterator_base_s CxIteratorBase; |
|
790ff923f375
add iterator documentation
Mike Becker <universe@uap-core.de>
parents:
1190
diff
changeset
|
132 | ``` |
|
790ff923f375
add iterator documentation
Mike Becker <universe@uap-core.de>
parents:
1190
diff
changeset
|
133 | |
|
790ff923f375
add iterator documentation
Mike Becker <universe@uap-core.de>
parents:
1190
diff
changeset
|
134 | The `valid` function indicates whether the iterator is currently pointing to an element in the collection. |
|
790ff923f375
add iterator documentation
Mike Becker <universe@uap-core.de>
parents:
1190
diff
changeset
|
135 | The `current` function is supposed to return that element, |
|
790ff923f375
add iterator documentation
Mike Becker <universe@uap-core.de>
parents:
1190
diff
changeset
|
136 | and the `next` function shall advance the iterator to the next element. |
|
790ff923f375
add iterator documentation
Mike Becker <universe@uap-core.de>
parents:
1190
diff
changeset
|
137 | |
|
1429
6e0c3a8a914a
remove the concept of "mutating iterators" - resolves #579
Mike Becker <universe@uap-core.de>
parents:
1424
diff
changeset
|
138 | The booleans `allow_remove` and `remove` are used for [removing elements](#removing-elements-via-iterators) as explained above. |
|
6e0c3a8a914a
remove the concept of "mutating iterators" - resolves #579
Mike Becker <universe@uap-core.de>
parents:
1424
diff
changeset
|
139 | When an iterator is created, the `allow_remove` field is set to indicate if removal of elements is supported. |
|
6e0c3a8a914a
remove the concept of "mutating iterators" - resolves #579
Mike Becker <universe@uap-core.de>
parents:
1424
diff
changeset
|
140 | The `remove` field is set to indicate if the current element should be removed on the next call to `next()` (see `cxIteratorFlagRemoval()`). |
|
6e0c3a8a914a
remove the concept of "mutating iterators" - resolves #579
Mike Becker <universe@uap-core.de>
parents:
1424
diff
changeset
|
141 | |
|
1432
fb82e7a92258
add possibility to wrap valid function of an iterator (just for the sake of completeness)
Mike Becker <universe@uap-core.de>
parents:
1429
diff
changeset
|
142 | Iterators may be wrapped in which case the original implementation can be stored in the `*_impl` function pointers. |
|
1429
6e0c3a8a914a
remove the concept of "mutating iterators" - resolves #579
Mike Becker <universe@uap-core.de>
parents:
1424
diff
changeset
|
143 | They can then be called by a wrapper implementation pointed to by `current` and `next`, respectively. |
|
1215
790ff923f375
add iterator documentation
Mike Becker <universe@uap-core.de>
parents:
1190
diff
changeset
|
144 | This can be useful when you want to support the `store_pointer` field of the [](collection.h.md) API. |
|
790ff923f375
add iterator documentation
Mike Becker <universe@uap-core.de>
parents:
1190
diff
changeset
|
145 | |
|
1424
563033aa998c
fixes tons of typos and grammar issues across the documentation - fixes #667
Mike Becker <universe@uap-core.de>
parents:
1245
diff
changeset
|
146 | A specialized, simple, and fast iterator over an array of a certain type |
|
1429
6e0c3a8a914a
remove the concept of "mutating iterators" - resolves #579
Mike Becker <universe@uap-core.de>
parents:
1424
diff
changeset
|
147 | that does not support removing elements can be implemented as follows: |
|
1215
790ff923f375
add iterator documentation
Mike Becker <universe@uap-core.de>
parents:
1190
diff
changeset
|
148 | ```C |
|
790ff923f375
add iterator documentation
Mike Becker <universe@uap-core.de>
parents:
1190
diff
changeset
|
149 | #include <cx/iterator.h> |
|
790ff923f375
add iterator documentation
Mike Becker <universe@uap-core.de>
parents:
1190
diff
changeset
|
150 | |
|
790ff923f375
add iterator documentation
Mike Becker <universe@uap-core.de>
parents:
1190
diff
changeset
|
151 | typedef struct my_foo_s { |
|
790ff923f375
add iterator documentation
Mike Becker <universe@uap-core.de>
parents:
1190
diff
changeset
|
152 | // ... your data ... |
|
790ff923f375
add iterator documentation
Mike Becker <universe@uap-core.de>
parents:
1190
diff
changeset
|
153 | } MyFoo; |
|
790ff923f375
add iterator documentation
Mike Becker <universe@uap-core.de>
parents:
1190
diff
changeset
|
154 | |
|
790ff923f375
add iterator documentation
Mike Becker <universe@uap-core.de>
parents:
1190
diff
changeset
|
155 | typedef struct my_foo_iterator_s { |
|
790ff923f375
add iterator documentation
Mike Becker <universe@uap-core.de>
parents:
1190
diff
changeset
|
156 | CX_ITERATOR_BASE; |
|
790ff923f375
add iterator documentation
Mike Becker <universe@uap-core.de>
parents:
1190
diff
changeset
|
157 | MyFoo *array; |
|
790ff923f375
add iterator documentation
Mike Becker <universe@uap-core.de>
parents:
1190
diff
changeset
|
158 | size_t index; |
|
790ff923f375
add iterator documentation
Mike Becker <universe@uap-core.de>
parents:
1190
diff
changeset
|
159 | size_t elem_count; |
|
790ff923f375
add iterator documentation
Mike Becker <universe@uap-core.de>
parents:
1190
diff
changeset
|
160 | } MyFooIterator; |
|
790ff923f375
add iterator documentation
Mike Becker <universe@uap-core.de>
parents:
1190
diff
changeset
|
161 | |
|
790ff923f375
add iterator documentation
Mike Becker <universe@uap-core.de>
parents:
1190
diff
changeset
|
162 | static bool my_foo_iter_valid(const void *it) { |
|
790ff923f375
add iterator documentation
Mike Becker <universe@uap-core.de>
parents:
1190
diff
changeset
|
163 | const MyFooIterator *iter = it; |
|
790ff923f375
add iterator documentation
Mike Becker <universe@uap-core.de>
parents:
1190
diff
changeset
|
164 | return iter->index < iter->elem_count; |
|
790ff923f375
add iterator documentation
Mike Becker <universe@uap-core.de>
parents:
1190
diff
changeset
|
165 | } |
|
790ff923f375
add iterator documentation
Mike Becker <universe@uap-core.de>
parents:
1190
diff
changeset
|
166 | |
|
790ff923f375
add iterator documentation
Mike Becker <universe@uap-core.de>
parents:
1190
diff
changeset
|
167 | static void *my_foo_iter_current(const void *it) { |
|
790ff923f375
add iterator documentation
Mike Becker <universe@uap-core.de>
parents:
1190
diff
changeset
|
168 | const MyFooIterator *iter = it; |
|
790ff923f375
add iterator documentation
Mike Becker <universe@uap-core.de>
parents:
1190
diff
changeset
|
169 | return &iter->array[iter->index]; |
|
790ff923f375
add iterator documentation
Mike Becker <universe@uap-core.de>
parents:
1190
diff
changeset
|
170 | } |
|
790ff923f375
add iterator documentation
Mike Becker <universe@uap-core.de>
parents:
1190
diff
changeset
|
171 | |
|
790ff923f375
add iterator documentation
Mike Becker <universe@uap-core.de>
parents:
1190
diff
changeset
|
172 | static void my_foo_iter_next(void *it) { |
|
790ff923f375
add iterator documentation
Mike Becker <universe@uap-core.de>
parents:
1190
diff
changeset
|
173 | MyFooIterator *iter = it; |
|
790ff923f375
add iterator documentation
Mike Becker <universe@uap-core.de>
parents:
1190
diff
changeset
|
174 | iter->index++; |
|
790ff923f375
add iterator documentation
Mike Becker <universe@uap-core.de>
parents:
1190
diff
changeset
|
175 | } |
|
790ff923f375
add iterator documentation
Mike Becker <universe@uap-core.de>
parents:
1190
diff
changeset
|
176 | |
|
790ff923f375
add iterator documentation
Mike Becker <universe@uap-core.de>
parents:
1190
diff
changeset
|
177 | MyFooIterator myFooIterator(MyFoo *array, size_t elem_count) { |
|
790ff923f375
add iterator documentation
Mike Becker <universe@uap-core.de>
parents:
1190
diff
changeset
|
178 | MyFooIterator iter; |
|
790ff923f375
add iterator documentation
Mike Becker <universe@uap-core.de>
parents:
1190
diff
changeset
|
179 | |
|
790ff923f375
add iterator documentation
Mike Becker <universe@uap-core.de>
parents:
1190
diff
changeset
|
180 | // base fields |
|
790ff923f375
add iterator documentation
Mike Becker <universe@uap-core.de>
parents:
1190
diff
changeset
|
181 | iter.base.valid = my_foo_iter_valid; |
|
790ff923f375
add iterator documentation
Mike Becker <universe@uap-core.de>
parents:
1190
diff
changeset
|
182 | iter.base.current = my_foo_iter_current; |
|
790ff923f375
add iterator documentation
Mike Becker <universe@uap-core.de>
parents:
1190
diff
changeset
|
183 | iter.base.next = my_foo_iter_next; |
|
790ff923f375
add iterator documentation
Mike Becker <universe@uap-core.de>
parents:
1190
diff
changeset
|
184 | iter.base.remove = false; |
|
1429
6e0c3a8a914a
remove the concept of "mutating iterators" - resolves #579
Mike Becker <universe@uap-core.de>
parents:
1424
diff
changeset
|
185 | iter.base.allow_remove = false; |
|
1215
790ff923f375
add iterator documentation
Mike Becker <universe@uap-core.de>
parents:
1190
diff
changeset
|
186 | |
|
790ff923f375
add iterator documentation
Mike Becker <universe@uap-core.de>
parents:
1190
diff
changeset
|
187 | // custom fields |
|
790ff923f375
add iterator documentation
Mike Becker <universe@uap-core.de>
parents:
1190
diff
changeset
|
188 | iter.index = 0; |
|
790ff923f375
add iterator documentation
Mike Becker <universe@uap-core.de>
parents:
1190
diff
changeset
|
189 | iter.elem_count = elem_count; |
|
790ff923f375
add iterator documentation
Mike Becker <universe@uap-core.de>
parents:
1190
diff
changeset
|
190 | |
|
790ff923f375
add iterator documentation
Mike Becker <universe@uap-core.de>
parents:
1190
diff
changeset
|
191 | return iter; |
|
790ff923f375
add iterator documentation
Mike Becker <universe@uap-core.de>
parents:
1190
diff
changeset
|
192 | } |
|
790ff923f375
add iterator documentation
Mike Becker <universe@uap-core.de>
parents:
1190
diff
changeset
|
193 | ``` |
|
790ff923f375
add iterator documentation
Mike Becker <universe@uap-core.de>
parents:
1190
diff
changeset
|
194 | |
|
790ff923f375
add iterator documentation
Mike Becker <universe@uap-core.de>
parents:
1190
diff
changeset
|
195 | > Note, that the behavior of `current` is undefined when `valid` returns `false`. |
|
790ff923f375
add iterator documentation
Mike Becker <universe@uap-core.de>
parents:
1190
diff
changeset
|
196 | > That means, on the one hand, `current` does not need to check for validity of the iterator, |
|
1424
563033aa998c
fixes tons of typos and grammar issues across the documentation - fixes #667
Mike Becker <universe@uap-core.de>
parents:
1245
diff
changeset
|
197 | > but on the other hand, it is forbidden to invoke `current` when `valid` would return `false`. |
|
1215
790ff923f375
add iterator documentation
Mike Becker <universe@uap-core.de>
parents:
1190
diff
changeset
|
198 | {style="note"} |
|
790ff923f375
add iterator documentation
Mike Becker <universe@uap-core.de>
parents:
1190
diff
changeset
|
199 | |
|
790ff923f375
add iterator documentation
Mike Becker <universe@uap-core.de>
parents:
1190
diff
changeset
|
200 | > If performance matters in your application, it is recommended that you indeed create specialized iterators |
|
1424
563033aa998c
fixes tons of typos and grammar issues across the documentation - fixes #667
Mike Becker <universe@uap-core.de>
parents:
1245
diff
changeset
|
201 | > for your collections. The default UCX implementations trade some performance for generality. |
|
1190
a7b913d5d589
bring incomplete docs into a shape that can be released
Mike Becker <universe@uap-core.de>
parents:
1146
diff
changeset
|
202 | |
|
a7b913d5d589
bring incomplete docs into a shape that can be released
Mike Becker <universe@uap-core.de>
parents:
1146
diff
changeset
|
203 | <seealso> |
|
a7b913d5d589
bring incomplete docs into a shape that can be released
Mike Becker <universe@uap-core.de>
parents:
1146
diff
changeset
|
204 | <category ref="apidoc"> |
|
a7b913d5d589
bring incomplete docs into a shape that can be released
Mike Becker <universe@uap-core.de>
parents:
1146
diff
changeset
|
205 | <a href="https://ucx.sourceforge.io/api/iterator_8h.html">iterator.h</a> |
|
a7b913d5d589
bring incomplete docs into a shape that can be released
Mike Becker <universe@uap-core.de>
parents:
1146
diff
changeset
|
206 | </category> |
|
a7b913d5d589
bring incomplete docs into a shape that can be released
Mike Becker <universe@uap-core.de>
parents:
1146
diff
changeset
|
207 | </seealso> |