From d87457056803309c8263177dd27ad6f803d92684 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9my=20Zurcher?= Date: Wed, 12 Jun 2013 17:52:06 +0200 Subject: [PATCH] =?UTF-8?q?add=20EAPI=C2=A0eina=5Flist=5Ffilter(Eina=5FLis?= =?UTF-8?q?t=20*list,=20Eina=5FFilter=5FCb=20func)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - eina_list_filter returns a new list - typedef Eina_Bool (*Eina_Filter_Cb)(const void *data); - returns EINA_TRUE if satisfies the predicate --- src/lib/eina/eina_list.c | 25 +++++++++++++++++++ src/lib/eina/eina_list.h | 19 ++++++++++++++ src/lib/eina/eina_types.h | 14 +++++++++++ src/tests/eina/eina_test_list.c | 44 +++++++++++++++++++++++++++++++++ 4 files changed, 102 insertions(+) diff --git a/src/lib/eina/eina_list.c b/src/lib/eina/eina_list.c index 502e2ebe53..96b7fcbe31 100644 --- a/src/lib/eina/eina_list.c +++ b/src/lib/eina/eina_list.c @@ -1153,6 +1153,31 @@ eina_list_sort(Eina_List *list, unsigned int limit, Eina_Compare_Cb func) return list; } +EAPI Eina_List * +eina_list_filter(Eina_List *list, Eina_Filter_Cb func) +{ + const Eina_List *l; + Eina_List *lfiltered; + void *data; + + if (!list) + return NULL; + + EINA_MAGIC_CHECK_LIST(list, NULL); + + if (func == NULL) + return eina_list_clone(list); + + lfiltered = NULL; + EINA_LIST_FOREACH(list, l, data) + { + if (func(data) == EINA_TRUE) + lfiltered = eina_list_append(lfiltered, data); + } + + return lfiltered; +} + 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 02ffb3965a..8f91a8043d 100644 --- a/src/lib/eina/eina_list.h +++ b/src/lib/eina/eina_list.h @@ -939,6 +939,25 @@ EAPI Eina_List *eina_list_clone(const Eina_List *list) EINA_WARN_UNUS EAPI Eina_List *eina_list_sort(Eina_List *list, unsigned int limit, Eina_Compare_Cb func) EINA_ARG_NONNULL(3) EINA_WARN_UNUSED_RESULT; +/** + * @brief filter (clone some) the elements in the list in exactly same order. + * + * @param list The list to filter. + * @param func The filter function. + * @return The new list. + * + * This function clone in order the elements in @p list that satisfy the + * filter @p func. This filter function @p func must return @c EINA_TRUE if the + * element is to be cloned. If @p list is @c NULL, this functon returns @c NULL. + * If @p func is @c NULL, this functon calls @see eina_list_clone(). + * This returns a new list. + * + * @since 1.8 + * + * @warning @p list must be a pointer to the first element of the list. + */ +EAPI Eina_List *eina_list_filter(Eina_List *list, Eina_Filter_Cb func) EINA_WARN_UNUSED_RESULT; + /** * @brief Shuffle list. * diff --git a/src/lib/eina/eina_types.h b/src/lib/eina/eina_types.h index d37b20f71f..66d1ab1481 100644 --- a/src/lib/eina/eina_types.h +++ b/src/lib/eina/eina_types.h @@ -333,6 +333,20 @@ typedef int (*Eina_Compare_Cb)(const void *data1, const void *data2); */ #define EINA_COMPARE_CB(function) ((Eina_Compare_Cb)function) +/** + * @typedef Eina_Filter_Cb + * Function used in filtering functions. + * It returns EINA_TRUE only if @p data satisfies the predicate thus + * is not to be filtered. + */ +typedef Eina_Bool (*Eina_Filter_Cb)(const void *data); + +/** + * @def EINA_FILTER_CB + * Macro to cast to Eina_Filter_Cb. + */ +#define EINA_FILTER_CB(function) ((Eina_Filter_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 2c8c4a3f50..d4eb08086e 100644 --- a/src/tests/eina/eina_test_list.c +++ b/src/tests/eina/eina_test_list.c @@ -496,6 +496,49 @@ START_TEST(eina_test_remove_duplicates) } END_TEST +static Eina_Bool filter_cb(int *data) +{ + return ( (*data < 81) ? EINA_TRUE : EINA_FALSE ); +} + +START_TEST(eina_test_filter) +{ + int i; + int *p; + int data[] = { 6, 9, 93, 42, 1, 7, 9, 81, 1664, 1337 }; + int result[] = { 6, 9, 42, 1, 7, 9, 81 }; + Eina_List *list = NULL; + Eina_List *l = NULL; + + eina_init(); + + for (i = 0; i < 10; i++) + list = eina_list_append(list, &data[i]); + + l = eina_list_filter(list, NULL); + fail_if(eina_list_count(list) != 10); + for (i = 0; i < 10; i++) + { + p = eina_list_nth(l, i); + fail_if(*p != data[i]); + } + l = eina_list_free(l); + + l = eina_list_filter(list, EINA_FILTER_CB(filter_cb)); + fail_if(eina_list_count(l) != 6); + for (i = 0; i < 6; i++) + { + p = eina_list_nth(l, i); + fail_if(*p != result[i]); + } + l = eina_list_free(l); + + list = eina_list_free(list); + + eina_shutdown(); +} +END_TEST + void eina_test_list(TCase *tc) { @@ -505,4 +548,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); }