Inline List
[Containers]
These functions provide inline list management. More...
Data Structures | |
struct | _Eina_Inlist |
Inlined list type. More... | |
Defines | |
#define | EINA_INLIST Eina_Inlist __in_list |
Used for declaring an inlist member in a struct. | |
#define | EINA_INLIST_GET(Inlist) (& ((Inlist)->__in_list)) |
Utility macro to get the inlist object of a struct. | |
#define | EINA_INLIST_CONTAINER_GET(ptr,type) |
Utility macro to get the container object of an inlist. | |
#define | _EINA_INLIST_OFFSET(ref) ((char *)&(ref)->__in_list - (char *)(ref)) |
#define | _EINA_INLIST_CONTAINER(ref, ptr) |
#define | EINA_INLIST_FOREACH(list, l) |
#define | EINA_INLIST_REVERSE_FOREACH(list, l) |
Typedefs | |
typedef struct _Eina_Inlist | Eina_Inlist |
Inlined list type. | |
Functions | |
Eina_Inlist * | eina_inlist_append (Eina_Inlist *list, Eina_Inlist *new_l) |
Add a new node to end of a list. | |
Eina_Inlist * | eina_inlist_prepend (Eina_Inlist *list, Eina_Inlist *new_l) |
Add a new node to beginning of list. | |
Eina_Inlist * | eina_inlist_append_relative (Eina_Inlist *list, Eina_Inlist *new_l, Eina_Inlist *relative) |
Add a new node after the given relative item in list. | |
Eina_Inlist * | eina_inlist_prepend_relative (Eina_Inlist *list, Eina_Inlist *new_l, Eina_Inlist *relative) |
Add a new node before the given relative item in list. | |
Eina_Inlist * | eina_inlist_remove (Eina_Inlist *list, Eina_Inlist *item) |
Remove node from list. | |
Eina_Inlist * | eina_inlist_find (Eina_Inlist *list, Eina_Inlist *item) |
Find given node in list, returns itself if found, NULL if not. | |
Eina_Inlist * | eina_inlist_promote (Eina_Inlist *list, Eina_Inlist *item) |
Move existing node to beginning of list. | |
Eina_Inlist * | eina_inlist_demote (Eina_Inlist *list, Eina_Inlist *item) |
Move existing node to end of list. | |
unsigned int | eina_inlist_count (const Eina_Inlist *list) |
Get the count of the number of items in a list. | |
Eina_Iterator * | eina_inlist_iterator_new (const Eina_Inlist *list) |
Returns a new iterator associated to list. | |
Eina_Accessor * | eina_inlist_accessor_new (const Eina_Inlist *list) |
Returns a new accessor associated to a list. |
Detailed Description
These functions provide inline list management.
Inline lists mean its nodes pointers are part of same memory as data. This has the benefit of fragmenting memory less and avoiding node->data
indirection, but has the drawback of elements only being able to be part of one single inlist at same time. But it is possible to have inlist nodes to be part of regular lists created with eina_list_append() or eina_list_prepend().
Inline lists have their purposes, but if you don't know what those purposes are, go with regular lists instead.
#include <Eina.h> #include <stdio.h> int main(void) { struct my_struct { EINA_INLIST; int a, b; } *d, *cur; Eina_Inlist *list, *itr; eina_init(); d = malloc(sizeof(*d)); d->a = 1; d->b = 10; list = eina_inlist_append(NULL, EINA_INLIST_GET(d)); d = malloc(sizeof(*d)); d->a = 2; d->b = 20; list = eina_inlist_append(list, EINA_INLIST_GET(d)); d = malloc(sizeof(*d)); d->a = 3; d->b = 30; list = eina_inlist_prepend(list, EINA_INLIST_GET(d)); printf("list=%p\n", list); EINA_INLIST_FOREACH(list, cur) printf("\ta=%d, b=%d\n", cur->a, cur->b); list = eina_inlist_remove(list, EINA_INLIST_GET(d)); free(d); printf("list=%p\n", list); for (itr = list; itr != NULL; itr = itr->next) { cur = EINA_INLIST_CONTAINER_GET(itr, struct my_struct); printf("\ta=%d, b=%d\n", cur->a, cur->b); } while (list) { Eina_Inlist *aux = list; list = eina_inlist_remove(list, list); free(aux); } eina_shutdown(); return 0; }
Define Documentation
#define EINA_INLIST_CONTAINER_GET | ( | ptr, | |||
type | ) |
((type *)((char *)ptr - \
offsetof(type, __in_list)))
Utility macro to get the container object of an inlist.
#define _EINA_INLIST_CONTAINER | ( | ref, | |||
ptr | ) |
(void *)((char *)(ptr) - \ _EINA_INLIST_OFFSET(ref))
#define EINA_INLIST_FOREACH | ( | list, | |||
l | ) |
for (l = NULL, l = (list ? _EINA_INLIST_CONTAINER(l, list) : NULL); l; \ l = (EINA_INLIST_GET(l)->next ? _EINA_INLIST_CONTAINER(l, EINA_INLIST_GET(l)->next) : NULL))
#define EINA_INLIST_REVERSE_FOREACH | ( | list, | |||
l | ) |
for (l = NULL, l = (list ? _EINA_INLIST_CONTAINER(l, list->last) : NULL); \ l; l = (EINA_INLIST_GET(l)->prev ? _EINA_INLIST_CONTAINER(l, EINA_INLIST_GET(l)->prev) : NULL))
Function Documentation
Eina_Inlist * eina_inlist_append | ( | Eina_Inlist * | list, | |
Eina_Inlist * | new_l | |||
) |
Add a new node to end of a list.
- Note:
- this code is meant to be fast: appends are O(1) and do not walk list.
- new_l is considered to be in no list. If it was in another list before, eina_inlist_remove() it before adding. No check of new_l prev and next pointers is done, so it's safe to have them uninitialized.
- Parameters:
-
list existing list head or NULL to create a new list. new_l new list node, must not be NULL.
- Returns:
- the new list head. Use it and not list anymore.
Eina_Inlist * eina_inlist_prepend | ( | Eina_Inlist * | list, | |
Eina_Inlist * | new_l | |||
) |
Add a new node to beginning of list.
- Note:
- this code is meant to be fast: appends are O(1) and do not walk list.
- new_l is considered to be in no list. If it was in another list before, eina_inlist_remove() it before adding. No check of new_l prev and next pointers is done, so it's safe to have them uninitialized.
- Parameters:
-
list existing list head or NULL to create a new list. new_l new list node, must not be NULL.
- Returns:
- the new list head. Use it and not list anymore.
Eina_Inlist * eina_inlist_append_relative | ( | Eina_Inlist * | list, | |
Eina_Inlist * | new_l, | |||
Eina_Inlist * | relative | |||
) |
Add a new node after the given relative item in list.
- Note:
- this code is meant to be fast: appends are O(1) and do not walk list.
- new_l is considered to be in no list. If it was in another list before, eina_inlist_remove() it before adding. No check of new_l prev and next pointers is done, so it's safe to have them uninitialized.
- relative is considered to be inside list, no checks are done to confirm that and giving nodes from different lists will lead to problems. Giving NULL relative is the same as eina_list_append().
- Parameters:
-
list existing list head or NULL to create a new list. new_l new list node, must not be NULL. relative reference node, new_l will be added after it.
- Returns:
- the new list head. Use it and not list anymore.
Eina_Inlist * eina_inlist_prepend_relative | ( | Eina_Inlist * | list, | |
Eina_Inlist * | new_l, | |||
Eina_Inlist * | relative | |||
) |
Add a new node before the given relative item in list.
- Note:
- this code is meant to be fast: appends are O(1) and do not walk list.
- new_l is considered to be in no list. If it was in another list before, eina_inlist_remove() it before adding. No check of new_l prev and next pointers is done, so it's safe to have them uninitialized.
- relative is considered to be inside list, no checks are done to confirm that and giving nodes from different lists will lead to problems. Giving NULL relative is the same as eina_list_prepend().
- Parameters:
-
list existing list head or NULL to create a new list. new_l new list node, must not be NULL. relative reference node, new_l will be added before it.
- Returns:
- the new list head. Use it and not list anymore.
Eina_Inlist * eina_inlist_remove | ( | Eina_Inlist * | list, | |
Eina_Inlist * | item | |||
) |
Remove node from list.
- Note:
- this code is meant to be fast: appends are O(1) and do not walk list.
- item is considered to be inside list, no checks are done to confirm that and giving nodes from different lists will lead to problems, especially if item is the head since it will be different from list and the wrong new head will be returned.
- Parameters:
-
list existing list head, must not be NULL. item existing list node, must not be NULL.
- Returns:
- the new list head. Use it and not list anymore.
Eina_Inlist * eina_inlist_find | ( | Eina_Inlist * | list, | |
Eina_Inlist * | item | |||
) |
Find given node in list, returns itself if found, NULL if not.
- Warning:
- this is an expensive call and has O(n) cost, possibly walking the whole list.
- Parameters:
-
list existing list to search item in, must not be NULL. item what to search for, must not be NULL.
- Returns:
- item if found, NULL if not.
Eina_Inlist * eina_inlist_promote | ( | Eina_Inlist * | list, | |
Eina_Inlist * | item | |||
) |
Move existing node to beginning of list.
- Note:
- this code is meant to be fast: appends are O(1) and do not walk list.
- item is considered to be inside list. No checks are done to confirm this, and giving nodes from different lists will lead to problems.
- Parameters:
-
list existing list head or NULL to create a new list. item list node to move to beginning (head), must not be NULL.
- Returns:
- the new list head. Use it and not list anymore.
Eina_Inlist * eina_inlist_demote | ( | Eina_Inlist * | list, | |
Eina_Inlist * | item | |||
) |
Move existing node to end of list.
- Note:
- this code is meant to be fast: appends are O(1) and do not walk list.
- item is considered to be inside list. No checks are done to confirm this, and giving nodes from different lists will lead to problems.
- Parameters:
-
list existing list head or NULL to create a new list. item list node to move to end (tail), must not be NULL.
- Returns:
- the new list head. Use it and not list anymore.
unsigned int eina_inlist_count | ( | const Eina_Inlist * | list | ) |
Get the count of the number of items in a list.
- Parameters:
-
list The list whose count to return.
- Returns:
- The number of members in the list.
This function returns how many members list
contains. If the list is NULL
, 0 is returned.
- Warning:
- This is an order-N operation and so the time will depend on the number of elements on the list, so, it might become slow for big lists!
Eina_Iterator * eina_inlist_iterator_new | ( | const Eina_Inlist * | list | ) |
Returns a new iterator associated to list.
- Parameters:
-
list The list.
- Returns:
- A new iterator.
This function returns a newly allocated iterator associated to list
. If list
is NULL
or the count member of list
is less or equal than 0, this function still returns a valid iterator that will always return false on eina_iterator_next(), thus keeping API sane.
If the memory can not be allocated, NULL is returned and EINA_ERROR_OUT_OF_MEMORY is set. Otherwise, a valid iterator is returned.
- Warning:
- if the list structure changes then the iterator becomes invalid, and if you add or remove nodes iterator behavior is undefined, and your program may crash!
Eina_Accessor * eina_inlist_accessor_new | ( | const Eina_Inlist * | list | ) |
Returns a new accessor associated to a list.
- Parameters:
-
list The list.
- Returns:
- A new accessor.
This function returns a newly allocated accessor associated to list
. If list
is NULL
or the count member of list
is less or equal than 0, this function returns NULL. If the memory can not be allocated, NULL is returned and EINA_ERROR_OUT_OF_MEMORY is set. Otherwise, a valid accessor is returned.