Tizen Native API  6.5
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 {
     EINA_INLIST;
     int a, b;
};

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

eina_inlist-node_eg2-my-struct.png

Now we need some pointers and auxiliary 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;

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);
     }

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:

eina_inlist-node_eg2-list-inlist.png

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));

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));

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):

   eina_list_free(list);

   while (inlist)
     {
        struct my_struct *aux = EINA_INLIST_CONTAINER_GET(inlist,
                                                          struct my_struct);
        inlist = eina_inlist_remove(inlist, inlist);
        free(aux);
     }

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