forked from enlightenment/efl
Compare commits
8 Commits
master
...
devs/jeyzu
Author | SHA1 | Date |
---|---|---|
Jérémy Zurcher | 813cfcf08f | |
Jérémy Zurcher | 587077ef4b | |
Jérémy Zurcher | 6d2c2d3929 | |
Jérémy Zurcher | 041c4f41df | |
Jérémy Zurcher | 53c02a31ac | |
Jérémy Zurcher | d874570568 | |
Jérémy Zurcher | ab9bb6a2a8 | |
Jérémy Zurcher | 0d9a4e5717 |
|
@ -751,6 +751,64 @@ eina_list_remove_list(Eina_List *list, Eina_List *remove_list)
|
|||
return return_l;
|
||||
}
|
||||
|
||||
EAPI Eina_List *
|
||||
eina_list_remove_duplicates(Eina_List *list, Eina_Bool keep_first)
|
||||
{
|
||||
Eina_List *itr1, *itr2, *itr3;
|
||||
|
||||
if (!list)
|
||||
return NULL;
|
||||
|
||||
EINA_MAGIC_CHECK_LIST(list, NULL);
|
||||
|
||||
if (keep_first)
|
||||
{
|
||||
itr1 = list;
|
||||
while (itr1)
|
||||
{
|
||||
itr2 = itr1->next;
|
||||
|
||||
while (itr2)
|
||||
{
|
||||
itr3 = itr2->next;
|
||||
|
||||
if (itr1->data == itr2->data)
|
||||
{
|
||||
list = eina_list_remove_list(list, itr2);
|
||||
}
|
||||
|
||||
itr2 = itr3;
|
||||
}
|
||||
|
||||
itr1 = itr1->next;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
itr1 = list->accounting->last;
|
||||
while (itr1)
|
||||
{
|
||||
itr2 = itr1->prev;
|
||||
|
||||
while (itr2)
|
||||
{
|
||||
itr3 = itr2->prev;
|
||||
|
||||
if (itr1->data == itr2->data)
|
||||
{
|
||||
list = eina_list_remove_list(list, itr2);
|
||||
}
|
||||
|
||||
itr2 = itr3;
|
||||
}
|
||||
|
||||
itr1 = itr1->prev;
|
||||
}
|
||||
}
|
||||
|
||||
return list;
|
||||
}
|
||||
|
||||
EAPI Eina_List *
|
||||
eina_list_free(Eina_List *list)
|
||||
{
|
||||
|
@ -1095,6 +1153,93 @@ 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_map(Eina_List *list, Eina_Map_Cb func)
|
||||
{
|
||||
const Eina_List *l;
|
||||
void *data;
|
||||
|
||||
if (!list)
|
||||
return NULL;
|
||||
|
||||
EINA_MAGIC_CHECK_LIST(list, NULL);
|
||||
|
||||
if (func)
|
||||
EINA_LIST_FOREACH(list, l, data)
|
||||
func(data);
|
||||
|
||||
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)
|
||||
EINA_LIST_FOREACH(list, l, data)
|
||||
func(data, acc);
|
||||
|
||||
return list;
|
||||
}
|
||||
|
||||
EAPI void
|
||||
eina_list_filter_map_reduce(Eina_List *list,
|
||||
Eina_Filter_Cb filter,
|
||||
Eina_Map_Cb map,
|
||||
Eina_Reduce_Cb reduce, void *acc)
|
||||
{
|
||||
const Eina_List *l;
|
||||
void *data;
|
||||
|
||||
if (!list)
|
||||
return;
|
||||
|
||||
EINA_MAGIC_CHECK_LIST(list);
|
||||
|
||||
EINA_LIST_FOREACH(list, l, data)
|
||||
{
|
||||
if ((filter == NULL) || (filter(data) == EINA_TRUE))
|
||||
{
|
||||
if (map)
|
||||
map(data);
|
||||
if (reduce)
|
||||
reduce(data, acc);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
EAPI Eina_List *
|
||||
eina_list_shuffle(Eina_List *list, Eina_Random_Cb func)
|
||||
{
|
||||
|
|
|
@ -619,6 +619,25 @@ EAPI Eina_List *eina_list_remove(Eina_List *list, const void *data) E
|
|||
EAPI Eina_List *eina_list_remove_list(Eina_List *list, Eina_List *remove_list) EINA_ARG_NONNULL(2) EINA_WARN_UNUSED_RESULT;
|
||||
|
||||
|
||||
/**
|
||||
* @brief Remove duplicated list nodes.
|
||||
*
|
||||
* @param list The given linked list.
|
||||
* @param keep_first Keep the first or last occurence
|
||||
* @return A list pointer.
|
||||
*
|
||||
* This function removes multiple node occurences that have the same data.
|
||||
* It keeps the first or last occurence depending of @p keep_first.
|
||||
* If @p list is @c NULL, @c NULL is returned, otherwise a new list pointer
|
||||
* that should be used in place of the one passed to this function.
|
||||
*
|
||||
* @since 1.8
|
||||
*
|
||||
* @warning @p list must be a pointer to the first element of the list.
|
||||
*/
|
||||
EAPI Eina_List *eina_list_remove_duplicates(Eina_List *list, Eina_Bool keep_first) EINA_WARN_UNUSED_RESULT;
|
||||
|
||||
|
||||
/**
|
||||
* @brief Move the specified data to the head of the list.
|
||||
*
|
||||
|
@ -920,6 +939,68 @@ 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 Apply a function on all nodes of list
|
||||
*
|
||||
* @param list The list to apply function on.
|
||||
* @param func The function to apply on nodes.
|
||||
* @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_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 EINA_ARG_NONNULL(3);
|
||||
|
||||
/**
|
||||
* @brief Apply a filter, then a map then a reduce function on all nodes of list
|
||||
*
|
||||
* @param list The list to filter, map then reduce.
|
||||
* @param filter The filter function.
|
||||
* @param map The reduce function to apply on nodes.
|
||||
* @param reduce The reduce function to apply on nodes.
|
||||
* @param acc The pointer to the accumulator of the reduce function.
|
||||
* @since 1.8
|
||||
*
|
||||
* @see eina_list_filter()
|
||||
* @see eina_list_map()
|
||||
* @see eina_list_reduce()
|
||||
*
|
||||
* @warning @p list must be a pointer to the first element of the list.
|
||||
*/
|
||||
EAPI void eina_list_filter_map_reduce(Eina_List *list, Eina_Filter_Cb filter, Eina_Map_Cb map, Eina_Reduce_Cb reduce, void *acc) EINA_ARG_NONNULL(5);
|
||||
|
||||
/**
|
||||
* @brief Shuffle list.
|
||||
*
|
||||
|
|
|
@ -333,6 +333,44 @@ 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_Map_Cb
|
||||
* Function to be applied on nodes.
|
||||
*/
|
||||
typedef void (*Eina_Map_Cb)(const void *data);
|
||||
|
||||
/**
|
||||
* @def EINA_MAP_CB
|
||||
* Macro to cast to Eina_Map_Cb.
|
||||
*/
|
||||
#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
|
||||
|
|
|
@ -400,14 +400,14 @@ START_TEST(eina_test_shuffle)
|
|||
|
||||
eina_init();
|
||||
|
||||
for(i = 0; i < SHUFFLE_SZ; i++)
|
||||
for (i = 0; i < SHUFFLE_SZ; i++)
|
||||
{
|
||||
n[i] = i;
|
||||
rand_count[i] = 0;
|
||||
list = eina_list_append(list, &n[i]);
|
||||
}
|
||||
|
||||
for(i = 0; i < SHUFFLE_N; i++)
|
||||
for (i = 0; i < SHUFFLE_N; i++)
|
||||
{
|
||||
list = eina_list_shuffle(list, NULL);
|
||||
p = eina_list_nth(list, SHUFFLE_SZ/2);
|
||||
|
@ -425,7 +425,7 @@ START_TEST(eina_test_shuffle)
|
|||
}
|
||||
|
||||
d = SHUFFLE_SZ/(float)(SHUFFLE_N);
|
||||
for(i = 0; i < SHUFFLE_SZ; i++)
|
||||
for (i = 0; i < SHUFFLE_SZ; i++)
|
||||
{
|
||||
fail_if(rand_count[i]*d > 1.20f);
|
||||
fail_if(rand_count[i]*d < 0.80f);
|
||||
|
@ -435,6 +435,154 @@ START_TEST(eina_test_shuffle)
|
|||
}
|
||||
END_TEST
|
||||
|
||||
START_TEST(eina_test_remove_duplicates)
|
||||
{
|
||||
int i;
|
||||
int *p;
|
||||
int data[] = { 0, 1, 2, 3, 4, 5, 6 };
|
||||
int result1[] = { 0, 1, 2, 3, 4, 5, 6 };
|
||||
int result2[] = {2, 3, 4, 1, 6, 5, 0};
|
||||
Eina_List *list = NULL;
|
||||
|
||||
eina_init();
|
||||
|
||||
list = eina_list_append(list, &data[0]);
|
||||
list = eina_list_append(list, &data[1]);
|
||||
list = eina_list_append(list, &data[1]);
|
||||
list = eina_list_append(list, &data[2]);
|
||||
list = eina_list_append(list, &data[3]);
|
||||
list = eina_list_append(list, &data[4]);
|
||||
list = eina_list_append(list, &data[1]);
|
||||
list = eina_list_append(list, &data[5]);
|
||||
list = eina_list_append(list, &data[6]);
|
||||
list = eina_list_append(list, &data[5]);
|
||||
list = eina_list_append(list, &data[0]);
|
||||
list = eina_list_append(list, &data[0]);
|
||||
fail_if(eina_list_count(list) != 12);
|
||||
|
||||
list = eina_list_remove_duplicates(list, EINA_TRUE);
|
||||
fail_if(eina_list_count(list) != 7);
|
||||
for (i = 0; i < 7; i++)
|
||||
{
|
||||
p = eina_list_nth(list, i);
|
||||
fail_if(*p != result1[i]);
|
||||
}
|
||||
list = eina_list_free(list);
|
||||
|
||||
list = eina_list_append(list, &data[0]);
|
||||
list = eina_list_append(list, &data[1]);
|
||||
list = eina_list_append(list, &data[1]);
|
||||
list = eina_list_append(list, &data[2]);
|
||||
list = eina_list_append(list, &data[3]);
|
||||
list = eina_list_append(list, &data[4]);
|
||||
list = eina_list_append(list, &data[1]);
|
||||
list = eina_list_append(list, &data[5]);
|
||||
list = eina_list_append(list, &data[6]);
|
||||
list = eina_list_append(list, &data[5]);
|
||||
list = eina_list_append(list, &data[0]);
|
||||
list = eina_list_append(list, &data[0]);
|
||||
fail_if(eina_list_count(list) != 12);
|
||||
|
||||
list = eina_list_remove_duplicates(list, EINA_FALSE);
|
||||
fail_if(eina_list_count(list) != 7);
|
||||
for (i = 0; i < 7; i++)
|
||||
{
|
||||
p = eina_list_nth(list, i);
|
||||
fail_if(*p != result2[i]);
|
||||
}
|
||||
list = eina_list_free(list);
|
||||
|
||||
eina_shutdown();
|
||||
}
|
||||
END_TEST
|
||||
|
||||
static Eina_Bool filter_cb(int *data)
|
||||
{
|
||||
return ( (*data < 81) ? EINA_TRUE : EINA_FALSE );
|
||||
}
|
||||
|
||||
static void map_cb(int *data)
|
||||
{
|
||||
*data = *data * 3;
|
||||
}
|
||||
|
||||
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 };
|
||||
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 != result1[i]);
|
||||
}
|
||||
|
||||
l = eina_list_map(l, EINA_MAP_CB(map_cb));
|
||||
fail_if(eina_list_count(l) != 6);
|
||||
for (i = 0; i < 6; i++)
|
||||
{
|
||||
p = eina_list_nth(l, i);
|
||||
fail_if(*p != result2[i]);
|
||||
}
|
||||
|
||||
sum = 0;
|
||||
l = eina_list_reduce(l, EINA_REDUCE_CB(reduce_cb), &sum);
|
||||
fail_if(sum != 666);
|
||||
|
||||
l = eina_list_free(l);
|
||||
|
||||
|
||||
sum = 0;
|
||||
l = eina_list_clone(list);
|
||||
eina_list_filter_map_reduce(l,
|
||||
EINA_FILTER_CB(filter_cb),
|
||||
EINA_MAP_CB(map_cb),
|
||||
EINA_REDUCE_CB(reduce_cb), &sum);
|
||||
l = eina_list_free(l);
|
||||
fail_if(sum != 864);
|
||||
|
||||
sum = 0;
|
||||
l = eina_list_clone(list);
|
||||
eina_list_filter_map_reduce(l,
|
||||
NULL,
|
||||
EINA_MAP_CB(map_cb),
|
||||
EINA_REDUCE_CB(reduce_cb), &sum);
|
||||
l = eina_list_free(l);
|
||||
fail_if(sum != 32301);
|
||||
|
||||
list = eina_list_free(list);
|
||||
|
||||
eina_shutdown();
|
||||
}
|
||||
END_TEST
|
||||
|
||||
void
|
||||
eina_test_list(TCase *tc)
|
||||
{
|
||||
|
@ -443,4 +591,6 @@ eina_test_list(TCase *tc)
|
|||
tcase_add_test(tc, eina_test_sorted_insert);
|
||||
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_map_reduce);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue