]> mj.ucw.cz Git - libucw.git/blob - lib/clists.h
Improved and cleaned up the bucket library. The original "single operation
[libucw.git] / lib / clists.h
1 /*
2  *      Sherlock Library -- Circular Linked Lists
3  *
4  *      (c) 2003 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 _SHERLOCK_CLISTS_H
11 #define _SHERLOCK_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
49 static inline void clist_insert_after(cnode *what, cnode *after)
50 {
51   cnode *before = after->next;
52   what->next = before;
53   what->prev = after;
54   before->prev = what;
55   after->next = what;
56 }
57
58 static inline void clist_insert_before(cnode *what, cnode *before)
59 {
60   cnode *after = before->prev;
61   what->next = before;
62   what->prev = after;
63   before->prev = what;
64   after->next = what;
65 }
66
67 static inline void clist_add_tail(clist *l, cnode *n)
68 {
69   clist_insert_before(n, &l->head);
70 }
71
72 static inline void clist_add_head(clist *l, cnode *n)
73 {
74   clist_insert_after(n, &l->head);
75 }
76
77 static inline void clist_remove(cnode *n)
78 {
79   cnode *before = n->prev;
80   cnode *after = n->next;
81   before->next = after;
82   after->prev = before;
83 }
84
85 static inline void clist_init(clist *l)
86 {
87   cnode *head = &l->head;
88   head->next = head->prev = head;
89 }
90
91 #endif