RList
|
#include <stddef.h>
#include <stdbool.h>
#include <assert.h>
#include "rlist/platform.h"
#include "rlist/common.h"
Go to the source code of this file.
Data Structures | |
struct | srl_list |
struct | srl_iterator |
Defines | |
#define | SRL_INIT { 0, NULL, NULL } |
#define | SRL_INIT_WITH(free_fn) { 0, free_fn, NULL } |
Typedefs | |
typedef int(* | srl_map_fn )(struct srl_iterator *const iter, void *const context) |
Functions | |
static void * | srl_payload (const struct srl_iterator *const iter) |
static void | srl_init (struct srl_list *const list, rl_free_fn free_fn) |
static unsigned int | srl_size (const struct srl_list *const list) |
static struct srl_iterator * | srl_first (struct srl_list *const list, struct srl_iterator *const iter) |
struct srl_iterator * | srl_next (struct srl_iterator *const iter) |
static bool | srl_is_eol (const struct srl_iterator *const iter) |
bool | srl_insert_before (struct srl_iterator *const iter, void *const payload) |
void * | srl_del (struct srl_iterator *const iter) |
void | srl_del_all (struct srl_list *const list) |
struct srl_iterator * | srl_find (struct srl_iterator *const iter, rl_match_fn match_fn, void *const match_context) |
struct srl_iterator * | srl_find_payload (struct srl_iterator *const iter, void *const payload) |
int | srl_map (struct srl_iterator *const iter, srl_map_fn map_fn, void *const map_context, rl_match_fn match_fn, void *const match_context) |
Public RList API for singly linked lists.
Definition in file single.h.
#define SRL_INIT { 0, NULL, NULL } |
An initializer constant for srl_list objects.
After assigning this value to a list, it is empty and not associated with an rl_free_fn() function.
Static or local declarations of srl_list objects should be initialized in the declaration with this value (e.g., static struct srl_list list = SRL_INIT;
). The srl_init() function should be used where initialization at compile time is not possible so it has to occur at runtime, e.g., for dynamically allocated srl_list objects.
#define SRL_INIT_WITH | ( | free_fn | ) | { 0, free_fn, NULL } |
An initializer constant for srl_list objects with a custom call-back function for de-allocating payload data.
After assigning this value to a list, it is empty and has the specified rl_free_fn() function associated.
Static or local declarations of srl_list objects should be initialized in the declaration with this value (e.g., static struct srl_list list = SRL_INIT;
). The srl_init() function should be used where initialization at compile time is not possible so it has to occur at runtime, e.g., for dynamically allocated srl_list objects.
free_fn | points to a function with the type rl_free_fn() for de-allocating payload data. |
typedef int(* srl_map_fn)(struct srl_iterator *const iter, void *const context) |
A type for call-back functions that are applied to multiple list nodes.
Typically, call-backs of this type are used to apply a certain operation (such as modifying the payload or deleting nodes) to some or all nodes in a list (
Using call-back functions for these operations gives the user of srl_list full customizability on the action performed on the list nodes while the generic iteration code is provided as an RList function and does not need to be re-implemented and customized over and over.
iter | points to an iterator that refers to a list node. The call-back function may freely manipulate the node's payload. It may also freely manipulate the iterator via any of the RList functions, including deleting the current node. |
context | points to a custom memory location that the call-back function requires as input or for storing data across calls. |
void* srl_del | ( | struct srl_iterator *const | iter | ) |
Delete a node from a list.
This function deletes the node that the given iterator refers to.
The runtime complexity of this function is O(1).
iter | Points to an iterator object. The iterator may not be uninitialized and must have previously been returned by one of the RList functions. The result of calling this function with iter == NULL is undefined. |
NULL
. Note that if in this case the payload is present more than once in the list, it is indeed de-allocated but other list nodes with the same payload remain in the list and still point to the now de-allocated payload memory. Thus, inserting a payload more than once into a list should be avoided. If the list is not associated with an rl_free_fn() call-back function, the payload is not de-allocated and this function returns the payload of the deleted node. Note that the payload itself may be NULL
. void srl_del_all | ( | struct srl_list *const | list | ) |
Delete all nodes from a list.
This is a convenience function which calls srl_del() for all nodes of a list.
The runtime complexity of this function is O(n).
list | Points to the list object from which to delete all nodes. The result of calling this function with list == NULL is undefined. |
struct srl_iterator* srl_find | ( | struct srl_iterator *const | iter, |
rl_match_fn | match_fn, | ||
void *const | match_context | ||
) | [read] |
Find a list node based on a match call-back function.
This function iterates linearly over a list, starting at the given iterator position, and applies the given matcher call-back function to each list node. It returns an iterator for the first matching node.
The average runtime complexity of this function is O(n/2) + O(match_fn) when iter refers to the first list node.
iter | Points to an iterator object. The iterator indicates the list to search and the list node to begin the search at. The result of calling this function with iter == NULL or an uninitialized iterator object is undefined. |
match_fn | Points to a call-back function that identifies the list node to return. The result of calling this function with match_fn == NULL is undefined. |
match_context | A context object passed to match_fn on every invocation as its second parameter. The semantics of match_context depend solely on the implementation of the match_fn call-back. match_context may be NULL if match_fn supports that. |
struct srl_iterator* srl_find_payload | ( | struct srl_iterator *const | iter, |
void *const | payload | ||
) | [read] |
Find a list node with a certain payload.
This is a convenience function implemented via srl_find().
The average runtime complexity of this function is O(n/2) when iter refers to the first list node.
iter | Points to an iterator object. The iterator indicates the list to search and the list node to begin the search at. The result of calling this function with iter == NULL or an uninitialized iterator object is undefined. |
payload | points to the payload to find in list. If payload is NULL , the first list node with a NULL payload is searched for. |
static struct srl_iterator* srl_first | ( | struct srl_list *const | list, |
struct srl_iterator *const | iter | ||
) | [static, read] |
Initialize an iterator object so it refers to the first node in a list.
If the list is empty, the iterator is updated so that srl_is_eol() returns true.
The runtime complexity of this function is O(1).
list | Points to the list from which to retrieve the first node. The result of calling this function with list == NULL is undefined. |
iter | Points to the iterator object to initialize. The result of calling this function with iter == NULL is undefined. |
static void srl_init | ( | struct srl_list *const | list, |
rl_free_fn | free_fn | ||
) | [inline, static] |
Initialize a srl_list object at runtime.
This function should be used where initialization at compile time is not possible so it has to occur at runtime, e.g., for dynamically allocated srl_list objects. Static or local declarations of srl_list objects should be initialized in their declaration via SRL_INIT.
The runtime complexity of this function is O(1).
list | points to the list object to initialize. The result of calling this function with list == NULL is undefined. |
free_fn | points to a rl_free_fn() call-back function for de-allocating payload data. If free_fn is NULL , the list does not automatically de-allocate payload data. Proper memory management of the payload data is then the responsibility of the user of list. |
bool srl_insert_before | ( | struct srl_iterator *const | iter, |
void *const | payload | ||
) |
Add payload as a new node at a specific location of a list.
The runtime complexity of this function is O(1).
iter | Points to an iterator. The new node is inserted between the iterator's node and its predecessor. If iter refers to the end of the list (i.e., when srl_is_eol(iter) returns true ), the new node is inserted as the last node in the list. This also works for inserting the first node into an empty list. The result of calling this function with iter == NULL is undefined. |
payload | Points to the payload to add to the list. payload may be NULL , in which case a node with a NULL payload is prepended to the list. The same payload may be added to a list several times. In that case however, one needs to be particularly careful about when to de-allocate the payload data. Otherwise, one list node may still point to payload that has already been de-allocated for another list node. |
static bool srl_is_eol | ( | const struct srl_iterator *const | iter | ) | [inline, static] |
Determine whether an iterator refers to the end of a list.
This is primarily useful to determine when an iteration over a list has ended. In this state, the iterator does not refer to a valid list node and should not be passed to any RList functions except srl_is_eol().
The runtime complexity of this function is O(1).
iter | Points to the iterator object to check. The result of calling this function with iter == NULL is undefined. |
int srl_map | ( | struct srl_iterator *const | iter, |
srl_map_fn | map_fn, | ||
void *const | map_context, | ||
rl_match_fn | match_fn, | ||
void *const | match_context | ||
) |
Applies a call-back function to some or all nodes of a list.
This function linearly iterates over a list, starting at the given iterator. For each node, it first checks if an optional rl_match_fn() call-back matches the node. If the node is a match or no rl_match_fn() call-back is supplied, this function invokes the srl_map_fn() call-back for the node. It continues until the end of the list is reached or until the srl_map_fn() call-back returns a non-zero integer.
The average runtime complexity of this function is O(n/2) + O(match_fn) + O(map_fn) when iter refers to the first list node.
iter | Points to an iterator object. The iterator indicates the list to map map_fn onto and it specifies the list node to begin the map operation at. The result of calling this function with iter == NULL or an uninitialized iterator object is undefined. |
map_fn | points to the call-back function to invoke on every node matching match_fn. The result of calling this function with map_fn == NULL is undefined. |
map_context | A context object passed to map_fn on every invocation as its second parameter. The semantics of map_context depend solely on the implementation of the map_fn call-back. map_context may be NULL if map_fn supports that. |
match_fn | points to the call-back function that identifies the subset of nodes that map_fn is invoked for. If match_fn is NULL , map_fn is invoked for all list nodes. |
match_context | A context object passed to match_fn on every invocation as its second parameter. The semantics of match_context depend solely on the implementation of the match_fn call-back. match_context may be NULL if match_fn supports that. |
struct srl_iterator* srl_next | ( | struct srl_iterator *const | iter | ) | [read] |
Update an iterator object so it refers to the 'next' list node, i.e., the node following the one the iterator refers to before calling this function.
After passing an iterator to srl_del(), you must call srl_next() on the same iterator before passing it to any other RList function. This advances the iterator to the node after the deleted node.
This function is primarily intended for iterating through a list.
The runtime complexity of this function is O(1).
iter | Points to an iterator object. The iterator may not be uninitialized and must have previously been returned by one of the RList functions. If iter refers to the end of the list, i.e., if srl_is_eol(iter) returns true, this function does not modify iter. The result of calling this function with iter == NULL is undefined. |
static void* srl_payload | ( | const struct srl_iterator *const | iter | ) | [inline, static] |
Retrieve the payload an iterator object is associated with.
The runtime complexity of this function is O(1).
iter | points to the iterator for which to retrieve the payload pointer. The result of calling this function with iter == NULL is undefined. The result of calling this function with an inconsistent iterator ( |
static unsigned int srl_size | ( | const struct srl_list *const | list | ) | [inline, static] |
Retrieve the number of nodes currently held by a list.
The runtime complexity of this function is O(1).
list | points to the list object of which to retrieve the node count. The result of calling this function with list == NULL is undefined. |