00001
00002
00003
00004
00005
00006
00007 #ifndef _PS_LISTS_H
00008 #define _PS_LISTS_H
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035 #define MACRO_BEGIN do {
00036 #define MACRO_END } while (0)
00037
00038
00039
00040
00041
00042 #define list_forall(elt, list) for (elt=list; elt!=NULL; elt=elt->next)
00043
00044
00045
00046 #define list_find(elt, list, c) \
00047 MACRO_BEGIN list_forall(elt, list) if (c) break; MACRO_END
00048
00049
00050 #define list_forall2(elt, list, hook) \
00051 for (elt=list, hook=&list; elt!=NULL; hook=&elt->next, elt=elt->next)
00052
00053
00054 #define list_find2(elt, list, c, hook) \
00055 MACRO_BEGIN list_forall2(elt, list, hook) if (c) break; MACRO_END
00056
00057
00058 #define _list_forall_hook(list, hook) \
00059 for (hook=&list; *hook!=NULL; hook=&(*hook)->next)
00060
00061
00062 #define _list_find_hook(list, c, hook) \
00063 MACRO_BEGIN _list_forall_hook(list, hook) if (c) break; MACRO_END
00064
00065
00066 #define list_insert_athook(elt, hook) \
00067 MACRO_BEGIN elt->next = *hook; *hook = elt; MACRO_END
00068
00069
00070 #define list_insert_beforehook(elt, hook) \
00071 MACRO_BEGIN elt->next = *hook; *hook = elt; hook=&elt->next; MACRO_END
00072
00073
00074
00075 #define list_unlink_athook(list, elt, hook) \
00076 MACRO_BEGIN \
00077 elt = hook ? *hook : NULL; if (elt) { *hook = elt->next; elt->next = NULL; }\
00078 MACRO_END
00079
00080
00081
00082 #define list_unlink(listtype, list, elt) \
00083 MACRO_BEGIN \
00084 listtype **_hook; \
00085 _list_find_hook(list, *_hook==elt, _hook); \
00086 list_unlink_athook(list, elt, _hook); \
00087 MACRO_END
00088
00089
00090 #define list_prepend(list, elt) \
00091 MACRO_BEGIN elt->next = list; list = elt; MACRO_END
00092
00093
00094 #define list_append(listtype, list, elt) \
00095 MACRO_BEGIN \
00096 listtype **_hook; \
00097 _list_forall_hook(list, _hook) {} \
00098 list_insert_athook(elt, _hook); \
00099 MACRO_END
00100
00101
00102 #define list_unlink_cond(listtype, list, elt, c) \
00103 MACRO_BEGIN \
00104 listtype **_hook; \
00105 list_find2(elt, list, c, _hook); \
00106 list_unlink_athook(list, elt, _hook); \
00107 MACRO_END
00108
00109
00110
00111 #define list_nth(elt, list, n) \
00112 MACRO_BEGIN \
00113 int _x; \
00114 for (_x=(n), elt=list; _x && elt; _x--, elt=elt->next) {} \
00115 MACRO_END
00116
00117
00118
00119 #define list_nth_hook(elt, list, n, hook) \
00120 MACRO_BEGIN \
00121 int _x; \
00122 for (_x=(n), elt=list, hook=&list; _x && elt; _x--, hook=&elt->next, elt=elt->next) {} \
00123 MACRO_END
00124
00125
00126 #define list_length(listtype, list, n) \
00127 MACRO_BEGIN \
00128 listtype *_elt; \
00129 n=0; \
00130 list_forall(_elt, list) \
00131 n++; \
00132 MACRO_END
00133
00134
00135
00136 #define list_index(list, n, elt, c) \
00137 MACRO_BEGIN \
00138 n=0; \
00139 list_forall(elt, list) { \
00140 if (c) break; \
00141 n++; \
00142 } \
00143 if (!elt) \
00144 n=-1; \
00145 MACRO_END
00146
00147
00148 #define list_count(list, n, elt, c) \
00149 MACRO_BEGIN \
00150 n=0; \
00151 list_forall(elt, list) { \
00152 if (c) n++; \
00153 } \
00154 MACRO_END
00155
00156
00157 #define list_forall_unlink(elt, list) \
00158 for (elt=list; elt ? (list=elt->next, elt->next=NULL), 1 : 0; elt=list)
00159
00160
00161 #define list_reverse(listtype, list) \
00162 MACRO_BEGIN \
00163 listtype *_list1=NULL, *elt; \
00164 list_forall_unlink(elt, list) \
00165 list_prepend(_list1, elt); \
00166 list = _list1; \
00167 MACRO_END
00168
00169
00170
00171
00172
00173
00174
00175
00176
00177
00178
00179
00180 #define list_insert_ordered(listtype, list, elt, tmp, cond) \
00181 MACRO_BEGIN \
00182 listtype **_hook; \
00183 _list_find_hook(list, (tmp=*_hook, (cond)), _hook); \
00184 list_insert_athook(elt, _hook); \
00185 MACRO_END
00186
00187
00188
00189
00190
00191
00192
00193
00194 #define list_sort(listtype, list, a, b, cond) \
00195 MACRO_BEGIN \
00196 listtype *_newlist=NULL; \
00197 list_forall_unlink(a, list) \
00198 list_insert_ordered(listtype, _newlist, a, b, cond); \
00199 list = _newlist; \
00200 MACRO_END
00201
00202
00203
00204
00205
00206
00207 #define list_mergesort(listtype, list, a, b, cond) \
00208 MACRO_BEGIN \
00209 listtype *_elt, **_hook1; \
00210 \
00211 for (_elt=list; _elt; _elt=_elt->next1) { \
00212 _elt->next1 = _elt->next; \
00213 _elt->next = NULL; \
00214 } \
00215 do { \
00216 _hook1 = &(list); \
00217 while ((a = *_hook1) != NULL && (b = a->next1) != NULL ) { \
00218 _elt = b->next1; \
00219 _list_merge_cond(listtype, a, b, cond, *_hook1); \
00220 _hook1 = &((*_hook1)->next1); \
00221 *_hook1 = _elt; \
00222 } \
00223 } while (_hook1 != &(list)); \
00224 MACRO_END
00225
00226
00227 #define _list_merge_cond(listtype, a, b, cond, result) \
00228 MACRO_BEGIN \
00229 listtype **_hook; \
00230 _hook = &(result); \
00231 while (1) { \
00232 if (a==NULL) { \
00233 *_hook = b; \
00234 break; \
00235 } else if (b==NULL) { \
00236 *_hook = a; \
00237 break; \
00238 } else if (cond) { \
00239 *_hook = a; \
00240 _hook = &(a->next); \
00241 a = a->next; \
00242 } else { \
00243 *_hook = b; \
00244 _hook = &(b->next); \
00245 b = b->next; \
00246 } \
00247 } \
00248 MACRO_END
00249
00250
00251
00252
00253 #define dlist_append(head, end, elt) \
00254 MACRO_BEGIN \
00255 elt->prev = end; \
00256 elt->next = NULL; \
00257 if (end) { \
00258 end->next = elt; \
00259 } else { \
00260 head = elt; \
00261 } \
00262 end = elt; \
00263 MACRO_END
00264
00265
00266 #define dlist_forall_unlink(elt, head, end) \
00267 for (elt=head; elt ? (head=elt->next, elt->next=NULL, elt->prev=NULL), 1 : (end=NULL, 0); elt=head)
00268
00269
00270 #define dlist_unlink_first(head, end, elt) \
00271 MACRO_BEGIN \
00272 elt = head; \
00273 if (head) { \
00274 head = head->next; \
00275 if (head) { \
00276 head->prev = NULL; \
00277 } else { \
00278 end = NULL; \
00279 } \
00280 elt->prev = NULL; \
00281 elt->next = NULL; \
00282 } \
00283 MACRO_END
00284
00285 #endif
00286