diff options
Diffstat (limited to '')
-rw-r--r-- | libraries/eina/src/include/eina_iterator.h | 337 |
1 files changed, 337 insertions, 0 deletions
diff --git a/libraries/eina/src/include/eina_iterator.h b/libraries/eina/src/include/eina_iterator.h new file mode 100644 index 0000000..1c8e6ce --- /dev/null +++ b/libraries/eina/src/include/eina_iterator.h | |||
@@ -0,0 +1,337 @@ | |||
1 | /* EINA - EFL data type library | ||
2 | * Copyright (C) 2008 Cedric Bail | ||
3 | * | ||
4 | * This library is free software; you can redistribute it and/or | ||
5 | * modify it under the terms of the GNU Lesser General Public | ||
6 | * License as published by the Free Software Foundation; either | ||
7 | * version 2.1 of the License, or (at your option) any later version. | ||
8 | * | ||
9 | * This library is distributed in the hope that it will be useful, | ||
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
12 | * Lesser General Public License for more details. | ||
13 | * | ||
14 | * You should have received a copy of the GNU Lesser General Public | ||
15 | * License along with this library; | ||
16 | * if not, see <http://www.gnu.org/licenses/>. | ||
17 | */ | ||
18 | |||
19 | #ifndef EINA_ITERATOR_H__ | ||
20 | #define EINA_ITERATOR_H__ | ||
21 | |||
22 | #include "eina_config.h" | ||
23 | |||
24 | #include "eina_types.h" | ||
25 | #include "eina_magic.h" | ||
26 | |||
27 | /** | ||
28 | * @page eina_iterator_example Eina_Iterator usage | ||
29 | * @dontinclude eina_iterator_01.c | ||
30 | * | ||
31 | * As always when using eina we need to include it: | ||
32 | * @skip #include | ||
33 | * @until Eina.h | ||
34 | * | ||
35 | * Here we a declare an unimpressive @ref Eina_Each_Cb "function" that prints | ||
36 | * some data: | ||
37 | * @until } | ||
38 | * @note Returning EINA_TRUE is important so we don't stop iterating over the | ||
39 | * container. | ||
40 | * | ||
41 | * And here a more interesting function, it uses an iterator to print the | ||
42 | * contents of a container. What's interesting about it is that it doesn't care | ||
43 | * the type of container, it works for anything that can provide an iterator: | ||
44 | * @until } | ||
45 | * | ||
46 | * And on to our main function were we declare some variables and initialize | ||
47 | * eina, nothing too special: | ||
48 | * @until eina_init | ||
49 | * | ||
50 | * Next we populate both an array and a list with our strings, for more details | ||
51 | * see @ref eina_list_01_example and @ref eina_array_01_example: | ||
52 | * @until } | ||
53 | * | ||
54 | * And now we create an array and because the first element of the container | ||
55 | * doesn't interest us we skip it: | ||
56 | * @until iterator_next | ||
57 | * | ||
58 | * Having our iterator now pointing to interesting data we go ahead and print: | ||
59 | * @until print_eina_container | ||
60 | * | ||
61 | * As always once data with a structure we free it, but just because we can we | ||
62 | * do it by asking the iterator for it's container, and then of course free the | ||
63 | * iterator itself: | ||
64 | * @until eina_iterator_free | ||
65 | * | ||
66 | * But so far you're not impressed in @ref eina_array_01_example an array is | ||
67 | * also printed, so now we go to the cool stuff and use an iterator to do same | ||
68 | * stuff to a list: | ||
69 | * @until eina_iterator_free | ||
70 | * @note The only significant diference to the block above is in the | ||
71 | * function used to create the iterator. | ||
72 | * | ||
73 | * And now we free the list and shut eina down: | ||
74 | * @until } | ||
75 | */ | ||
76 | |||
77 | /** | ||
78 | * @page eina_iterator_01_c Eina_Iterator usage | ||
79 | * @page eina_iterator_01_c Eina_Iterator usage | ||
80 | * | ||
81 | * @include eina_iterator_01.c | ||
82 | * @example eina_iterator_01.c | ||
83 | */ | ||
84 | |||
85 | /** | ||
86 | * @addtogroup Eina_Iterator_Group Iterator Functions | ||
87 | * | ||
88 | * @brief These functions manage iterators on containers. | ||
89 | * | ||
90 | * These functions allow to access elements of a container in a | ||
91 | * generic way, without knowing which container is used (a bit like | ||
92 | * iterators in the C++ STL). Iterators only allows sequential access | ||
93 | * (that is, from an element to the next one). For random access, see | ||
94 | * @ref Eina_Accessor_Group. | ||
95 | * | ||
96 | * An iterator is created from container data types, so no creation | ||
97 | * function is available here. An iterator is deleted with | ||
98 | * eina_iterator_free(). To get the data and iterate, use | ||
99 | * eina_iterator_next(). To call a function on all the elements of a | ||
100 | * container, use eina_iterator_foreach(). | ||
101 | * | ||
102 | * Here an @ref eina_iterator_example "example" | ||
103 | */ | ||
104 | |||
105 | /** | ||
106 | * @addtogroup Eina_Content_Access_Group Content Access | ||
107 | * | ||
108 | * @{ | ||
109 | */ | ||
110 | |||
111 | /** | ||
112 | * @defgroup Eina_Iterator_Group Iterator Functions | ||
113 | * | ||
114 | * @{ | ||
115 | */ | ||
116 | |||
117 | /** | ||
118 | * @typedef Eina_Iterator | ||
119 | * Abstract type for iterators. | ||
120 | */ | ||
121 | typedef struct _Eina_Iterator Eina_Iterator; | ||
122 | |||
123 | /** | ||
124 | * @typedef Eina_Iterator_Next_Callback | ||
125 | * Type for a callback that returns the next element in a container. | ||
126 | */ | ||
127 | typedef Eina_Bool (*Eina_Iterator_Next_Callback)(Eina_Iterator *it, void **data); | ||
128 | |||
129 | /** | ||
130 | * @typedef Eina_Iterator_Get_Container_Callback | ||
131 | * Type for a callback that returns the container. | ||
132 | */ | ||
133 | typedef void *(*Eina_Iterator_Get_Container_Callback)(Eina_Iterator *it); | ||
134 | |||
135 | /** | ||
136 | * @typedef Eina_Iterator_Free_Callback | ||
137 | * Type for a callback that frees the container. | ||
138 | */ | ||
139 | typedef void (*Eina_Iterator_Free_Callback)(Eina_Iterator *it); | ||
140 | |||
141 | /** | ||
142 | * @typedef Eina_Iterator_Lock_Callback | ||
143 | * Type for a callback that lock the container. | ||
144 | */ | ||
145 | typedef Eina_Bool (*Eina_Iterator_Lock_Callback)(Eina_Iterator *it); | ||
146 | |||
147 | /** | ||
148 | * @struct _Eina_Iterator | ||
149 | * structure of an iterator | ||
150 | */ | ||
151 | struct _Eina_Iterator | ||
152 | { | ||
153 | #define EINA_ITERATOR_VERSION 1 | ||
154 | int version; /**< Version of the Iterator API. */ | ||
155 | |||
156 | Eina_Iterator_Next_Callback next EINA_ARG_NONNULL(1, 2) EINA_WARN_UNUSED_RESULT; /**< Callback called when a next element is requested. */ | ||
157 | Eina_Iterator_Get_Container_Callback get_container EINA_ARG_NONNULL(1) EINA_WARN_UNUSED_RESULT; /**< Callback called when the container is requested. */ | ||
158 | Eina_Iterator_Free_Callback free EINA_ARG_NONNULL(1); /**< Callback called when the container is freed. */ | ||
159 | |||
160 | Eina_Iterator_Lock_Callback lock EINA_WARN_UNUSED_RESULT; /**< Callback called when the container is locked. */ | ||
161 | Eina_Iterator_Lock_Callback unlock EINA_WARN_UNUSED_RESULT; /**< Callback called when the container is unlocked. */ | ||
162 | |||
163 | #define EINA_MAGIC_ITERATOR 0x98761233 | ||
164 | EINA_MAGIC | ||
165 | }; | ||
166 | |||
167 | /** | ||
168 | * @def FUNC_ITERATOR_NEXT(Function) | ||
169 | * Helper macro to cast @p Function to a Eina_Iterator_Next_Callback. | ||
170 | */ | ||
171 | #define FUNC_ITERATOR_NEXT(Function) ((Eina_Iterator_Next_Callback)Function) | ||
172 | |||
173 | /** | ||
174 | * @def FUNC_ITERATOR_GET_CONTAINER(Function) | ||
175 | * Helper macro to cast @p Function to a Eina_Iterator_Get_Container_Callback. | ||
176 | */ | ||
177 | #define FUNC_ITERATOR_GET_CONTAINER(Function) ((Eina_Iterator_Get_Container_Callback)Function) | ||
178 | |||
179 | /** | ||
180 | * @def FUNC_ITERATOR_FREE(Function) | ||
181 | * Helper macro to cast @p Function to a Eina_Iterator_Free_Callback. | ||
182 | */ | ||
183 | #define FUNC_ITERATOR_FREE(Function) ((Eina_Iterator_Free_Callback)Function) | ||
184 | |||
185 | /** | ||
186 | * @def FUNC_ITERATOR_LOCK(Function) | ||
187 | * Helper macro to cast @p Function to a Eina_Iterator_Lock_Callback. | ||
188 | */ | ||
189 | #define FUNC_ITERATOR_LOCK(Function) ((Eina_Iterator_Lock_Callback)Function) | ||
190 | |||
191 | |||
192 | /** | ||
193 | * @brief Free an iterator. | ||
194 | * | ||
195 | * @param iterator The iterator to free. | ||
196 | * | ||
197 | * This function frees @p iterator if it is not @c NULL; | ||
198 | */ | ||
199 | EAPI void eina_iterator_free(Eina_Iterator *iterator) EINA_ARG_NONNULL(1); | ||
200 | |||
201 | |||
202 | /** | ||
203 | * @brief Return the container of an iterator. | ||
204 | * | ||
205 | * @param iterator The iterator. | ||
206 | * @return The container which created the iterator. | ||
207 | * | ||
208 | * This function returns the container which created @p iterator. If | ||
209 | * @p iterator is @c NULL, this function returns @c NULL. | ||
210 | */ | ||
211 | EAPI void *eina_iterator_container_get(Eina_Iterator *iterator) EINA_ARG_NONNULL(1) EINA_PURE; | ||
212 | |||
213 | /** | ||
214 | * @brief Return the value of the current element and go to the next one. | ||
215 | * | ||
216 | * @param iterator The iterator. | ||
217 | * @param data The data of the element. | ||
218 | * @return #EINA_TRUE on success, #EINA_FALSE otherwise. | ||
219 | * | ||
220 | * This function returns the value of the current element pointed by | ||
221 | * @p iterator in @p data, then goes to the next element. If @p | ||
222 | * iterator is @c NULL or if a problem occurred, #EINA_FALSE is | ||
223 | * returned, otherwise #EINA_TRUE is returned. | ||
224 | */ | ||
225 | EAPI Eina_Bool eina_iterator_next(Eina_Iterator *iterator, | ||
226 | void **data) EINA_ARG_NONNULL(1, 2) EINA_WARN_UNUSED_RESULT; | ||
227 | |||
228 | |||
229 | /** | ||
230 | * @brief Iterate over the container and execute a callback on each element. | ||
231 | * | ||
232 | * @param iterator The iterator. | ||
233 | * @param callback The callback called on each iteration. | ||
234 | * @param fdata The data passed to the callback. | ||
235 | * | ||
236 | * This function iterates over the elements pointed by @p iterator, | ||
237 | * beginning from the current element. For Each element, the callback | ||
238 | * @p cb is called with the data @p fdata. If @p iterator is @c NULL, | ||
239 | * the function returns immediately. Also, if @p cb returns @c | ||
240 | * EINA_FALSE, the iteration stops at that point, if @p cb returns @c EINA_TRUE | ||
241 | * the iteration continues. | ||
242 | */ | ||
243 | EAPI void eina_iterator_foreach(Eina_Iterator *iterator, | ||
244 | Eina_Each_Cb callback, | ||
245 | const void *fdata) EINA_ARG_NONNULL(1, 2); | ||
246 | |||
247 | |||
248 | /** | ||
249 | * @brief Lock the container of the iterator. | ||
250 | * | ||
251 | * @param iterator The iterator. | ||
252 | * @return #EINA_TRUE on success, #EINA_FALSE otherwise. | ||
253 | * | ||
254 | * If the container of the @p iterator permits it, it will be locked. When a | ||
255 | * container is locked calling eina_iterator_foreach() on it will return | ||
256 | * immediately. If @p iterator is @c NULL or if a problem occurred, #EINA_FALSE | ||
257 | * is returned, otherwise #EINA_TRUE is returned. If the container isn't | ||
258 | * lockable, it will return EINA_TRUE. | ||
259 | * | ||
260 | * @warning None of the existing eina data structures are lockable. | ||
261 | */ | ||
262 | EAPI Eina_Bool eina_iterator_lock(Eina_Iterator *iterator) EINA_ARG_NONNULL(1); | ||
263 | |||
264 | /** | ||
265 | * @brief Unlock the container of the iterator. | ||
266 | * | ||
267 | * @param iterator The iterator. | ||
268 | * @return #EINA_TRUE on success, #EINA_FALSE otherwise. | ||
269 | * | ||
270 | * If the container of the @p iterator permits it and was previously | ||
271 | * locked, it will be unlocked. If @p iterator is @c NULL or if a | ||
272 | * problem occurred, #EINA_FALSE is returned, otherwise #EINA_TRUE | ||
273 | * is returned. If the container is not lockable, it will return | ||
274 | * EINA_TRUE. | ||
275 | * | ||
276 | * @warning None of the existing eina data structures are lockable. | ||
277 | */ | ||
278 | EAPI Eina_Bool eina_iterator_unlock(Eina_Iterator *iterator) EINA_ARG_NONNULL(1); | ||
279 | |||
280 | /** | ||
281 | * @def EINA_ITERATOR_FOREACH | ||
282 | * @brief Macro to iterate over all elements easily. | ||
283 | * | ||
284 | * @param itr The iterator to use. | ||
285 | * @param data Where to store * data, must be a pointer support getting | ||
286 | * its address since * eina_iterator_next() requires a pointer | ||
287 | * to pointer! | ||
288 | * | ||
289 | * This macro is a convenient way to use iterators, very similar to | ||
290 | * EINA_LIST_FOREACH(). | ||
291 | * | ||
292 | * This macro can be used for freeing the data of a list, like in the | ||
293 | * following example. It has the same goal as the one documented in | ||
294 | * EINA_LIST_FOREACH(), but using iterators: | ||
295 | * | ||
296 | * @code | ||
297 | * Eina_List *list; | ||
298 | * Eina_Iterator *itr; | ||
299 | * char *data; | ||
300 | * | ||
301 | * // list is already filled, | ||
302 | * // its elements are just duplicated strings | ||
303 | * | ||
304 | * itr = eina_list_iterator_new(list); | ||
305 | * EINA_ITERATOR_FOREACH(itr, data) | ||
306 | * free(data); | ||
307 | * eina_iterator_free(itr); | ||
308 | * eina_list_free(list); | ||
309 | * @endcode | ||
310 | * | ||
311 | * @note this example is not optimal algorithm to release a list since | ||
312 | * it will walk the list twice, but it serves as an example. For | ||
313 | * optimized version use EINA_LIST_FREE() | ||
314 | * | ||
315 | * @warning The order in which the elements will be traversed depends on the | ||
316 | * underlying container and @b shouldn't be relied upon. | ||
317 | * | ||
318 | * @warning unless explicitly stated in functions returning iterators, | ||
319 | * do not modify the iterated object while you walk it, in this | ||
320 | * example using lists, do not remove list nodes or you might | ||
321 | * crash! This is not a limitiation of iterators themselves, | ||
322 | * rather in the iterators implementations to keep them as simple | ||
323 | * and fast as possible. | ||
324 | */ | ||
325 | #define EINA_ITERATOR_FOREACH(itr, \ | ||
326 | data) while (eina_iterator_next((itr), \ | ||
327 | (void **)(void *)&(data))) | ||
328 | |||
329 | /** | ||
330 | * @} | ||
331 | */ | ||
332 | |||
333 | /** | ||
334 | * @} | ||
335 | */ | ||
336 | |||
337 | #endif | ||