#ifndef CHAIN_H
#define CHAIN_H
/**
* @file
*
* Defines a semi-generalized "chain of things" behaviour.
*
* The structure of this is a chain_list, which contains a number of chain_head items, which then contain a number of
* induvidual items.
*/
#include "error.h"
#include <sys/queue.h>
/**
* The chain header.
*/
struct chain_head {
/** The list of items */
const void *chain;
/** The context arg */
void *arg;
/** Our position in the chain_list */
STAILQ_ENTRY(chain_head) node;
};
/**
* @struct chain_list
*
* The chain list
*/
STAILQ_HEAD(chain_list, chain_head);
/**
* Initialize a `struct chain_list`
*/
#define CHAIN_INIT(list_ptr) STAILQ_INIT(list_ptr)
/**
* Add an item onto the end of a chain_list
*/
err_t chain_add (struct chain_list *list, const void *chain, void *arg);
/**
* Iterate over the contents of a chain_list
*
* struct chain_list *list = ...;
* struct chain_head *head;
* struct foo *foo;
*
* CHAIN_FOREACH(list, head) {
* for (foo = head->chain; foo->bar; foo++) {
* foo->bar(foo, head->arg);
* }
* }
*/
#define CHAIN_FOREACH(list_ptr, head_ptr) STAILQ_FOREACH(head_ptr, list_ptr, node)
/**
* Remove an item added with chain_add from a chain_list, matching against the given chain/arg.
*
* If no item matches, nothing is done.
*/
void chain_remove (struct chain_list *list, const void *chain, void *arg);
/**
* Free a chain_list
*/
void chain_free (struct chain_list *list);
#endif