Eina_Inlist advanced usage - lists and inlists

This example describes the usage of Eina_Inlist mixed with Eina_List . We create and add elements to an inlist, and the even members are also added to a normal list. Later we remove the elements divisible by 3 from this normal list.

The struct that is going to be used is the same used in Eina_Inlist basic usage , since we still need the EINA_INLIST macro to declare the inlist node info:

struct my_struct {
int a, b;
};
#define EINA_INLIST
Used for declaring an inlist member in a struct.
Definition eina_inlist.h:413

The resulting node representing this struct can be exemplified by the following picture:

Now we need some pointers and auxiliar variables that will help us iterate on the lists:

struct my_struct *d, *cur;
int i;
Eina_Inlist *inlist = NULL;
Eina_List *list = NULL, *l_itr, *l_next;
Inlined list type.
Definition eina_inlist.h:407
Type for a generic double linked list.
Definition eina_list.h:321

Allocating 100 elements and putting them into an inlist, and the even elements also go to the normal list:

for (i = 0; i < 100; i++)
{
d = malloc(sizeof(*d));
d->a = i;
d->b = i * 10;
inlist = eina_inlist_append(inlist, EINA_INLIST_GET(d));
if ((i % 2) == 0)
list = eina_list_prepend(list, d);
}
Eina_Inlist * eina_inlist_append(Eina_Inlist *in_list, Eina_Inlist *in_item)
Add a new node to end of a list.
Definition eina_inlist.c:222
#define EINA_INLIST_GET(Inlist)
Utility macro to get the inlist object of a struct.
Definition eina_inlist.h:415
Eina_List * eina_list_prepend(Eina_List *list, const void *data)
Prepends the given data to the given linked list.
Definition eina_list.c:560

After this point, what we have are two distinct lists that share some elements. The first list (inlist) is defined by the pointers inside the elements data structure, while the second list (normal list) has its own node data structure that is kept outside of the elements.

The two lists, sharing some elements, can be represented by the following picture:

Accessing both lists is done normally, as if they didn't have any elements in common:

printf("inlist=%p\n", inlist);
EINA_INLIST_FOREACH(inlist, cur)
printf("\ta=%d, b=%d\n", cur->a, cur->b);
printf("list=%p\n", list);
EINA_LIST_FOREACH(list, l_itr, cur)
printf("\ta=%d, b=%d\n", cur->a, cur->b);
printf("inlist count=%d\n", eina_inlist_count(inlist));
printf("list count=%d\n\n", eina_list_count(list));
unsigned int eina_inlist_count(const Eina_Inlist *list)
Get the count of the number of items in a list.
Definition eina_inlist.c:443
#define EINA_INLIST_FOREACH(list, l)
Macro to iterate over an inlist.
Definition eina_inlist.h:794
static unsigned int eina_list_count(const Eina_List *list)
Get the count of the number of items in a list.
#define EINA_LIST_FOREACH(list, l, data)
Macro to iterate over a list.
Definition eina_list.h:1399

We can remove elements from the normal list, but we just don't free them because they are still stored in the inlist:

EINA_LIST_FOREACH_SAFE(list, l_itr, l_next, cur)
{
if ((cur->a % 3) == 0)
list = eina_list_remove_list(list, l_itr);
}
printf("inlist count=%d\n", eina_inlist_count(inlist));
printf("list count=%d\n\n", eina_list_count(list));
#define EINA_LIST_FOREACH_SAFE(list, l, l_next, data)
Macro to iterate over a list with support for node deletion.
Definition eina_list.h:1509
Eina_List * eina_list_remove_list(Eina_List *list, Eina_List *remove_list)
Remove the specified list node.
Definition eina_list.c:720

To finish this example, we want to free both lists, we can't just free all elements on the second list (normal list) because they are still being used in the inlist. So we first discard the normal list without freeing its elements, then we free all elements in the inlist (that contains all elements allocated until now):

while (inlist)
{
struct my_struct *aux = EINA_INLIST_CONTAINER_GET(inlist,
struct my_struct);
inlist = eina_inlist_remove(inlist, inlist);
free(aux);
}
#define EINA_INLIST_CONTAINER_GET(ptr, type)
Utility macro to get the container object of an inlist.
Definition eina_inlist.h:417
Eina_Inlist * eina_inlist_remove(Eina_Inlist *in_list, Eina_Inlist *in_item)
Remove node from list.
Definition eina_inlist.c:330
Eina_List * eina_list_free(Eina_List *list)
Free an entire list and all the nodes, ignoring the data contained.
Definition eina_list.c:754

Here is the full source code for this example: eina_inlist_02.c Eina_Inlist advanced usage - lists and inlists source