RList
Data Structures | Defines | Typedefs | Functions
src/include/rlist/double.h File Reference
#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  drl_list
struct  drl_iterator

Defines

#define DRL_INIT   { 0, NULL, NULL, NULL }
#define DRL_INIT_WITH(free_fn)   { 0, free_fn, NULL, NULL }

Typedefs

typedef int(* drl_map_fn )(struct drl_iterator *const iter, void *const context)

Functions

static void * drl_payload (const struct drl_iterator *const iter)
static void drl_init (struct drl_list *const list, rl_free_fn free_fn)
static unsigned int drl_size (const struct drl_list *const list)
static struct drl_iteratordrl_first (struct drl_list *const list, struct drl_iterator *const iter)
static struct drl_iteratordrl_last (struct drl_list *const list, struct drl_iterator *const iter)
static struct drl_iteratordrl_next (struct drl_iterator *const iter)
static struct drl_iteratordrl_prev (struct drl_iterator *const iter)
static bool drl_is_eol (const struct drl_iterator *const iter)
bool drl_insert_before (struct drl_iterator *const iter, void *const payload)
void * drl_del (struct drl_iterator *const iter)
void drl_del_all (struct drl_list *const list)
struct drl_iteratordrl_find (struct drl_iterator *const iter, rl_match_fn match_fn, void *const match_context)
struct drl_iteratordrl_find_payload (struct drl_iterator *const iter, void *const payload)
int drl_map (struct drl_iterator *const iter, drl_map_fn map_fn, void *const map_context, rl_match_fn match_fn, void *const match_context)

Detailed Description

Public RList API for doubly linked lists.

Definition in file double.h.


Define Documentation

#define DRL_INIT   { 0, NULL, NULL, NULL }

An initializer constant for drl_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 drl_list objects should be initialized in the declaration with this value (e.g., static struct drl_list list = DRL_INIT;). The drl_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 drl_list objects.

Definition at line 64 of file double.h.

#define DRL_INIT_WITH (   free_fn)    { 0, free_fn, NULL, NULL }

An initializer constant for drl_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 drl_list objects should be initialized in the declaration with this value (e.g., static struct drl_list list = DRL_INIT;). The drl_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 drl_list objects.

Parameters:
free_fnpoints to a function with the type rl_free_fn() for de-allocating payload data.

Definition at line 76 of file double.h.


Typedef Documentation

typedef int(* drl_map_fn)(struct drl_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 (

See also:
drl_map()). It is recommended to make such call-back functions efficient because they are applied to potentially large numbers of list nodes.

Using call-back functions for these operations gives the user of drl_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.

Parameters:
iterpoints 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.
contextpoints to a custom memory location that the call-back function requires as input or for storing data across calls.
Returns:
If the call-back function returns 0, the iteration over the list continues and the call-back function is invoked for the remaining list nodes. If a non-zero value is returned, the iteration stops and the call-back is not invoked for any further list nodes.

Definition at line 197 of file double.h.


Function Documentation

void* drl_del ( struct drl_iterator *const  iter)

Delete a node from a list.

This function deletes the node that the given iterator refers to.

Warning:
After drl_del() returns, the iterator iter is in an inconsistent state. To make the iterator consistent again, call drl_next() or drl_prev(). The result of passing an inconsistent iterator to any other RList function is undefined. Note that when drl_del() is invoked from a drl_map_fn() call-back function, drl_next() is invoked implicitely after the call-back returns. Thus the call-back does not need to invoke drl_next() or drl_prev() itself.

The runtime complexity of this function is O(1).

Parameters:
iterPoints 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.
Returns:
If the list is associated with an rl_free_fn() call-back function, that call-back in invoked for the payload of the node to delete and this function returns 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.

Definition at line 164 of file double.c.

void drl_del_all ( struct drl_list *const  list)

Delete all nodes from a list.

This is a convenience function which calls drl_del() for all nodes of a list.

The runtime complexity of this function is O(n).

Parameters:
listPoints to the list object from which to delete all nodes. The result of calling this function with list == NULL is undefined.

Definition at line 215 of file double.c.

struct drl_iterator* drl_find ( struct drl_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.

Parameters:
iterPoints 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_fnPoints 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_contextA 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.
Returns:
If match_fn matches the node referred to by iter or a subsequent node, this function updates iter so that it refers to the first such matching node and returns iter. If match_fn matches no node in list, this function updates iter so that it refers to the end of the list and returns iter. If iter refers to the end of the list, this function does not update iter and returns iter. This function never returns NULL.

Definition at line 243 of file double.c.

struct drl_iterator* drl_find_payload ( struct drl_iterator *const  iter,
void *const  payload 
) [read]

Find a list node with a certain payload.

This is a convenience function implemented via drl_find().

The average runtime complexity of this function is O(n/2) when iter refers to the first list node.

Parameters:
iterPoints 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.
payloadpoints to the payload to find in list. If payload is NULL, the first list node with a NULL payload is searched for.
Returns:
If payload matches the node referred to by iter or a subsequent node, this function updates iter so that it refers to the first such matching node and returns iter. If match_fn matches no node in list, this function updates iter so that it refers to the end of the list and returns iter. If iter refers to the end of the list, this function does not update iter and returns iter. This function never returns NULL.

Definition at line 271 of file double.c.

static struct drl_iterator* drl_first ( struct drl_list *const  list,
struct drl_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 drl_is_eol() returns true.

The runtime complexity of this function is O(1).

Parameters:
listPoints to the list from which to retrieve the first node. The result of calling this function with list == NULL is undefined.
iterPoints to the iterator object to initialize. The result of calling this function with iter == NULL is undefined.
Returns:
This function returns iter.

Definition at line 327 of file double.h.

static void drl_init ( struct drl_list *const  list,
rl_free_fn  free_fn 
) [inline, static]

Initialize a drl_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 drl_list objects. Static or local declarations of drl_list objects should be initialized in their declaration via DRL_INIT.

The runtime complexity of this function is O(1).

Parameters:
listpoints to the list object to initialize. The result of calling this function with list == NULL is undefined.
free_fnpoints 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.

Definition at line 291 of file double.h.

bool drl_insert_before ( struct drl_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).

Parameters:
iterPoints 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 drl_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.
payloadPoints 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.
Returns:
Returns true if the new list node was successfully inserted into the list before iter. Returns false, if the list was not modified because the meta-data for the new node could not be allocated.

Definition at line 129 of file double.c.

static bool drl_is_eol ( const struct drl_iterator *const  iter) [inline, static]

Determine whether an iterator refers to either end of a list, i.e., whether it iterated beyond the last list node or before the first list node.

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 drl_is_eol().

The runtime complexity of this function is O(1).

Parameters:
iterPoints to the iterator object to check. The result of calling this function with iter == NULL is undefined.
Returns:
This function returns true if iter refers to the end of its list instead of a valid list node. It returns false if the iterator refers to a valid list node.

Definition at line 463 of file double.h.

static struct drl_iterator* drl_last ( struct drl_list *const  list,
struct drl_iterator *const  iter 
) [static, read]

Initialize an iterator object so it refers to the last node in a list.

If the list is empty, the iterator is updated so that drl_is_eol() returns true.

The runtime complexity of this function is O(1).

Parameters:
listPoints to the list from which to retrieve the last node. The result of calling this function with list == NULL is undefined.
iterPoints to the iterator object to initialize. The result of calling this function with iter == NULL is undefined.
Returns:
This function returns iter.

Definition at line 351 of file double.h.

int drl_map ( struct drl_iterator *const  iter,
drl_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 drl_map_fn() call-back for the node. It continues until the end of the list is reached or until the drl_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.

Parameters:
iterPoints 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_fnpoints 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_contextA 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_fnpoints 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_contextA 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.
Returns:
This function returns the value returned by the last invocation of map_fn(). If map_fn() is not invoked because iter did not point to any remaining list nodes or because match_fn() did not return true for any list node, this function returns 0.
See also:
drl_map()

Definition at line 277 of file double.c.

static struct drl_iterator* drl_next ( struct drl_iterator *const  iter) [static, 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 drl_del(), you must call drl_next() or drl_prev() on the same iterator before passing it to any other RList function. This advances the iterator to the node after or before the deleted node.

This function is primarily intended for iterating through a list.

The runtime complexity of this function is O(1).

Parameters:
iterPoints 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 either end of the list, i.e., if drl_is_eol(iter) returns true, this function does not modify iter. The result of calling this function with iter == NULL is undefined.
Returns:
This function returns iter.

Definition at line 378 of file double.h.

static void* drl_payload ( const struct drl_iterator *const  iter) [inline, static]

Retrieve the payload an iterator object is associated with.

The runtime complexity of this function is O(1).

Parameters:
iterpoints 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 (
See also:
drl_del()) is undefined.
Returns:
Returns the payload of the list node that iter refers to.

Definition at line 271 of file double.h.

static struct drl_iterator* drl_prev ( struct drl_iterator *const  iter) [static, read]

Update an iterator object so it refers to the 'previous' list node, i.e., the node preceeding the one the iterator refers to before calling this function.

After passing an iterator to drl_del(), you must call drl_next() or drl_prev() on the same iterator before passing it to any other RList function. This advances the iterator to the node after or before the deleted node.

This function is primarily intended for iterating through a list.

The runtime complexity of this function is O(1).

Parameters:
iterPoints 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 either end of the list, i.e., if drl_is_eol(iter) returns true, this function does not modify iter. The result of calling this function with iter == NULL is undefined.
Returns:
This function returns iter.

Definition at line 422 of file double.h.

static unsigned int drl_size ( const struct drl_list *const  list) [inline, static]

Retrieve the number of nodes currently held by a list.

The runtime complexity of this function is O(1).

Parameters:
listpoints to the list object of which to retrieve the node count. The result of calling this function with list == NULL is undefined.
Returns:
The number of nodes currently held by list.

Definition at line 308 of file double.h.