]> git.decadent.org.uk Git - ion3.git/blob - libtu/dlist.h
[svn-inject] Installing original source of ion3
[ion3.git] / libtu / dlist.h
1 /*
2  * libtu/common.h
3  *
4  * Copyright (c) Tuomo Valkonen 1999-2005. 
5  *
6  * You may distribute and modify this library under the terms of either
7  * the Clarified Artistic License or the GNU LGPL, version 2.1 or later.
8  */
9
10 #ifndef LIBTU_DLIST_H
11 #define LIBTU_DLIST_H
12
13
14 /*{{{ Linking */
15
16
17 #define LINK_ITEM(LIST, ITEM, NEXT, PREV) \
18     (ITEM)->NEXT=NULL;                    \
19     if((LIST)==NULL){                     \
20         (LIST)=(ITEM);                    \
21         (ITEM)->PREV=(ITEM);              \
22     }else{                                \
23         (ITEM)->PREV=(LIST)->PREV;        \
24         (ITEM)->PREV->NEXT=(ITEM);        \
25         (LIST)->PREV=(ITEM);              \
26     }
27
28
29 #define LINK_ITEM_FIRST(LIST, ITEM, NEXT, PREV) \
30     (ITEM)->NEXT=(LIST);                        \
31     if((LIST)==NULL){                           \
32         (ITEM)->PREV=(ITEM);                    \
33     }else{                                      \
34         (ITEM)->PREV=(LIST)->PREV;              \
35         (LIST)->PREV=(ITEM);                    \
36     }                                           \
37     (LIST)=(ITEM);
38
39
40 #define LINK_ITEM_LAST LINK_ITEM
41
42
43 #define LINK_ITEM_BEFORE(LIST, BEFORE, ITEM, NEXT, PREV) \
44     (ITEM)->NEXT=(BEFORE);                               \
45     (ITEM)->PREV=(BEFORE)->PREV;                         \
46     (BEFORE)->PREV=(ITEM);                               \
47     if((BEFORE)==(LIST))                                 \
48         (LIST)=(ITEM);                                   \
49     else                                                 \
50         (ITEM)->PREV->NEXT=(ITEM)
51
52
53 #define LINK_ITEM_AFTER(LIST, AFTER, ITEM, NEXT, PREV) \
54     (ITEM)->NEXT=(AFTER)->NEXT;                        \
55     (ITEM)->PREV=(AFTER);                              \
56     (AFTER)->NEXT=(ITEM);                              \
57     if((ITEM)->NEXT==NULL)                             \
58         (LIST)->PREV=(ITEM);                           \
59     else                                               \
60         (ITEM)->NEXT->PREV=ITEM;
61
62
63 #define UNLINK_ITEM(LIST, ITEM, NEXT, PREV)  \
64     if((ITEM)->PREV!=NULL){                  \
65         if((ITEM)==(LIST)){                  \
66             (LIST)=(ITEM)->NEXT;             \
67             if((LIST)!=NULL)                 \
68                 (LIST)->PREV=(ITEM)->PREV;   \
69         }else if((ITEM)->NEXT==NULL){        \
70             (ITEM)->PREV->NEXT=NULL;         \
71             (LIST)->PREV=(ITEM)->PREV;       \
72         }else{                               \
73             (ITEM)->PREV->NEXT=(ITEM)->NEXT; \
74             (ITEM)->NEXT->PREV=(ITEM)->PREV; \
75         }                                    \
76     }                                        \
77     (ITEM)->NEXT=NULL;                       \
78     (ITEM)->PREV=NULL;
79
80
81 /*}}}*/
82
83
84 /*{{{ Iteration */
85
86
87 #define LIST_FIRST(LIST, NEXT, PREV) \
88     (LIST)
89 #define LIST_LAST(LIST, NEXT, PREV) \
90     ((LIST)==NULL ? NULL : LIST_PREV_WRAP(LIST, LIST, NEXT, PREV))
91 #define LIST_NEXT(LIST, REG, NEXT, PREV) \
92     ((REG)->NEXT)
93 #define LIST_PREV(LIST, REG, NEXT, PREV) \
94     ((REG)->PREV->NEXT ? (REG)->PREV : NULL)
95 #define LIST_NEXT_WRAP(LIST, REG, NEXT, PREV) \
96     (((REG) && (REG)->NEXT) ? (REG)->NEXT : (LIST))
97 #define LIST_PREV_WRAP(LIST, REG, NEXT, PREV) \
98     ((REG) ? (REG)->PREV : (LIST))
99
100 #define LIST_FOR_ALL(LIST, NODE, NEXT, PREV) \
101     for(NODE=LIST; NODE!=NULL; NODE=(NODE)->NEXT)
102
103 #define LIST_FOR_ALL_REV(LIST, NODE, NEXT, PREV)     \
104     for(NODE=((LIST)==NULL ? NULL : (LIST)->PREV);   \
105         NODE!=NULL;                                  \
106         NODE=((NODE)==(LIST) ? NULL : (NODE)->PREV))
107
108 #define LIST_FOR_ALL_W_NEXT(LIST, NODE, NXT, NEXT, PREV)  \
109     for(NODE=LL, NXT=(NODE==NULL ? NULL : (NODE)->NEXT);  \
110         NODE!=NULL;                                       \
111         NODE=NXT, NXT=(NODE==NULL ? NULL : (NODE)->NEXT))
112
113 #define LIST_FOR_ALL_W_NEXT_REV(LIST, NODE, NXT, NEXT, PREV) \
114     for(NODE=((LIST)==NULL ? NULL : (LIST)->PREV),           \
115          NXT=((NODE)==(LIST) ? NULL : (NODE)->PREV);         \
116         NODE!=NULL;                                          \
117         NODE=NXT,                                            \
118          NXT=((NODE)==(LIST) ? NULL : (NODE)->PREV))
119
120
121 /*}}}*/
122
123
124 #endif /* LIBTU_DLIST_H */