summaryrefslogtreecommitdiff
path: root/src/lib/eina
diff options
context:
space:
mode:
authorCedric BAIL <cedric@osg.samsung.com>2018-11-15 17:42:27 -0800
committerCedric BAIL <cedric@osg.samsung.com>2018-11-23 10:13:54 -0800
commitbd474a8829119d487e5a3bb42f8a0d7a372948ad (patch)
tree6a9348aafb6e266121030e098e403580fa0fb387 /src/lib/eina
parenta8f520188a19f722d4ae6dee6246d37cb46bb975 (diff)
eina: add eina_multi_iterator_new.
This will return an Iterator that will walk over a serie of iterator. This technicaly take ownership of the iterator it is walking over and destroy as it goes and doesn't need them anymore. Reviewed-by: Vitor Sousa da Silva <vitorsousa@expertisesolutions.com.br> Differential Revision: https://phab.enlightenment.org/D7286
Diffstat (limited to 'src/lib/eina')
-rw-r--r--src/lib/eina/eina_iterator.c79
-rw-r--r--src/lib/eina/eina_iterator.h33
2 files changed, 112 insertions, 0 deletions
diff --git a/src/lib/eina/eina_iterator.c b/src/lib/eina/eina_iterator.c
index d025b6ad5b..34763f2148 100644
--- a/src/lib/eina/eina_iterator.c
+++ b/src/lib/eina/eina_iterator.c
@@ -29,6 +29,8 @@
29#include "eina_safety_checks.h" 29#include "eina_safety_checks.h"
30#include "eina_iterator.h" 30#include "eina_iterator.h"
31 31
32#include "eina_list.h"
33
32/*============================================================================* 34/*============================================================================*
33 * Local * 35 * Local *
34 *============================================================================*/ 36 *============================================================================*/
@@ -290,6 +292,83 @@ eina_carray_length_iterator_new(void** array, unsigned int step, unsigned int le
290 return &it->iterator; 292 return &it->iterator;
291} 293}
292 294
295typedef struct _Eina_Iterator_Multi Eina_Multi_Iterator;
296
297struct _Eina_Iterator_Multi
298{
299 Eina_Iterator iterator;
300
301 Eina_List *iterators;
302};
303
304static Eina_Bool
305eina_multi_iterator_next(Eina_Multi_Iterator *it, void **data)
306{
307 Eina_Bool r;
308
309 if (!it->iterators)
310 return EINA_FALSE;
311
312 // Search for an iterator that do have some data
313 while (!eina_iterator_next(eina_list_data_get(it->iterators), data))
314 {
315 eina_iterator_free(eina_list_data_get(it->iterators));
316 it->iterators = eina_list_remove_list(it->iterators, it->iterators);
317
318 if (!it->iterators) return EINA_FALSE;
319 }
320
321 return EINA_TRUE;
322}
323
324static void**
325eina_multi_iterator_get_container(Eina_Multi_Iterator *it)
326{
327 if (!it->iterators) return NULL;
328 return eina_iterator_container_get(eina_list_data_get(it->iterators));
329}
330
331static void
332eina_multi_iterator_free(Eina_Multi_Iterator *it)
333{
334 Eina_Iterator *itc;
335
336 EINA_LIST_FREE(it->iterators, itc)
337 eina_iterator_free(itc);
338 free(it);
339}
340
341EAPI Eina_Iterator *
342eina_multi_iterator_internal_new(Eina_Iterator *itc, ...)
343{
344 Eina_Multi_Iterator *it;
345 va_list args;
346
347 it = calloc(1, sizeof (Eina_Multi_Iterator));
348 if (!it) return NULL;
349
350 EINA_MAGIC_SET(&it->iterator, EINA_MAGIC_ITERATOR);
351
352 it->iterators = eina_list_append(it->iterators, itc);
353
354 va_start(args, itc);
355
356 while ((itc = (Eina_Iterator *) va_arg(args, Eina_Iterator *)))
357 {
358 it->iterators = eina_list_append(it->iterators, itc);
359 }
360
361 va_end(args);
362
363 it->iterator.version = EINA_ITERATOR_VERSION;
364 it->iterator.next = FUNC_ITERATOR_NEXT(eina_multi_iterator_next);
365 it->iterator.get_container = FUNC_ITERATOR_GET_CONTAINER(
366 eina_multi_iterator_get_container);
367 it->iterator.free = FUNC_ITERATOR_FREE(eina_multi_iterator_free);
368
369 return &it->iterator;
370}
371
293typedef struct { 372typedef struct {
294 Eina_Iterator iterator; 373 Eina_Iterator iterator;
295 374
diff --git a/src/lib/eina/eina_iterator.h b/src/lib/eina/eina_iterator.h
index 7f1e94cb02..ebfd27c2cc 100644
--- a/src/lib/eina/eina_iterator.h
+++ b/src/lib/eina/eina_iterator.h
@@ -350,6 +350,39 @@ EAPI Eina_Iterator *eina_carray_length_iterator_new(void** array, unsigned int s
350EAPI Eina_Iterator* eina_iterator_filter_new(Eina_Iterator *original, Eina_Each_Cb filter, Eina_Free_Cb free_cb, void *data) EINA_ARG_NONNULL(1) EINA_WARN_UNUSED_RESULT; 350EAPI Eina_Iterator* eina_iterator_filter_new(Eina_Iterator *original, Eina_Each_Cb filter, Eina_Free_Cb free_cb, void *data) EINA_ARG_NONNULL(1) EINA_WARN_UNUSED_RESULT;
351 351
352/** 352/**
353 * @brief Creates an Eina_Iterator that iterates through a serie
354 * of Eina_Iterator.
355 *
356 * @param[in] it The first Eina_Iterator to iterate over
357 * @return The iterator that will walk all the other iterator
358 *
359 * Eina_Iterator* iterator = eina_multi_iterator_new(it1, it2, it3, NULL);
360 *
361 * @note The returned array will destroy iterator given to it once they are not
362 * necessary anymore. Taking ownership of those iterator.
363 *
364 * @since 1.22
365 */
366EAPI Eina_Iterator *eina_multi_iterator_internal_new(Eina_Iterator *it, ...) EINA_ARG_NONNULL(1) EINA_WARN_UNUSED_RESULT;
367
368/**
369 * @def eina_multi_iterator_new
370 * @brief Creates an Eina_Iterator that iterates through a serie
371 * of Eina_Iterator.
372 *
373 * @param[in] it The first Eina_Iterator to iterate over
374 * @return The iterator that will walk all the other iterator
375 *
376 * Eina_Iterator* iterator = eina_multi_iterator_new(it1, it2, it3);
377 *
378 * @note The returned array will destroy iterator given to it once they are not
379 * necessary anymore. Taking ownership of those iterator.
380 *
381 * @since 1.22
382 */
383#define eina_multi_iterator_new(It, ...) eina_multi_iterator_internal_new(It, ##__VA_ARGS__, NULL)
384
385/**
353 * @def EINA_ITERATOR_FOREACH 386 * @def EINA_ITERATOR_FOREACH
354 * @brief Definition for the macro to iterate over all elements easily. 387 * @brief Definition for the macro to iterate over all elements easily.
355 * 388 *