diff --git a/src/lib/eina/eina_iterator.c b/src/lib/eina/eina_iterator.c index 4a4e281079..d025b6ad5b 100644 --- a/src/lib/eina/eina_iterator.c +++ b/src/lib/eina/eina_iterator.c @@ -229,6 +229,67 @@ eina_carray_iterator_new(void** array) return &it->iterator; } +typedef struct _Eina_Iterator_CArray_Length Eina_Iterator_CArray_Length; + +struct _Eina_Iterator_CArray_Length +{ + Eina_Iterator iterator; + + void** array; + uintptr_t current; + + uintptr_t end; + unsigned int step; +}; + +static Eina_Bool +eina_carray_length_iterator_next(Eina_Iterator_CArray_Length *it, void **data) +{ + if (it->current >= it->end) + return EINA_FALSE; + + memcpy(data, (void*) it->current, it->step); + it->current += it->step; + + return EINA_TRUE; +} + +static void** +eina_carray_length_iterator_get_container(Eina_Iterator_CArray_Length *it) +{ + return it->array; +} + +static void +eina_carray_length_iterator_free(Eina_Iterator_CArray_Length *it) +{ + free(it); +} + +EAPI Eina_Iterator * +eina_carray_length_iterator_new(void** array, unsigned int step, unsigned int length) +{ + Eina_Iterator_CArray_Length *it; + + it = calloc(1, sizeof (Eina_Iterator_CArray_Length)); + if (!it) return NULL; + + EINA_MAGIC_SET(&it->iterator, EINA_MAGIC_ITERATOR); + + it->array = array; + it->current = (uintptr_t) it->array; + it->end = it->current + length * step; + it->step = step; + + it->iterator.version = EINA_ITERATOR_VERSION; + it->iterator.next = FUNC_ITERATOR_NEXT(eina_carray_length_iterator_next); + it->iterator.get_container = FUNC_ITERATOR_GET_CONTAINER( + eina_carray_length_iterator_get_container); + it->iterator.free = FUNC_ITERATOR_FREE(eina_carray_length_iterator_free); + + return &it->iterator; +} + typedef struct { Eina_Iterator iterator; diff --git a/src/lib/eina/eina_iterator.h b/src/lib/eina/eina_iterator.h index 6c33db1a63..1bed2bd33b 100644 --- a/src/lib/eina/eina_iterator.h +++ b/src/lib/eina/eina_iterator.h @@ -294,11 +294,42 @@ EAPI Eina_Bool eina_iterator_unlock(Eina_Iterator *iterator) EINA_ARG_NONNULL(1) * int array[] = {1, 2, 3, 4}; * int* array2[] = {&array[0], &array[1], &array[2], &array[3], NULL}; * - * Eina_Iterator* iterator = eina_carray_iterator_new((void**)array); + * Eina_Iterator* iterator = eina_carray_iterator_new((void**)array2); * * @since 1.18 */ -EAPI Eina_Iterator* eina_carray_iterator_new(void** array) EINA_ARG_NONNULL(1) EINA_WARN_UNUSED_RESULT; +EAPI Eina_Iterator *eina_carray_iterator_new(void** array) EINA_ARG_NONNULL(1) EINA_WARN_UNUSED_RESULT; + +/** + * @brief Creates an Eina_Iterator that iterates through a + * C array of specified size. + * + * @param[in] array The array + * + * You can create it like this: + * int array[] = {1, 2, 3, 4}; + * + * Eina_Iterator* iterator = eina_carray_length_iterator_new((void**)array, sizeof (array[0]), (EINA_C_ARRAY_LENGTH(array)); + * + * @since 1.22 + */ +EAPI Eina_Iterator *eina_carray_length_iterator_new(void** array, unsigned int step, unsigned int length) EINA_ARG_NONNULL(1) EINA_WARN_UNUSED_RESULT; + +/** + * @def EINA_C_ARRAY_ITERATOR_NEW + * @brief Creates an Eina_Iterator that iterates through a + * NUL-terminated C array. + * + * @param[in] array The NUL-terminated array + * + * You can create it like this: + * int array[] = {1, 2, 3, 4}; + * + * Eina_Iterator* iterator = EINA_C_ARRAY_ITERATOR_NEW(array); + * + * @since 1.22 + */ +#define EINA_C_ARRAY_ITERATOR_NEW(Array) eina_carray_length_iterator_new((void**) Array, sizeof (Array[0]), EINA_C_ARRAY_LENGTH(Array)) /** * @brief Creates a new iterator which which iterates through all elements with are accepted by the filter callback