Inline List

- Main Page
- Related Pages
- Modules
- Data Structures
- Files
- Examples

Data Structures | Macros | Typedefs | Functions
Inline List
Eina » Data Types » Containers

These functions provide inline list management. More...

## Data Structures
struct | _Eina_Inlist
| Inlined list type. More...

## Macros
#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, it)
#define | EINA_INLIST_FOREACH_SAFE(list, list2, it)
#define | EINA_INLIST_REVERSE_FOREACH(list, it)
#define | EINA_INLIST_REVERSE_FOREACH_FROM(list, it)
#define | EINA_INLIST_FREE(list, it) for (it = (__typeof__(it)) list; list; it = (__typeof__(it)) list)

## Typedefs
typedef struct _Eina_Inlist | Eina_Inlist
| Inlined list type.
typedef struct _Eina_Inlist_Sorted_State | Eina_Inlist_Sorted_State

## Functions
EINA_API Eina_Inlist * | eina_inlist_append (Eina_Inlist *in_list, Eina_Inlist *in_item)
| Adds a new node to end of a list.
EINA_API Eina_Inlist * | eina_inlist_prepend (Eina_Inlist *in_list, Eina_Inlist *in_item)
| Adds a new node to beginning of list.
EINA_API Eina_Inlist * | eina_inlist_append_relative (Eina_Inlist *in_list, Eina_Inlist *in_item, Eina_Inlist *in_relative)
| Adds a new node after the given relative item in list.
EINA_API Eina_Inlist * | eina_inlist_prepend_relative (Eina_Inlist *in_list, Eina_Inlist *in_item, Eina_Inlist *in_relative)
| Adds a new node before the given relative item in list.
EINA_API Eina_Inlist * | eina_inlist_remove (Eina_Inlist *in_list, Eina_Inlist *in_item)
| Removes node from list.
EINA_API Eina_Inlist * | eina_inlist_find (Eina_Inlist *in_list, Eina_Inlist *in_item)
| Finds given node in list, returns itself if found, NULL if not.
EINA_API Eina_Inlist * | eina_inlist_promote (Eina_Inlist *list, Eina_Inlist *item)
| Moves existing node to beginning of list.
EINA_API Eina_Inlist * | eina_inlist_demote (Eina_Inlist *list, Eina_Inlist *item)
| Moves existing node to end of list.
static Eina_Inlist * | eina_inlist_first (const Eina_Inlist *list)
| Gets the first list node in the list.
static Eina_Inlist * | eina_inlist_last (const Eina_Inlist *list)
| Gets the last list node in the list.
EINA_API unsigned int | eina_inlist_count (const Eina_Inlist *list)
| Gets the count of the number of items in a list.
EINA_API Eina_Iterator * | eina_inlist_iterator_new (const Eina_Inlist *in_list)
| Returns a new iterator associated to list.
EINA_API Eina_Accessor * | eina_inlist_accessor_new (const Eina_Inlist *in_list)
| Returns a new accessor associated to a list.
EINA_API Eina_Inlist * | eina_inlist_sorted_insert (Eina_Inlist *list, Eina_Inlist *item, Eina_Compare_Cb func)
| Inserts a new node into a sorted list.
EINA_API Eina_Inlist_Sorted_State * | eina_inlist_sorted_state_new (void)
| Creates state with valid data in it.
EINA_API int | eina_inlist_sorted_state_init (Eina_Inlist_Sorted_State *state, Eina_Inlist *list)
| Forces an Eina_Inlist_Sorted_State to match the content of a list.
EINA_API void | eina_inlist_sorted_state_free (Eina_Inlist_Sorted_State *state)
| Frees an Eina_Inlist_Sorted_State.
EINA_API Eina_Inlist * | eina_inlist_sorted_state_insert (Eina_Inlist *list, Eina_Inlist *item, Eina_Compare_Cb func, Eina_Inlist_Sorted_State *state)
| Inserts a new node into a sorted list.
EINA_API Eina_Inlist * | eina_inlist_sort (Eina_Inlist *head, Eina_Compare_Cb func)
| Sorts a list according to the ordering func will return.

## 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 higher cost for some common operations like count and sort.

It is possible to have inlist nodes to be part of regular lists, created with eina_list_append() or eina_list_prepend(). It's also possible to have a structure with two inlist pointers, thus be part of two different inlists at the same time, but the current convenience macros provided won't work for both of them. Consult Advanced Usage for more info.

Inline lists have their purposes, but if you don't know what those purposes are, go with regular lists instead.

Tip: When using inlists in more than one place (that is, passing them around functions or keeping a pointer to them in a structure) it's more correct to keep a pointer to the first container, and not a pointer to the first inlist item (mostly they are the same, but that's not always correct). This lets the compiler to do type checking and let the programmer know exactly what type this list is.

A simple example demonstrating the basic usage of an inlist can be found here: Eina_Inlist basic usage

# Algorithm

The basic structure can be represented by the following picture:

One data structure will also have the node information, with three pointers: prev, next and last. The last pointer is just valid for the first element (the list head), otherwise each insertion in the list would have to be done updating every node with the correct pointer. This means that it's always very important to keep a pointer to the first element of the list, since it is the only one that has the correct information to allow a proper O(1) append to the list.

# Performance

Due to the nature of the inlist, there's no accounting information, and no easy access to the last element from each list node. This means that eina_inlist_count() is order-N, while eina_list_count() is order-1 (constant time).

# Advanced Usage

The basic usage considers a struct that will have the user data, and also have an inlist node information (prev, next and last pointers) created with EINA_INLIST during the struct declaration. This allows one to use the convenience macros EINA_INLIST_GET(), EINA_INLIST_CONTAINER_GET(), EINA_INLIST_FOREACH() and so. This happens because the EINA_INLIST macro declares a struct member with the name __inlist, and all the other macros assume that this struct member has this name.

It may be the case that someone needs to have some inlist nodes added to a Eina_List too. If this happens, the inlist nodes can be added to the Eina_List without any problems. This example demonstrates this case: Eina_Inlist advanced usage - lists and inlists

It's also possible to have some data that is part of two different inlists. If this is the case, then it won't be possible to use the convenience macros to both of the lists. It will be necessary to create a new set of macros that will allow access to the second list node info. An example for this usage can be found here: Eina_Inlist advanced usage - multi-inlists

List of examples:

- Eina_Inlist basic usage
- Eina_Inlist advanced usage - lists and inlists
- Eina_Inlist advanced usage - multi-inlists

## Macro Definition Documentation

## ◆ EINA_INLIST_CONTAINER_GET

#define EINA_INLIST_CONTAINER_GET | ( |  | ptr,
|  |  | type
| ) |  |

Value:
((type *)(void *)((char *)ptr - \
offsetof(type, __in_list)))

Utility macro to get the container object of an inlist.

Examples
  eina_inlist_01.c, eina_inlist_02.c, and eina_inlist_03.c.

## ◆ _EINA_INLIST_OFFSET

#define _EINA_INLIST_OFFSET | ( |  | ref | ) | ((char *)&(ref)->__in_list - (char *)(ref))

Parameters

  [in,out] | ref | The reference to be used.

## ◆ _EINA_INLIST_CONTAINER

#define _EINA_INLIST_CONTAINER | ( |  | ref,
|  |  | ptr
| ) |  |

Value:
(void *)((char *)(ptr) - \
_EINA_INLIST_OFFSET(ref))
_EINA_INLIST_OFFSET
#define _EINA_INLIST_OFFSET(ref)
Definition: eina_inlist.h:807

Parameters

  [in,out] | ref | The reference to be used.
  [out] | ptr | The pointer to be used.

## ◆ EINA_INLIST_FOREACH

#define EINA_INLIST_FOREACH | ( |  | list,
|  |  | it
| ) |  |

Value:
for (it = NULL, it = (list ? _EINA_INLIST_CONTAINER(it, list) : NULL); it; \
it = (EINA_INLIST_GET(it)->next ? _EINA_INLIST_CONTAINER(it, EINA_INLIST_GET(it)->next) : NULL))
_EINA_INLIST_CONTAINER
#define _EINA_INLIST_CONTAINER(ref, ptr)
Definition: eina_inlist.h:815
EINA_INLIST_GET
#define EINA_INLIST_GET(Inlist)
Utility macro to get the inlist object of a struct.
Definition: eina_inlist.h:413

Parameters

  [in,out] | list | The list to iterate on.
  [out] | it | The pointer to the list item, i.e. a pointer to each item that is part of the list.

Examples
  eina_inlist_01.c, eina_inlist_02.c, and eina_inlist_03.c.

## ◆ EINA_INLIST_FOREACH_SAFE

#define EINA_INLIST_FOREACH_SAFE | ( |  | list,
|  |  | list2,
|  |  | it
| ) |  |

Value:
for (it = NULL, it = (list ? _EINA_INLIST_CONTAINER(it, list) : NULL), list2 = it ? EINA_INLIST_GET(it)->next : NULL; \
it; \
it = NULL, it = list2 ? _EINA_INLIST_CONTAINER(it, list2) : NULL, list2 = list2 ? list2->next : NULL)

Parameters

  [in,out] | list | The list to iterate on.
  [out] | list2 | Auxiliary Eina_Inlist variable so we can save the pointer to the next element, allowing us to free/remove the current one. Note that this macro is only safe if the next element is not removed. Only the current one is allowed to be removed.
  [out] | it | The pointer to the list item, i.e. a pointer to each item that is part of the list.

## ◆ EINA_INLIST_REVERSE_FOREACH

#define EINA_INLIST_REVERSE_FOREACH | ( |  | list,
|  |  | it
| ) |  |

Value:
for (it = NULL, it = (list ? _EINA_INLIST_CONTAINER(it, list->last) : NULL); \
it; it = (EINA_INLIST_GET(it)->prev ? _EINA_INLIST_CONTAINER(it, EINA_INLIST_GET(it)->prev) : NULL))

Parameters

  [in,out] | list | The list to traverse in reverse order.
  [out] | it | The pointer to the list item, i.e. a pointer to each item that is part of the list.

## ◆ EINA_INLIST_REVERSE_FOREACH_FROM

#define EINA_INLIST_REVERSE_FOREACH_FROM | ( |  | list,
|  |  | it
| ) |  |

Value:
for (it = NULL, it = (list ? _EINA_INLIST_CONTAINER(it, list) : NULL); \
it; it = (EINA_INLIST_GET(it)->prev ? _EINA_INLIST_CONTAINER(it, EINA_INLIST_GET(it)->prev) : NULL))

Parameters

  [in,out] | list | The last list to traverse in reverse order.
  [in] | it | The pointer to the list item, i.e. a pointer to each item that is part of the list.

See also
  EINA_INLIST_REVERSE_FOREACH()

Since
  1.8

EINA_INLIST_REVERSE_FOREACH() starts from last list of the given list. This starts from given list, not the last one.

## ◆ EINA_INLIST_FREE

#define EINA_INLIST_FREE | ( |  | list,
|  |  | it
| ) |  | for (it = (__typeof__(it)) list; list; it = (__typeof__(it)) list)

Parameters

  [in,out] | list | The list to free.
  [in] | it | The pointer to the list item, i.e. a pointer to each item that is part of the list.

NOTE: it is the duty of the body loop to properly remove the item from the inlist and free it. This function will turn into a infinite loop if you don't remove all items from the list.

Since
  1.8

## Typedef Documentation

## ◆ Eina_Inlist_Sorted_State

Eina_Inlist_Sorted_State

Since
  1.1.0 State of sorted Eina_Inlist

## Function Documentation

## ◆ eina_inlist_append()

EINA_API Eina_Inlist * eina_inlist_append | ( | Eina_Inlist * | in_list,
|  | Eina_Inlist * | in_item
| ) |  |

Adds a new node to end of a list.

Note
  This code is meant to be fast: appends are O(1) and do not walk in_list.
  in_item 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

  [in,out] | in_list | Existing list head or `NULL` to create a new list.
  [in] | in_item | New list node, must not be `NULL`.

Returns
  The new list head. Use it and not in_list anymore.

References EINA_SAFETY_ON_NULL_RETURN_VAL, _Eina_Inlist::last, _Eina_Inlist::next, and _Eina_Inlist::prev.

Referenced by ecore_buffer_free_callback_add(), ecore_wl2_subsurface_new(), ecore_wl2_window_frame_callback_add(), ecore_wl2_window_new(), ecore_wl_subsurf_create(), ecore_x_input_multi_select(), eeze_udev_watch_add(), eina_benchmark_register(), eina_inlist_append_relative(), eina_inlist_sorted_insert(), eina_inlist_sorted_state_insert(), eina_log_domain_level_set(), eina_quadtree_add(), eina_quadtree_change(), eina_simple_xml_attribute_new(), eina_simple_xml_node_tag_new(), eldbus_connection_event_callback_add(), eldbus_message_iter_container_new(), eldbus_message_iter_get_and_next(), eldbus_name_owner_changed_callback_add(), eldbus_object_event_callback_add(), eldbus_object_send(), eldbus_proxy_event_callback_add(), elm_color_class_editor_add(), elm_gesture_layer_tap_longpress_cb_add(), elm_prefs_data_event_callback_add(), elm_transit_effect_add(), evas_event_callback_priority_add(), evas_object_event_callback_priority_add(), evas_object_smart_callback_priority_add(), evas_output_method_set(), and evas_textblock_style_set().

## ◆ eina_inlist_prepend()

EINA_API Eina_Inlist * eina_inlist_prepend | ( | Eina_Inlist * | in_list,
|  | Eina_Inlist * | in_item
| ) |  |

Adds a new node to beginning of list.

Note
  This code is meant to be fast: appends are O(1) and do not walk in_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

  [in,out] | in_list | Existing list head or `NULL` to create a new list.
  [in] | in_item | New list node, must not be `NULL`.

Returns
  The new list head. Use it and not in_list anymore.

References EINA_SAFETY_ON_NULL_RETURN_VAL, _Eina_Inlist::last, _Eina_Inlist::next, and _Eina_Inlist::prev.

Referenced by ecore_poller_add(), ecore_poller_poller_interval_set(), eina_counter_start(), eina_inlist_prepend_relative(), eina_inlist_sorted_insert(), eina_inlist_sorted_state_insert(), and eina_rectangle_pool_request().

## ◆ eina_inlist_append_relative()

EINA_API Eina_Inlist * eina_inlist_append_relative | ( | Eina_Inlist * | in_list,
|  | Eina_Inlist * | in_item,
|  | Eina_Inlist * | in_relative
| ) |  |

Adds 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 in_list.
  in_item_l is considered to be in no list. If it was in another list before, eina_inlist_remove() it before adding. No check of in_item prev and next pointers is done, so it's safe to have them uninitialized.
  in_relative is considered to be inside in_list, no checks are done to confirm that and giving nodes from different lists will lead to problems. Giving NULL in_relative is the same as eina_list_append().

Parameters

  [in,out] | in_list | Existing list head or `NULL` to create a new list.
  [in] | in_item | New list node, must not be `NULL`.
  [in] | in_relative | Reference node, in_item will be added after it.

Returns
  The new list head. Use it and not list anymore.

References eina_inlist_append(), EINA_SAFETY_ON_NULL_RETURN_VAL, _Eina_Inlist::last, _Eina_Inlist::next, and _Eina_Inlist::prev.

Referenced by eina_inlist_sorted_insert(), and eina_inlist_sorted_state_insert().

## ◆ eina_inlist_prepend_relative()

EINA_API Eina_Inlist * eina_inlist_prepend_relative | ( | Eina_Inlist * | in_list,
|  | Eina_Inlist * | in_item,
|  | Eina_Inlist * | in_relative
| ) |  |

Adds 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 in_list.
  in_item is considered to be in no list. If it was in another list before, eina_inlist_remove() it before adding. No check of in_item prev and next pointers is done, so it's safe to have them uninitialized.
  in_relative is considered to be inside in_list, no checks are done to confirm that and giving nodes from different lists will lead to problems. Giving NULL in_relative is the same as eina_list_prepend().

Parameters

  [in,out] | in_list | Existing list head or `NULL` to create a new list.
  [in] | in_item | New list node, must not be `NULL`.
  [in] | in_relative | Reference node, in_item will be added before it.

Returns
  The new list head. Use it and not in_list anymore.

References eina_inlist_prepend(), EINA_SAFETY_ON_NULL_RETURN_VAL, _Eina_Inlist::last, _Eina_Inlist::next, and _Eina_Inlist::prev.

Referenced by eina_inlist_sorted_insert(), and eina_inlist_sorted_state_insert().

## ◆ eina_inlist_remove()

EINA_API Eina_Inlist * eina_inlist_remove | ( | Eina_Inlist * | in_list,
|  | Eina_Inlist * | in_item
| ) |  |

Removes node from list.

Note
  This code is meant to be fast: appends are O(1) and do not walk list.
  in_item is considered to be inside in_list, no checks are done to confirm that and giving nodes from different lists will lead to problems, especially if in_item is the head since it will be different from list and the wrong new head will be returned.

Parameters

  [in,out] | in_list | Existing list head, must not be `NULL`.
  [in] | in_item | Existing list node, must not be `NULL`.

Returns
  The new list head. Use it and not list anymore.

References EINA_LOG_ERR, EINA_SAFETY_ON_NULL_RETURN_VAL, EINA_UNLIKELY, _Eina_Inlist::last, _Eina_Inlist::next, and _Eina_Inlist::prev.

Referenced by ecore_buffer_free(), ecore_buffer_free_callback_remove(), ecore_poller_poller_interval_set(), ecore_wl2_window_frame_callback_del(), ecore_wl2_window_free(), eeze_udev_watch_del(), eina_benchmark_free(), eina_counter_free(), eina_rectangle_pool_release(), eina_simple_xml_attribute_free(), eldbus_name_owner_changed_callback_del(), elm_gesture_layer_tap_longpress_cb_del(), elm_prefs_data_event_callback_del(), elm_store_free(), evas_event_callback_del(), evas_event_callback_del_full(), evas_object_event_callback_del(), evas_object_event_callback_del_full(), evas_object_smart_callback_del(), and evas_object_smart_callback_del_full().

## ◆ eina_inlist_find()

EINA_API Eina_Inlist * eina_inlist_find | ( | Eina_Inlist * | in_list,
|  | Eina_Inlist * | in_item
| ) |  |

Finds 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

  [in] | in_list | Existing list to search in_item in, must not be `NULL`.
  [in] | in_item | What to search for, must not be `NULL`.

Returns
  in_item if found, `NULL` if not.

References EINA_SAFETY_ON_NULL_RETURN_VAL, and _Eina_Inlist::next.

## ◆ eina_inlist_promote()

EINA_API Eina_Inlist * eina_inlist_promote | ( | Eina_Inlist * | list,
|  | Eina_Inlist * | item
| ) |  |

Moves 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

  [in] | list | Existing list head or `NULL` to create a new list.
  [in] | item | List node to move to beginning (head), must not be `NULL`.

Returns
  The new list head. Use it and not list anymore.

References EINA_SAFETY_ON_NULL_RETURN_VAL, _Eina_Inlist::last, _Eina_Inlist::next, and _Eina_Inlist::prev.

## ◆ eina_inlist_demote()

EINA_API Eina_Inlist * eina_inlist_demote | ( | Eina_Inlist * | list,
|  | Eina_Inlist * | item
| ) |  |

Moves 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

  [in] | list | Existing list head or `NULL` to create a new list.
  [in] | item | List node to move to end (tail), must not be `NULL`.

Returns
  The new list head. Use it and not list anymore.

References EINA_SAFETY_ON_NULL_RETURN_VAL, _Eina_Inlist::last, _Eina_Inlist::next, and _Eina_Inlist::prev.

## ◆ eina_inlist_first()

static Eina_Inlist * eina_inlist_first | ( | const Eina_Inlist * | list | ) |
| inlinestatic

Gets the first list node in the list.

Parameters

  [in] | list | The list to get the first list node from.

Returns
  The first list node in the list.

This function returns the first list node in the list `list`. If `list` is `NULL`, `NULL` is returned.

This is a O(N) operation (it takes time proportional to the length of the list).

Since
  1.8

## ◆ eina_inlist_last()

static Eina_Inlist * eina_inlist_last | ( | const Eina_Inlist * | list | ) |
| inlinestatic

Gets the last list node in the list.

Parameters

  [in] | list | The list to get the last list node from.

Returns
  The last list node in the list.

This function returns the last list node in the list `list`. If `list` is `NULL`, `NULL` is returned.

This is a O(N) operation (it takes time proportional to the length of the list).

Since
  1.8

## ◆ eina_inlist_count()

EINA_API unsigned int eina_inlist_count | ( | const Eina_Inlist * | list | ) |

Gets the count of the number of items in a list.

Parameters

  [in] | 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!

References _Eina_Inlist::next.

## ◆ eina_inlist_iterator_new()

EINA_API Eina_Iterator * eina_inlist_iterator_new | ( | const Eina_Inlist * | in_list | ) |

Returns a new iterator associated to list.

Parameters

  [in] | in_list | The list.

Returns
  A new iterator.

This function returns a newly allocated iterator associated to `in_list`. If `in_list` is `NULL` or the count member of `in_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. 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!

References EINA_MAGIC_SET, FUNC_ITERATOR_FREE, FUNC_ITERATOR_GET_CONTAINER, and FUNC_ITERATOR_NEXT.

Referenced by ecore_wl2_display_inputs_get().

## ◆ eina_inlist_accessor_new()

EINA_API Eina_Accessor * eina_inlist_accessor_new | ( | const Eina_Inlist * | in_list | ) |

Returns a new accessor associated to a list.

Parameters

  [in] | in_list | The list.

Returns
  A new accessor.

This function returns a newly allocated accessor associated to `in_list`. If `in_list` is `NULL` or the count member of `in_list` is less or equal than `0`, this function returns `NULL`. If the memory can not be allocated, `NULL` is returned and Otherwise, a valid accessor is returned.

References EINA_MAGIC_SET, FUNC_ACCESSOR_FREE, FUNC_ACCESSOR_GET_AT, and FUNC_ACCESSOR_GET_CONTAINER.

Referenced by elm_gengrid_nth_item_get(), and elm_genlist_nth_item_get().

## ◆ eina_inlist_sorted_insert()

EINA_API Eina_Inlist * eina_inlist_sorted_insert | ( | Eina_Inlist * | list,
|  | Eina_Inlist * | item,
|  | Eina_Compare_Cb | func
| ) |  |

Inserts a new node into a sorted list.

Parameters

  [in,out] | list | The given linked list, must be sorted.
  [in] | item | List node to insert, must not be `NULL`.
  [in] | func | The function called for the sort.

Returns
  A list pointer.

This function inserts item into a linked list assuming it was sorted and the result will be sorted. If `list` is `NULL`, item is returned. On success, a new list pointer that should be used in place of the one given to this function is returned. Otherwise, the old pointer is returned.

Note
  O(log2(n)) comparisons (calls to `func`) average/worst case performance. As said in eina_list_search_sorted_near_list(), lists do not have O(1) access time, so walking to the correct node can be costly, consider worst case to be almost O(n) pointer dereference (list walk).

Since
  1.1.0

References eina_inlist_append(), eina_inlist_append_relative(), eina_inlist_prepend(), eina_inlist_prepend_relative(), eina_inlist_sorted_state_init(), EINA_SAFETY_ON_NULL_RETURN_VAL, and _Eina_Inlist::next.

## ◆ eina_inlist_sorted_state_new()

EINA_API Eina_Inlist_Sorted_State * eina_inlist_sorted_state_new | ( | void |  | ) |

Creates state with valid data in it.

Returns
  A valid Eina_Inlist_Sorted_State.

Since
  1.1.0

See eina_inlist_sorted_state_insert() for more information.

## ◆ eina_inlist_sorted_state_init()

EINA_API int eina_inlist_sorted_state_init | ( | Eina_Inlist_Sorted_State * | state,
|  | Eina_Inlist * | list
| ) |  |

Forces an Eina_Inlist_Sorted_State to match the content of a list.

Parameters

  [in,out] | state | The state to update
  [in] | list | The list to match

Returns
  The number of item in the actually in the list

Since
  1.1.0

See eina_inlist_sorted_state_insert() for more information. This function is useful if you didn't use eina_inlist_sorted_state_insert() at some point, but still think you have a sorted list. It will only correctly work on a sorted list.

References _Eina_Inlist::next.

Referenced by eina_inlist_sorted_insert().

## ◆ eina_inlist_sorted_state_free()

EINA_API void eina_inlist_sorted_state_free | ( | Eina_Inlist_Sorted_State * | state | ) |

Frees an Eina_Inlist_Sorted_State.

Parameters

  [in,out] | state | The state to destroy

Since
  1.1.0

See eina_inlist_sorted_state_insert() for more information.

## ◆ eina_inlist_sorted_state_insert()

EINA_API Eina_Inlist * eina_inlist_sorted_state_insert | ( | Eina_Inlist * | list,
|  | Eina_Inlist * | item,
|  | Eina_Compare_Cb | func,
|  | Eina_Inlist_Sorted_State * | state
| ) |  |

Inserts a new node into a sorted list.

Parameters

  [in,out] | list | The given linked list, must be sorted.
  [in] | item | list node to insert, must not be `NULL`.
  [in] | func | The function called for the sort.
  [in,out] | state | The current array for initial dichotomic search

Returns
  A list pointer.

Since
  1.1.0

This function inserts item into a linked list assuming `state` matches the exact content order of the list. It uses `state` to do a fast first step dichotomic search before starting to walk the inlist itself. This makes this code much faster than eina_inlist_sorted_insert() as it doesn't need to walk the list at all. The result is of course a sorted list with an updated state. If `list` is `NULL`, item is returned. On success, a new list pointer that should be used in place of the one given to this function is returned. Otherwise, the old pointer is returned.

Note
  O(log2(n)) comparisons (calls to `func`) average/worst case performance. As said in eina_list_search_sorted_near_list(), lists do not have O(1) access time, so walking to the correct node can be costly, but this version tries to minimize that by making it a O(log2(n)) for number small number. After n == 256, it starts to add a linear cost again. Consider worst case to be almost O(n) pointer dereference (list walk).

References eina_inlist_append(), eina_inlist_append_relative(), eina_inlist_prepend(), eina_inlist_prepend_relative(), and _Eina_Inlist::next.

Referenced by eldbus_signal_handler_match_extra_vset().

## ◆ eina_inlist_sort()

EINA_API Eina_Inlist * eina_inlist_sort | ( | Eina_Inlist * | head,
|  | Eina_Compare_Cb | func
| ) |  |

Sorts a list according to the ordering func will return.

Parameters

  [in,out] | head | The list handle to sort.
  [in] | func | A function pointer that can handle comparing the list data nodes.

Returns
  the new head of list.

This function sorts all the elements of `head`. `func` is used to compare two elements of `head`. If `head` or `func` are `NULL`, this function returns `NULL`.

Note
  in-place: this will change the given list, so you should now point to the new list head that is returned by this function.
  Worst case is O(n * log2(n)) comparisons (calls to func()). That means that for 1,000,000 list elements, sort will do 20,000,000 comparisons.

Example:

typedef struct _Sort_Ex Sort_Ex;
struct _Sort_Ex
{
EINA_INLIST;
const char *text;
};
int
sort_cb(const Inlist *l1, const Inlist *l2)
{
const Sort_Ex *x1;
const Sort_Ex *x2;
x1 = EINA_INLIST_CONTAINER_GET(l1, Sort_Ex);
x2 = EINA_INLIST_CONTAINER_GET(l2, Sort_Ex);
return(strcmp(x1->text, x2->text));
}
extern Eina_Inlist *list;
list = eina_inlist_sort(list, sort_cb);
eina_inlist_sort
EINA_API Eina_Inlist * eina_inlist_sort(Eina_Inlist *head, Eina_Compare_Cb func)
Sorts a list according to the ordering func will return.
Definition: eina_inlist.c:804
EINA_INLIST_CONTAINER_GET
#define EINA_INLIST_CONTAINER_GET(ptr, type)
Utility macro to get the container object of an inlist.
Definition: eina_inlist.h:415
EINA_INLIST
#define EINA_INLIST
Used for declaring an inlist member in a struct.
Definition: eina_inlist.h:411
_Eina_Inlist
Inlined list type.
Definition: eina_inlist.h:405

References EINA_SAFETY_ON_NULL_RETURN_VAL, _Eina_Inlist::last, and _Eina_Inlist::next.