From 041c4f41df5d143fa4612b3432df6b31a685a9e9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9my=20Zurcher?= Date: Thu, 13 Jun 2013 14:59:26 +0200 Subject: [PATCH] add EAPI Eina_List* eina_list_reduce(Eina_List *list, Eina_Reduce_Cb func, void *acc) - apply the reduce function on the list nodes - typedef void (*Eina_Reduce_Cb)(const void *data, void *acc) --- src/lib/eina/eina_list.c | 20 ++++++++++++++++++++ src/lib/eina/eina_list.h | 13 +++++++++++++ src/lib/eina/eina_types.h | 12 ++++++++++++ src/tests/eina/eina_test_list.c | 14 ++++++++++++-- 4 files changed, 57 insertions(+), 2 deletions(-) diff --git a/src/lib/eina/eina_list.c b/src/lib/eina/eina_list.c index 3cf7940a4b..e2cb1cde22 100644 --- a/src/lib/eina/eina_list.c +++ b/src/lib/eina/eina_list.c @@ -1198,6 +1198,26 @@ eina_list_map(Eina_List *list, Eina_Map_Cb func) return list; } +EAPI Eina_List * +eina_list_reduce(Eina_List *list, Eina_Reduce_Cb func, void *acc) +{ + const Eina_List *l; + void *data; + + if (!list) + return NULL; + + EINA_MAGIC_CHECK_LIST(list, NULL); + + if (func == NULL) + return list; + + EINA_LIST_FOREACH(list, l, data) + func(data, acc); + + return list; +} + EAPI Eina_List * eina_list_shuffle(Eina_List *list, Eina_Random_Cb func) { diff --git a/src/lib/eina/eina_list.h b/src/lib/eina/eina_list.h index 3163031ef3..509b60a873 100644 --- a/src/lib/eina/eina_list.h +++ b/src/lib/eina/eina_list.h @@ -970,6 +970,19 @@ EAPI Eina_List *eina_list_filter(Eina_List *list, Eina_Filter_Cb func */ EAPI Eina_List *eina_list_map(Eina_List *list, Eina_Map_Cb func) EINA_WARN_UNUSED_RESULT; +/** + * @brief Apply a reduce function on all nodes of list + * + * @param list The list to reduce. + * @param func The reduce function to apply on nodes. + * @param acc The pointer to the accumulator of the reduce function. + * @return The same list. + * @since 1.8 + * + * @warning @p list must be a pointer to the first element of the list. + */ +EAPI Eina_List *eina_list_reduce(Eina_List *list, Eina_Reduce_Cb func, void *acc) EINA_WARN_UNUSED_RESULT; + /** * @brief Shuffle list. * diff --git a/src/lib/eina/eina_types.h b/src/lib/eina/eina_types.h index c5e213cf11..160da8d38b 100644 --- a/src/lib/eina/eina_types.h +++ b/src/lib/eina/eina_types.h @@ -359,6 +359,18 @@ typedef void (*Eina_Map_Cb)(const void *data); */ #define EINA_MAP_CB(function) ((Eina_Map_Cb)function) +/** + * @typedef Eina_Reduce_Cb + * Function to be applied on nodes. + */ +typedef void (*Eina_Reduce_Cb)(const void *data, void *acc); + +/** + * @def EINA_REDUCE_CB + * Macro to cast to Eina_Reduce_Cb. + */ +#define EINA_REDUCE_CB(function) ((Eina_Reduce_Cb)function) + /** * @typedef Eina_Random_Cb * Function used in shuffling functions. An integer betwen min and max diff --git a/src/tests/eina/eina_test_list.c b/src/tests/eina/eina_test_list.c index 45c296d56b..2e01061d73 100644 --- a/src/tests/eina/eina_test_list.c +++ b/src/tests/eina/eina_test_list.c @@ -506,10 +506,16 @@ static void map_cb(int *data) *data = *data * 3; } -START_TEST(eina_test_filter) +static void reduce_cb(int *data, int *acc) +{ + *acc += (*data * 3); +} + +START_TEST(eina_test_filter_map_reduce) { int i; int *p; + int sum; int data[] = { 6, 9, 93, 42, 1, 7, 9, 81, 1664, 1337 }; int result1[] = { 6, 9, 42, 1, 7, 9 }; int result2[] = { 18, 27, 126, 3, 21, 27 }; @@ -545,6 +551,10 @@ START_TEST(eina_test_filter) p = eina_list_nth(l, i); fail_if(*p != result2[i]); } + + l = eina_list_reduce(l, EINA_REDUCE_CB(reduce_cb), &sum); + fail_if(sum != 666); + l = eina_list_free(l); list = eina_list_free(list); @@ -562,5 +572,5 @@ eina_test_list(TCase *tc) tcase_add_test(tc, eina_test_list_split); tcase_add_test(tc, eina_test_shuffle); tcase_add_test(tc, eina_test_remove_duplicates); - tcase_add_test(tc, eina_test_filter); + tcase_add_test(tc, eina_test_filter_map_reduce); }