/* vx_list.h - simple circular doubly-linked list type and macros */ #ifndef VX_LIST_H #define VX_LIST_H #ifdef __cplusplus extern "C" { #endif typedef struct Circ_list_struct Circ_list; struct Circ_list_struct { Circ_list * prev; Circ_list * next; }; /* * CIRC_LIST_INIT(l) initializes the list node l as a list * containing a single node (itself). Used for list heads/sentinels. */ #define CIRC_LIST_INIT(l) \ do { \ Circ_list * l_ = (l); \ l_->prev = l_; \ l_->next = l_; \ } while ((0)) /* * CIRC_LIST_REMOVE(n) removes the node n from the list * that it is in. (n must be in a list). * n is left with dangling references to the list. * If n is alone in the list, this is a no-op. */ #define CIRC_LIST_REMOVE(n) \ do { \ Circ_list * n_ = (n); \ Circ_list * nxt_ = n_->next; \ n_->prev->next = nxt_; \ nxt_->prev = n_->prev; \ } while ((0)) /* * CIRC_LIST_INSERT_AFTER(l, n) inserts node n after node l * in the list that l currently belongs to. n should * be a free node. If l represents the 'head' of the list * rather than an 'item', this operation inserts n as the * first item in list. */ #define CIRC_LIST_INSERT_AFTER(l, n) \ do { \ Circ_list * l_ = (l); \ Circ_list * n_ = (n); \ n_->prev = l_; \ n_->next = l_->next; \ l_->next->prev = n_; \ l_->next = n_; \ } while ((0)) /* * CIRC_LIST_INSERT_BEFORE(l, n) inserts node n before node l * in the list that l currently belongs to. n should * be a free node. If l represents the head of the list, * this operation corresponds to inserting n at the tail. */ #define CIRC_LIST_INSERT_BEFORE(l, n) \ do { \ Circ_list * l_ = (l); \ Circ_list * n_ = (n); \ n_->next = l_; \ n_->prev = l_->prev; \ l_->prev->next = n_; \ l_->prev = n_; \ } while ((0)) #ifdef __cplusplus } #endif #endif /* VX_LIST_H */