In a empty initialized node, this pointers point to the node itself. Note that these pointers can never ever become NULL. This lists are used by using one node as 'root' node where its both pointers are the head/tail pointer to the actual list. Care needs to be taken to ensure not to apply any operations meant to be applied to data nodes to the root node. This way is the prefered way to use this lists. Alternatively one can store only a chain of data nodes and use a LList pointer to point to the first item (which might be NULL in case no data is stored). When using the 2nd approach care must be taken since most functions below expect lists to have a root node.
This header can be used in 2 different ways: 1) (prerefered) just including it provides all functions as static inlined functions. This is the default 2) define LLIST_INTERFACE before including this header gives only the declarations define LLIST_IMPLEMENTATION before including this header yields in definitions this can be used to generate a library. This is currently untested and not recommended. The rationale for using inlined functions is that most functions are very small and likely to be used in performance critical parts. Inlining can give a hughe performance and optimization improvement here. The few functions which are slightly larger are expected to be the less common used ones, so inlining them too shouldn't be a problem either
Definition in file llist.h.
#include <stddef.h>


Go to the source code of this file.
Classes | |
| struct | llist_struct |
Defines | |
| #define | LLIST_AUTO(name) llist name = {&name,&name} |
| Macro to instantiate a local llist. | |
| #define | LLIST_FOREACH(list, node) |
| Iterate forward over a list. | |
| #define | LLIST_FOREACH_REV(list, node) |
| Iterate backward over a list. | |
| #define | LLIST_FORRANGE(start, end, node) |
| Iterate forward over a range. | |
| #define | LLIST_FORRANGE_REV(rstart, rend, node) |
| Iterate backward over a range. | |
| #define | LLIST_FUNC(proto,...) LLIST_MACRO proto { __VA_ARGS__ } |
| #define | llist_head llist_next |
| #define | llist_insert_head(list, element) llist_insert_next (list, element) |
| #define | llist_insert_tail(list, element) llist_insert_prev (list, element) |
| #define | LLIST_MACRO static |
| #define | llist_tail llist_prev |
| #define | LLIST_TO_STRUCTP(llist, type, member) ((type*)(((char*)(llist)) - offsetof(type, member))) |
| cast back from a member of a structure to a pointer of the structure | |
| #define | LLIST_WHILE_HEAD(list, head) |
| Consume a list from head. | |
| #define | LLIST_WHILE_TAIL(list, tail) |
| Consume a list from tail. | |
Typedefs | |
| typedef const llist * | const_LList |
| typedef llist * | LList |
| typedef struct llist_struct | llist |
| typedef int(* | llist_cmpfn )(LList a, LList b) |
| Sort a list. | |
| typedef llist ** | LList_ref |
Functions | |
| LLIST_FUNC (LList llist_get_nth_stop(LList self, int n, const_LList stop), if(n >0) while(n--){self=llist_next(self);if(self==stop) return NULL;}else while(n++){self=llist_prev(self);if(self==stop) return NULL;}return self;) | |
| Get the nth element of a list with a stop node. | |
| LLIST_FUNC (LList llist_nth(LList self, int n), if(n >0) while(n--) self=llist_next(self);else while(n++) self=llist_prev(self);return self;) | |
| Get the nth element of a list. | |
| LLIST_FUNC (void llist_forward(LList_ref self),*self=(*self)->next;) | |
| Advance a pointer to a node to its next node. | |
| LLIST_FUNC (LList llist_prev(const_LList self), return self->prev;) | |
| Get previous node. | |
| LLIST_FUNC (LList llist_next(const_LList self), return self->next;) | |
| Get next node. | |
| LLIST_FUNC (LList llist_advance(LList self), LList tmp=self->next->next;tmp->prev=self;self->next->prev=self->prev;self->prev->next=self->next;self->prev=self->next;self->next->next=self;self->next=tmp;return self;) | |
| Swap a node with its next node. | |
| LLIST_FUNC (LList llist_insertlist_prev(LList self, LList prev), if(!llist_is_empty(prev)){self->prev->next=prev->next;prev->next->prev=self->prev;self->prev=prev->prev;prev->prev->next=self;prev->prev=prev->next=prev;}return self;) | |
| Move the content of a list before a node in another list. | |
| LLIST_FUNC (LList llist_insertlist_next(LList self, LList next), if(!llist_is_empty(next)){self->next->prev=next->prev;next->prev->next=self->next;self->next=next->next;next->next->prev=self;next->prev=next->next=next;}return self;) | |
| Move the content of a list after a node in another list. | |
| LLIST_FUNC (LList llist_insert_prev(LList self, LList prev), llist_unlink_fast_(prev);self->prev->next=prev;prev->next=self;prev->prev=self->prev;self->prev=prev;return self;) | |
| Insert a node before another. | |
| LLIST_FUNC (LList llist_insert_next(LList self, LList next), llist_unlink_fast_(next);self->next->prev=next;next->prev=self;next->next=self->next;self->next=next;return self;) | |
| Insert a node after another. | |
| LLIST_FUNC (LList llist_relocate(LList self), return self->next->prev=self->prev->next=self;) | |
| Fix a node which got relocated in memory. | |
| LLIST_FUNC (LList llist_unlink(LList self), llist_unlink_fast_(self);return self->next=self->prev=self;) | |
| Remove a node from a list. | |
| LLIST_FUNC (void llist_unlink_fast_(LList self), LList nxt=self->next, pre=self->prev;nxt->prev=pre;pre->next=nxt;) | |
| LLIST_FUNC (unsigned llist_count(const_LList self), unsigned cnt=0;const_LList i=self;for(;i->next!=self;++cnt, i=i->next);return cnt;) | |
| Count the nodes of a list. | |
| LLIST_FUNC (int llist_is_before_after(const_LList self, const_LList before, const_LList after), for(const_LList i=before->next;i!=self;i=i->next){if(i==after) return 1;}return 0;) | |
| Check the order of elements in a list. | |
| LLIST_FUNC (int llist_is_member(const_LList self, const_LList member), for(const_LList i=member->next;i!=member;i=i->next){if(i==self) return 1;}return 0;) | |
| Check if a node is a member of a list. | |
| LLIST_FUNC (int llist_is_end(const_LList self, const_LList end), return self==end;) | |
| Check for the end of a list. | |
| LLIST_FUNC (int llist_is_tail(const_LList self, const_LList tail), return self->prev==tail;) | |
| Check for the tail of a list. | |
| LLIST_FUNC (int llist_is_head(const_LList self, const_LList head), return self->next==head;) | |
| Check for the head of a list. | |
| LLIST_FUNC (int llist_is_single(const_LList self), return self->next->next==self;) | |
| Check if self is the only node in a list or self is not in a list. | |
| LLIST_FUNC (int llist_is_empty(const_LList self), return self->next==self;) | |
| Check if a node is not linked with some other node. | |
| LLIST_FUNC (void llist_init(LList self), self->next=self->prev=self;) | |
| Initialize a new llist. | |
| #define LLIST_AUTO | ( | name | ) | llist name = {&name,&name} |
| #define LLIST_TO_STRUCTP | ( | llist, | |||
| type, | |||||
| member | ) | ((type*)(((char*)(llist)) - offsetof(type, member))) |
cast back from a member of a structure to a pointer of the structure
Definition at line 119 of file llist.h.
Referenced by lumiera_config_lookup_item_find(), lumiera_config_lookup_item_tail_find(), lumiera_config_lookup_remove(), lumiera_mmapings_destroy(), and lumiera_mmapings_mmap_acquire().
| #define LLIST_FOREACH | ( | list, | |||
| node | ) |
Value:
for (LList node = llist_head (list); \
! llist_is_end (node, list); \
llist_forward (&node))
| list | the root node of the list to be iterated | |
| node | pointer to the iterated node |
Definition at line 127 of file llist.h.
Referenced by lumiera_config_dump(), and lumiera_mmapings_mmap_acquire().
| #define LLIST_FOREACH_REV | ( | list, | |||
| node | ) |
| #define LLIST_FORRANGE | ( | start, | |||
| end, | |||||
| node | ) |
| #define LLIST_FORRANGE_REV | ( | rstart, | |||
| rend, | |||||
| node | ) |
| #define LLIST_WHILE_HEAD | ( | list, | |||
| head | ) |
Value:
for (LList head = llist_head (list); \
!llist_is_empty (list); \
head = llist_head (list))
The body of this statement should remove the head from the list, else it would be a infinite loop
| list | the root node of the list to be consumed | |
| head | pointer to the head node |
| #define LLIST_WHILE_TAIL | ( | list, | |||
| tail | ) |
Value:
for (LList tail = llist_tail (list); \
!llist_is_empty (list); \
tail = llist_tail (list))
The body of this statement should remove the tail from the list, else it would be a infinite loop
| list | the root node of the list to be consumed | |
| tail | pointer to the tail node |
Definition at line 183 of file llist.h.
Referenced by lumiera_mmapings_destroy(), and lumiera_mrucache_destroy().
| typedef int(* llist_cmpfn)(LList a, LList b) |
| LLIST_FUNC | ( | void | llist_initLList self, | |
| self-> | next = self->prev=self; | |||
| ) |
Initialize a new llist.
Must not be applied to a list node which is not empty! Lists need to be initialized before any other operation on them is called.
| self | node to be initialized |
| LLIST_FUNC | ( | int | llist_is_emptyconst_LList self, | |
| return self-> | next = =self; | |||
| ) |
Check if a node is not linked with some other node.
| LLIST_FUNC | ( | int | llist_is_singleconst_LList self, | |
| return self->next-> | next = =self; | |||
| ) |
Check if self is the only node in a list or self is not in a list.
| self | node to be checked |
| LLIST_FUNC | ( | int | llist_is_headconst_LList self, const_LList head, | |
| return self-> | next = =head; | |||
| ) |
Check for the head of a list.
| self | root of the list | |
| head | expected head of the list |
| LLIST_FUNC | ( | int | llist_is_tailconst_LList self, const_LList tail, | |
| return self-> | prev = =tail; | |||
| ) |
Check for the tail of a list.
| self | root of the list | |
| tail | expected tail of the list |
| LLIST_FUNC | ( | int | llist_is_endconst_LList self, const_LList end, | |
| return | self = =end; | |||
| ) |
Check for the end of a list.
The end is by definition one past the tail of a list, which is the root node itself.
| self | root node of the list | |
| end | expected end of the list |
| LLIST_FUNC | ( | int | llist_is_memberconst_LList self, const_LList member | ) |
Check if a node is a member of a list.
| self | root node of the list | |
| member | node to be searched |
| LLIST_FUNC | ( | int | llist_is_before_afterconst_LList self, const_LList before, const_LList after | ) |
Check the order of elements in a list.
| self | root node of the list | |
| before | expected to be before after | |
| after | expected to be after before |
| LLIST_FUNC | ( | unsigned | llist_countconst_LList self, | |
| unsigned | cnt = 0;const_LList i=self;for(;i->next!=self;++cnt, i=i->next);return cnt; | |||
| ) |
Count the nodes of a list.
| self | root node of the list |
| LLIST_FUNC | ( | LList | llist_unlinkLList self, | |
| llist_unlink_fast_(self);return self-> | next = self->prev=self; | |||
| ) |
Remove a node from a list.
| self | node to be removed |
| LLIST_FUNC | ( | LList | llist_relocateLList self, | |
| return self->next-> | prev = self->prev->next=self; | |||
| ) |
Fix a node which got relocated in memory.
It is supported to realloc/move list nodes in memory but one must call 'list_relocate' after doing so. IMPORTANT: it is not possible to relocate nodes which are empty this way, nor can this be determined after the relocation, so either llist_init them afterwards or insert a bogus node before moving the node and relocating it and remove it afterwards.
| self | node which got relocated |
| LLIST_FUNC | ( | LList | llist_insert_nextLList self, LList next, | |
| llist_unlink_fast_(next);self->next-> | prev = next;next->prev=self;next->next=self->next;self->next=next;return self; | |||
| ) |
Insert a node after another.
| self | node after which we want to insert | |
| next | node which shall be inserted after self. Could already linked to a list from where it will be removed. |
| LLIST_FUNC | ( | LList | llist_insert_prevLList self, LList prev, | |
| llist_unlink_fast_(prev);self->prev-> | next = prev;prev->next=self;prev->prev=self->prev;self->prev=prev;return self; | |||
| ) |
Insert a node before another.
| self | node before which we want to insert | |
| prev | node which shall be inserted before self. Could already linked to a list from where it will be removed. |
| LLIST_FUNC | ( | LList | llist_insertlist_nextLList self, LList next | ) |
Move the content of a list after a node in another list.
| self | node after which we want to insert a list | |
| next | rootnode of the list which shall be inserted after self |
| LLIST_FUNC | ( | LList | llist_insertlist_prevLList self, LList prev | ) |
Move the content of a list before a node in another list.
| self | node before which we want to insert a list | |
| prev | rootnode of the list which shall be inserted before self |
| LLIST_FUNC | ( | LList | llist_advanceLList self, | |
| LList | tmp = self->next->next;tmp->prev=self;self->next->prev=self->prev;self->prev->next=self->next;self->prev=self->next;self->next->next=self;self->next=tmp;return self; | |||
| ) |
Swap a node with its next node.
Swap a node with its previous node.
| self | node to be advaced |
| self | node to be retreated |
| LLIST_FUNC | ( | LList | llist_nextconst_LList self, | |
| return self->next; | ||||
| ) |
Get next node.
| self | current node |
| LLIST_FUNC | ( | LList | llist_prevconst_LList self, | |
| return self->prev; | ||||
| ) |
Get previous node.
| self | current node |
| LLIST_FUNC | ( | void | llist_forwardLList_ref self, | |
| * | self = (*self)->next; | |||
| ) |
Advance a pointer to a node to its next node.
Retreat a pointer to a node to its previous node.
| self | pointer-to-pointer to the current node *self will point to the next node after this call | |
| self | pointer-to-pointer to the current node *self will point to the previous node after this call |
| LLIST_FUNC | ( | LList | llist_nthLList self, int n, | |
| if(n >0) while(n--) | self = llist_next(self);else while(n++) self=llist_prev(self);return self; | |||
| ) |
Get the nth element of a list.
| self | list to be queried | |
| n | nth element after (positive n) or before (negative n) self this function does not stop at head/tail. |
| LLIST_FUNC | ( | LList | llist_get_nth_stopLList self, int n, const_LList stop | ) |
Get the nth element of a list with a stop node.
| self | list to be queried | |
| n | nth element after (positive n) or before (negative n) self | |
| stop | node which will abort the iteration |
1.5.6