summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJérémy Zurcher <jeremy@asynk.ch>2013-06-12 17:52:06 +0200
committerJérémy Zurcher <jeremy@asynk.ch>2013-06-12 17:52:06 +0200
commitd87457056803309c8263177dd27ad6f803d92684 (patch)
tree41b80784a094f3e7dcf25c08b283c1d295683bef
parentab9bb6a2a83d3ab933ff5e0a26f54f4f9c96518f (diff)
downloadefl-d87457056803309c8263177dd27ad6f803d92684.tar.gz
add EAPI eina_list_filter(Eina_List *list, Eina_Filter_Cb func)
- eina_list_filter returns a new list - typedef Eina_Bool (*Eina_Filter_Cb)(const void *data); - returns EINA_TRUE if satisfies the predicate
-rw-r--r--src/lib/eina/eina_list.c25
-rw-r--r--src/lib/eina/eina_list.h19
-rw-r--r--src/lib/eina/eina_types.h14
-rw-r--r--src/tests/eina/eina_test_list.c44
4 files changed, 102 insertions, 0 deletions
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
@@ -1154,6 +1154,31 @@ eina_list_sort(Eina_List *list, unsigned int limit, Eina_Compare_Cb func)
}
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)
{
unsigned int n, i, j;
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
@@ -940,6 +940,25 @@ EAPI Eina_List *eina_list_sort(Eina_List *list, unsigned int limit, E
/**
+ * @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.
*
* @param list The list handle to shuffle.
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
@@ -334,6 +334,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
* inclusive must be returned.
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);
}