forked from enlightenment/efl
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
This commit is contained in:
parent
a8f520188a
commit
bd474a8829
|
@ -29,6 +29,8 @@
|
||||||
#include "eina_safety_checks.h"
|
#include "eina_safety_checks.h"
|
||||||
#include "eina_iterator.h"
|
#include "eina_iterator.h"
|
||||||
|
|
||||||
|
#include "eina_list.h"
|
||||||
|
|
||||||
/*============================================================================*
|
/*============================================================================*
|
||||||
* Local *
|
* Local *
|
||||||
*============================================================================*/
|
*============================================================================*/
|
||||||
|
@ -290,6 +292,83 @@ eina_carray_length_iterator_new(void** array, unsigned int step, unsigned int le
|
||||||
return &it->iterator;
|
return &it->iterator;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
typedef struct _Eina_Iterator_Multi Eina_Multi_Iterator;
|
||||||
|
|
||||||
|
struct _Eina_Iterator_Multi
|
||||||
|
{
|
||||||
|
Eina_Iterator iterator;
|
||||||
|
|
||||||
|
Eina_List *iterators;
|
||||||
|
};
|
||||||
|
|
||||||
|
static Eina_Bool
|
||||||
|
eina_multi_iterator_next(Eina_Multi_Iterator *it, void **data)
|
||||||
|
{
|
||||||
|
Eina_Bool r;
|
||||||
|
|
||||||
|
if (!it->iterators)
|
||||||
|
return EINA_FALSE;
|
||||||
|
|
||||||
|
// Search for an iterator that do have some data
|
||||||
|
while (!eina_iterator_next(eina_list_data_get(it->iterators), data))
|
||||||
|
{
|
||||||
|
eina_iterator_free(eina_list_data_get(it->iterators));
|
||||||
|
it->iterators = eina_list_remove_list(it->iterators, it->iterators);
|
||||||
|
|
||||||
|
if (!it->iterators) return EINA_FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
return EINA_TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void**
|
||||||
|
eina_multi_iterator_get_container(Eina_Multi_Iterator *it)
|
||||||
|
{
|
||||||
|
if (!it->iterators) return NULL;
|
||||||
|
return eina_iterator_container_get(eina_list_data_get(it->iterators));
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
eina_multi_iterator_free(Eina_Multi_Iterator *it)
|
||||||
|
{
|
||||||
|
Eina_Iterator *itc;
|
||||||
|
|
||||||
|
EINA_LIST_FREE(it->iterators, itc)
|
||||||
|
eina_iterator_free(itc);
|
||||||
|
free(it);
|
||||||
|
}
|
||||||
|
|
||||||
|
EAPI Eina_Iterator *
|
||||||
|
eina_multi_iterator_internal_new(Eina_Iterator *itc, ...)
|
||||||
|
{
|
||||||
|
Eina_Multi_Iterator *it;
|
||||||
|
va_list args;
|
||||||
|
|
||||||
|
it = calloc(1, sizeof (Eina_Multi_Iterator));
|
||||||
|
if (!it) return NULL;
|
||||||
|
|
||||||
|
EINA_MAGIC_SET(&it->iterator, EINA_MAGIC_ITERATOR);
|
||||||
|
|
||||||
|
it->iterators = eina_list_append(it->iterators, itc);
|
||||||
|
|
||||||
|
va_start(args, itc);
|
||||||
|
|
||||||
|
while ((itc = (Eina_Iterator *) va_arg(args, Eina_Iterator *)))
|
||||||
|
{
|
||||||
|
it->iterators = eina_list_append(it->iterators, itc);
|
||||||
|
}
|
||||||
|
|
||||||
|
va_end(args);
|
||||||
|
|
||||||
|
it->iterator.version = EINA_ITERATOR_VERSION;
|
||||||
|
it->iterator.next = FUNC_ITERATOR_NEXT(eina_multi_iterator_next);
|
||||||
|
it->iterator.get_container = FUNC_ITERATOR_GET_CONTAINER(
|
||||||
|
eina_multi_iterator_get_container);
|
||||||
|
it->iterator.free = FUNC_ITERATOR_FREE(eina_multi_iterator_free);
|
||||||
|
|
||||||
|
return &it->iterator;
|
||||||
|
}
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
Eina_Iterator iterator;
|
Eina_Iterator iterator;
|
||||||
|
|
||||||
|
|
|
@ -349,6 +349,39 @@ EAPI Eina_Iterator *eina_carray_length_iterator_new(void** array, unsigned int s
|
||||||
*/
|
*/
|
||||||
EAPI 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;
|
EAPI 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;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Creates an Eina_Iterator that iterates through a serie
|
||||||
|
* of Eina_Iterator.
|
||||||
|
*
|
||||||
|
* @param[in] it The first Eina_Iterator to iterate over
|
||||||
|
* @return The iterator that will walk all the other iterator
|
||||||
|
*
|
||||||
|
* Eina_Iterator* iterator = eina_multi_iterator_new(it1, it2, it3, NULL);
|
||||||
|
*
|
||||||
|
* @note The returned array will destroy iterator given to it once they are not
|
||||||
|
* necessary anymore. Taking ownership of those iterator.
|
||||||
|
*
|
||||||
|
* @since 1.22
|
||||||
|
*/
|
||||||
|
EAPI Eina_Iterator *eina_multi_iterator_internal_new(Eina_Iterator *it, ...) EINA_ARG_NONNULL(1) EINA_WARN_UNUSED_RESULT;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @def eina_multi_iterator_new
|
||||||
|
* @brief Creates an Eina_Iterator that iterates through a serie
|
||||||
|
* of Eina_Iterator.
|
||||||
|
*
|
||||||
|
* @param[in] it The first Eina_Iterator to iterate over
|
||||||
|
* @return The iterator that will walk all the other iterator
|
||||||
|
*
|
||||||
|
* Eina_Iterator* iterator = eina_multi_iterator_new(it1, it2, it3);
|
||||||
|
*
|
||||||
|
* @note The returned array will destroy iterator given to it once they are not
|
||||||
|
* necessary anymore. Taking ownership of those iterator.
|
||||||
|
*
|
||||||
|
* @since 1.22
|
||||||
|
*/
|
||||||
|
#define eina_multi_iterator_new(It, ...) eina_multi_iterator_internal_new(It, ##__VA_ARGS__, NULL)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @def EINA_ITERATOR_FOREACH
|
* @def EINA_ITERATOR_FOREACH
|
||||||
* @brief Definition for the macro to iterate over all elements easily.
|
* @brief Definition for the macro to iterate over all elements easily.
|
||||||
|
|
Loading…
Reference in New Issue