]> mj.ucw.cz Git - libucw.git/blob - lib/clists.h
Merge with git+ssh://git.ucw.cz/projects/sherlock/GIT/sherlock.git
[libucw.git] / lib / clists.h
1 /*
2  *      UCW Library -- Circular Linked Lists
3  *
4  *      (c) 2003--2005 Martin Mares <mj@ucw.cz>
5  *
6  *      This software may be freely distributed and used according to the terms
7  *      of the GNU Lesser General Public License.
8  */
9
10 #ifndef _UCW_CLISTS_H
11 #define _UCW_CLISTS_H
12
13 typedef struct cnode {
14   struct cnode *next, *prev;
15 } cnode;
16
17 typedef struct clist {
18   struct cnode head;
19 } clist;
20
21 static inline void *clist_head(clist *l)
22 {
23   return (l->head.next != &l->head) ? l->head.next : NULL;
24 }
25
26 static inline void *clist_tail(clist *l)
27 {
28   return (l->head.prev != &l->head) ? l->head.prev : NULL;
29 }
30
31 static inline void *clist_next(clist *l, cnode *n)
32 {
33   return (n->next != &l->head) ? (void *) n->next : NULL;
34 }
35
36 static inline void *clist_prev(clist *l, cnode *n)
37 {
38   return (n->prev != &l->head) ? (void *) n->prev : NULL;
39 }
40
41 static inline int clist_empty(clist *l)
42 {
43   return (l->head.next == &l->head);
44 }
45
46 #define CLIST_WALK(n,list) for(n=(void*)(list).head.next; (cnode*)(n) != &(list).head; n=(void*)((cnode*)(n))->next)
47 #define CLIST_WALK_DELSAFE(n,list,tmp) for(n=(void*)(list).head.next; tmp=(void*)((cnode*)(n))->next, (cnode*)(n) != &(list).head; n=(void*)tmp)
48 #define CLIST_FOR_EACH(type,n,list) for(type n=(void*)(list).head.next; (cnode*)(n) != &(list).head; n=(void*)((cnode*)(n))->next)
49 #define CLIST_FOR_EACH_DELSAFE(type,n,list,tmp) for(type n=(void*)(list).head.next; tmp=(void*)((cnode*)(n))->next, (cnode*)(n) != &(list).head; n=(void*)tmp)
50
51 #define CLIST_FOR_EACH_BACKWARDS(type,n,list) for(type n=(void*)(list).head.prev; (cnode*)(n) != &(list).head; n=(void*)((cnode*)(n))->prev)
52
53 static inline void clist_insert_after(cnode *what, cnode *after)
54 {
55   cnode *before = after->next;
56   what->next = before;
57   what->prev = after;
58   before->prev = what;
59   after->next = what;
60 }
61
62 static inline void clist_insert_before(cnode *what, cnode *before)
63 {
64   cnode *after = before->prev;
65   what->next = before;
66   what->prev = after;
67   before->prev = what;
68   after->next = what;
69 }
70
71 static inline void clist_add_tail(clist *l, cnode *n)
72 {
73   clist_insert_before(n, &l->head);
74 }
75
76 static inline void clist_add_head(clist *l, cnode *n)
77 {
78   clist_insert_after(n, &l->head);
79 }
80
81 static inline void clist_remove(cnode *n)
82 {
83   cnode *before = n->prev;
84   cnode *after = n->next;
85   before->next = after;
86   after->prev = before;
87 }
88
89 static inline void clist_init(clist *l)
90 {
91   cnode *head = &l->head;
92   head->next = head->prev = head;
93 }
94
95 static inline void clist_insert_list_after(clist *what, cnode *after)
96 {
97   if (!clist_empty(what))
98     {
99       cnode *w = &what->head;
100       w->prev->next = after->next;
101       after->next->prev = w->prev;
102       w->next->prev = after;
103       after->next = w->next;
104       clist_init(what);
105     }
106 }
107
108 #endif