Contains struct picotm_slist
and helpers.
More...
Data Structures | |
struct | picotm_slist |
Entry in a singly-linked list. More... | |
Macros | |
#define | PICOTM_SLIST_HEAD_INITIALIZER(head_) |
#define | PICOTM_SLIST_ITEM_INITIALIZER |
Functions | |
static struct picotm_slist * | picotm_slist_back (const struct picotm_slist *head) |
static struct picotm_slist * | picotm_slist_begin (const struct picotm_slist *head) |
static void | picotm_slist_cleanup_0 (struct picotm_slist *head, void(*cleanup)(struct picotm_slist *)) |
static void | picotm_slist_cleanup_1 (struct picotm_slist *head, void(*cleanup)(struct picotm_slist *, void *), void *data1) |
static void | picotm_slist_cleanup_2 (struct picotm_slist *head, void(*cleanup)(struct picotm_slist *, void *, void *), void *data1, void *data2) |
static void | picotm_slist_dequeue (struct picotm_slist *item) |
static void | picotm_slist_dequeue_front (struct picotm_slist *head) |
static const struct picotm_slist * | picotm_slist_end (const struct picotm_slist *head) |
static void | picotm_slist_enqueue_after (struct picotm_slist *item, struct picotm_slist *newitem) |
static void | picotm_slist_enqueue_back (struct picotm_slist *head, struct picotm_slist *newitem) |
static void | picotm_slist_enqueue_before (struct picotm_slist *item, struct picotm_slist *newitem) |
static void | picotm_slist_enqueue_front (struct picotm_slist *head, struct picotm_slist *newitem) |
static void | picotm_slist_enqueue_sorted (struct picotm_slist *head, struct picotm_slist *newitem, int(*cmp)(struct picotm_slist *, struct picotm_slist *)) |
static struct picotm_slist * | picotm_slist_find_0 (const struct picotm_slist *head, _Bool(*test)(const struct picotm_slist *)) |
static struct picotm_slist * | picotm_slist_find_1 (const struct picotm_slist *head, _Bool(*test)(const struct picotm_slist *, void *), void *data) |
static struct picotm_slist * | picotm_slist_find_2 (const struct picotm_slist *head, _Bool(*test)(const struct picotm_slist *, void *, void *), void *data1, void *data2) |
static struct picotm_slist * | picotm_slist_front (const struct picotm_slist *head) |
static struct picotm_slist * | picotm_slist_init_head (struct picotm_slist *head) |
static struct picotm_slist * | picotm_slist_init_item (struct picotm_slist *item) |
static _Bool | picotm_slist_is_empty (const struct picotm_slist *head) |
static _Bool | picotm_slist_is_enqueued (const struct picotm_slist *item) |
static struct picotm_slist * | picotm_slist_next (const struct picotm_slist *item) |
static struct picotm_slist * | picotm_slist_prev (const struct picotm_slist *item) |
static void | picotm_slist_uninit_head (struct picotm_slist *head) |
static void | picotm_slist_uninit_item (struct picotm_slist *item) |
static struct picotm_slist * | picotm_slist_walk_0 (const struct picotm_slist *head, size_t(*walk)(struct picotm_slist *)) |
static struct picotm_slist * | picotm_slist_walk_1 (const struct picotm_slist *head, size_t(*walk)(struct picotm_slist *, void *data), void *data) |
static struct picotm_slist * | picotm_slist_walk_2 (const struct picotm_slist *head, size_t(*walk)(struct picotm_slist *, void *data1, void *data2), void *data1, void *data2) |
The data structure struct picotm_slist
represents a singly-linked list, or slist. This can either be the list head, or an entry in a list.
The head of a singly-linked list is the main reference to a list. It does not itself contain data. A call to picotm_slist_init_head()
initializes a list head.
Or alternatively, the C pre-processor macro PICOTM_SLIST_HEAD_INITIALIZER
initializes static or stack-allocated list heads.
Calls to picotm_slist_init_item()
or PICOTM_SLIST_ITEM_INITIALIZER
initialize list entries in a similar way.
Typically, slist items are stored in a container structure that also holds additional application data. For example, a singly-linked list that stores values of type unsigned long
could use the following data entries.
The singly-linked list refers from item
to item
field of the contained list entries. The helper function ulong_item_of_slist()
takes a list item and returns the corresponding data element of type struct ulong_item
.
Both, slist head and item elements, require cleanup by their respective clean-up function picotm_slist_uninit_head()
or picotm_slist_uninit_item()
.
List item elements that are to be uninitialized may not be enqueued in a list; head elements may not refer to any items.
The functions picotm_slist_enqueue_front()
and picotm_slist_enqueue_back
insert an entry at the front, resp. the back, of an slist. If we already know an existing entry from an slist, we can insert an entry before or after the existing one with a call to picotm_enqueue_slist_before()
, resp. picotm_slist_enqueue_after()
. Here's an example with picotm_slist_enqueue_front()
.
A call to picotm_slist_dequeue()
removes an entry from an slist.
To see if an item is enqueued in an slist, we call picotm_slist_is_enqueued()
, whch returns true
in this case. Likewise, a call to picotm_slist_empty()
returns true
if a list is empty.
For iterating over a singly-linked list, the functions picotm_slist_begin()
and picotm_slist_end()
return the slist's first and final element. The final element is a terminator and not a useable slist item. Reaching this value signals the callers to stop iterating. We use picotm_slist_next()
and picotm_slist_prev()
for moving between consecutive elements. singly-linked lists can only be traversed in forward direction, so the latter function picotm_slist_prev()
is of linear complexity. I should be avoided within loop constructs.
Here's a typical example of a loop that walks over all elements in an slist. In this case, it sums up the values of type unsigned long
that are enqueued in the list.
Singly-linked lists provide a number of built-in algorithms. With the walk function picotm_slist_walk_1()
we can walk over all entries in a list. With walk, the previous example can be rewritten in the following way.
The overall iteration over the slist entries is performed by picotm_slist_walk_1()
. The function calls sum_cb()
for each item and the pointer to sum
is passed as additional data parameter.
The function sum_cb()
accumulates the list entries' values in sum
and returns the number of items to increment. Returning values larger than 1 therefore allows to skip successive list entries. Returning 0 prematurely stops the iteration. The value returned by picotm_slist_walk1()
is the element at which the iteration stopped.
With the find function picotm_slist_find_1()
we can search an slist for the first item that matches a specific criteria. In the following example, we search for the first element with a value of 0.
The function test_cb()
compares the value of an slist item to a reference value, which is 0 in our case. If both match, it will return 'true'. The function picotm_slist_find1()
calls test_cb()
for each item in the slist and returns the first item for which the test function returned 'true'. If none is found, the find function returns the final terminator entry. Our example code checks and handles this case explicitly.
Finally, there's the clean-up function picotm_slist_cleanup_0()
, which dequeues all list entries one by one and calls a clean-up function on each. Once called, the clean-up function acquires ownership of the given item. Here's an example of cleaning up a list of items that have been allocated with malloc()
. The corresponding free()
is performed in the item clean-up function.