ZEDA  1.6.18
zeda_list.h
Go to the documentation of this file.
1 /* ZEDA - Elementary Data and Algorithms
2  * Copyright (C) 1998 Tomomichi Sugihara (Zhidao)
3  */
9 #ifndef __ZEDA_LIST_H__
10 #define __ZEDA_LIST_H__
11 
12 #include <zeda/zeda_misc.h>
13 
15 
16 /* ********************************************************** *//* ************************************************** */
19 
20 /* ********************************************************** *//* ******************************************************* */
34 
35 #ifdef __cplusplus
36 #define zListClass(list_t,cell_t,data_t) \
37 struct cell_t{\
38  cell_t *prev, *next;\
39  data_t data;\
40  cell_t(){ prev = next = this; };\
41 };\
42 struct list_t{\
43  int size;\
44  cell_t root;\
45  list_t(){ size = 0; };\
46 }
47 #else
48 #define zListClass(list_t,cell_t,data_t) \
49 typedef struct __##cell_t{\
50  struct __##cell_t *prev, *next;\
51  data_t data;\
52 } cell_t;\
53 typedef struct __##list_t{\
54  int size;\
55  cell_t root;\
56 } list_t
57 #endif /* __cplusplus */
58 
59 /* dummy list cell class */
61 
63 #define zListCellPrev(c) (c)->prev
64 
65 #define zListCellNext(c) (c)->next
66 
67 #define zListCellSetPrev(c,p) ( zListCellPrev(c) = (p) )
68 
69 #define zListCellSetNext(c,n) ( zListCellNext(c) = (n) )
70 
72 #define zListCellInit(c) do{\
73  zListCellSetNext( c, c ); \
74  zListCellSetPrev( c, c ); \
75 } while(0)
76 
79 #define zListCellBind(l,f) do{\
80  zListCellSetPrev( f, l ); \
81  zListCellSetNext( l, f ); \
82 } while(0)
83 
85 #define zListCellInsertNext(c,n) do{\
86  zListCellBind( n, zListCellNext(c) ); \
87  zListCellBind( c, n ); \
88 } while(0)
89 
91 #define zListCellInsertPrev(c,p) do{\
92  zListCellBind( zListCellPrev(c), p ); \
93  zListCellBind( p, c ); \
94 } while(0)
95 
97 #define zListCellPurge(c) do{\
98  zListCellBind( zListCellPrev((c)), zListCellNext((c)) ); \
99  zListCellInit( (c) ); \
100 } while(0)
101 
104 #define zListCellDeleteNext(c,n) do{\
105  if( zListCellNext(c) != (c) ){ \
106  *(n) = zListCellNext( c ); \
107  zListCellPurge( *(n) );\
108  } else\
109  *(n) = NULL;\
110 } while(0)
111 
114 #define zListCellDeletePrev(c,p) do{\
115  if( zListCellPrev(c) != (c) ){ \
116  *(p) = zListCellPrev( c ); \
117  zListCellPurge( *(p) );\
118  } else\
119  *(p) = NULL;\
120 } while(0)
121 
124 #define zListCellSwap(cell_t,c1,c2) do{\
125  cell_t *__zlist_cell_swap_tmp; \
126  \
127  __zlist_cell_swap_tmp = zListCellPrev( c1 ); \
128  zListCellBind( zListCellPrev(c2), c1 ); \
129  zListCellBind( __zlist_cell_swap_tmp, c2 ); \
130  __zlist_cell_swap_tmp = zListCellNext( c1 ); \
131  zListCellBind( c1, zListCellNext(c2) ); \
132  zListCellBind( c2, __zlist_cell_swap_tmp ); \
133 } while(0)
134 
135 #ifndef __KERNEL__
136 
138 #define zListCellFPrint(f,c) do{\
139  fprintf( f, "cell [%p] ", c ); \
140  fprintf( f, "%p <- prev | next-> %p\n", \
141  zListCellPrev(c), zListCellNext(c) ); \
142 } while(0)
143 
145 #define zListCellPrint(c) zListCellFPrint( stdout, c )
146 #else
147 #define zListCellPrint(c) do{\
148  printk( "cell [%p] ", c ); \
149  printk( "%p <- prev | next-> %p\n", \
150  zListCellPrev(c), zListCellNext(c) ); \
151 } while(0)
152 #endif /* __KERNEL__ */
153 
154 /* ********************************************************** */
155 /* bidirectional ring list structure
156  * ********************************************************** */
157 
159 #define zListSize(l) (l)->size
160 
161 #define zListRoot(l) ( &(l)->root )
162 
163 #define zListHead(l) zListCellPrev( zListRoot( l ) )
164 
165 #define zListTail(l) zListCellNext( zListRoot( l ) )
166 
168 #define zListSetSize(l,n) ( zListSize(l) = (n) )
169 
170 #define zListIncSize(l) ( zListSize(l)++ )
171 
172 #define zListDecSize(l) ( zListSize(l)-- )
173 
175 #define zListIsEmpty(l) ( zListSize(l) == 0 )
176 
178 #define zListInit(l) do{\
179  zListSetSize( l, 0 ); \
180  zListCellInit( zListRoot( l ) ); \
181 } while(0)
182 
184 #define zListDestroy(t,l) do{\
185  t *__zlist_destroy_cell = NULL; \
186  \
187  while( !zListIsEmpty( l ) ){ \
188  zListDeleteHead( l, &__zlist_destroy_cell ); \
189  zFree( __zlist_destroy_cell ); \
190  } \
191 } while(0)
192 
194 #define zListInsertNext(l,c,n) do{\
195  zListCellInsertNext( c, n ); \
196  zListIncSize(l); \
197 } while(0)
198 
200 #define zListInsertPrev(l,c,p) do{\
201  zListCellInsertPrev( c, p ); \
202  zListIncSize(l); \
203 } while(0)
204 
206 #define zListInsertHead(l,c) zListInsertPrev( l, zListRoot(l), c )
207 
208 #define zListInsertTail(l,c) zListInsertNext( l, zListRoot(l), c )
209 
212 #define zListDeleteNext(l,c,n) do{\
213  zListCellDeleteNext( c, n ); \
214  zListDecSize(l); \
215 } while(0)
216 
219 #define zListDeletePrev(l,c,p) do{\
220  zListCellDeletePrev( c, p ); \
221  zListDecSize(l); \
222 } while(0)
223 
226 #define zListDeleteHead(l,c) zListDeletePrev( l, zListRoot(l), c )
227 
229 #define zListDeleteTail(l,c) zListDeleteNext( l, zListRoot(l), c )
230 
232 #define zListPurge(l,c) do{\
233  zListCellPurge( c );\
234  zListDecSize(l);\
235 } while(0)
236 
239 #define zListAppendA(a,p) do{\
240  if( !zListIsEmpty(p) ){\
241  zListCellBind( zListHead(a), zListTail(p) );\
242  zListCellBind( zListHead(p), zListRoot(a) );\
243  zListSize(a) += zListSize(p);\
244  zListInit(p);\
245  }\
246 } while(0)
247 
250 #define zListAppendZ(a,p) do{\
251  if( !zListIsEmpty(p) ){\
252  zListCellBind( zListHead(p), zListTail(a) );\
253  zListCellBind( zListRoot(a), zListTail(p) );\
254  zListSize(a) += zListSize(p);\
255  zListInit(p);\
256  }\
257 } while(0)
258 
259 #define zListAppend(a,p) zListAppendZ(a,p)
260 
262 #define zListMove(src,dst) do{\
263  zListCellBind( zListRoot(dst), zListTail(src) );\
264  zListCellBind( zListHead(src), zListRoot(dst) );\
265  zListSetSize( dst, zListSize(src) );\
266  zListInit( src );\
267 } while(0)
268 
271 #define zListSwap(cell_t,l1,l2) do{\
272  int __tmpsize;\
273  zListCellSwap( cell_t, zListRoot(l1), zListRoot(l2) );\
274  __tmpsize = zListSize(l1);\
275  zListSetSize( l1, zListSize(l2) );\
276  zListSetSize( l2, __tmpsize );\
277 } while(0)
278 
281 #define zListToHead(l,c) \
282  for( ; (c)!=zListRoot(l); (c)=zListCellNext(c) )
283 
285 #define zListToTail(l,c) \
286  for( ; (c)!=zListRoot(l); (c)=zListCellPrev(c) )
287 
289 #define zListForEach(l,c) \
290  for( (c)=zListTail(l); (c)!=zListRoot(l); (c)=zListCellNext(c) )
291 
293 #define zListForEachRew(l,c) \
294  for( (c)=zListHead(l); (c)!=zListRoot(l); (c)=zListCellPrev(c) )
295 
299 #define zListItem(list,i,cp) do{\
300  int __z_list_item_tmp;\
301  *(cp) = NULL;\
302  if( (i) >= 0 && (i) < zListSize(list) ){\
303  if( (i) <= zListSize(list) - (i) ){\
304  __z_list_item_tmp = 0;\
305  zListForEach( list, *(cp) )\
306  if( __z_list_item_tmp++ == (i) ) break;\
307  } else{\
308  __z_list_item_tmp = zListSize( list );\
309  zListForEachRew( list, *(cp) )\
310  if( --__z_list_item_tmp == (i) ) break;\
311  }\
312  }\
313 } while(0)
314 
333 #define zListQuickSortDef(list_t, cell_t) \
334 static void _##list_t##InnerQuickSort(cell_t *head, cell_t *tail, int (*cmp)(void*,void*,void*), void *priv);\
335 void _##list_t##InnerQuickSort(cell_t *head, cell_t *tail, int (*cmp)(void*,void*,void*), void *priv)\
336 {\
337  cell_t *hp, *tp, *pivot, *p;\
338 \
339  for( pivot=hp=head, tp=tail; ; ){\
340  /* choose a pivot for the head value */\
341  while( cmp( (void *)hp, (void *)pivot, priv ) > 0 && hp != tail )\
342  hp = zListCellPrev( hp );\
343  while( cmp( (void *)tp, (void *)pivot, priv ) < 0 && tp != head )\
344  tp = zListCellNext( tp );\
345  if( hp == tp || hp == zListCellPrev( tp ) )\
346  break;\
347  zListCellSwap( cell_t, hp, tp );\
348  /* if head or tail is swapped, it should be renewed. */\
349  if( hp == head ) head = tp;\
350  if( tail == tp ) tail = hp;\
351  p = zListCellNext( hp );\
352  hp = zListCellPrev( tp );\
353  tp = p;\
354  }\
355  if( hp != head )\
356  _##list_t##InnerQuickSort( head, zListCellNext(hp), cmp, priv );\
357  if( tp != tail )\
358  _##list_t##InnerQuickSort( zListCellPrev(tp), tail, cmp, priv );\
359 }\
360 \
361 list_t *list_t##QuickSort(list_t *list, int (* cmp)(void*,void*,void*), void *priv)\
362 {\
363  _##list_t##InnerQuickSort( zListHead(list), zListTail(list), cmp, priv );\
364  return list;\
365 }
366 
390 #ifndef __KERNEL__
391 __EXPORT void _zListFPrint(FILE *fp, zList *list);
392 #define zListFPrint(f,l) _zListFPrint( f, (zList *)(l) )
393 #define zListPrint(l) zListFPrint( stdout, l )
394 #else
395 void zListPrint(zList *list);
396 #endif /* __KERNEL__ */
397 
398 /* zStack/zQueue alias */
399 
401 #define zStackPush(s,v) zListInsertHead(s,v)
402 
403 #define zStackPop(s,c) zListDeleteHead(s,c)
404 
406 #define zQueueEnqueue(q,v) zListInsertTail(q,v)
407 
408 #define zQueueDequeue(q,c) zListDeleteHead(q,c)
409 
414 
416 __EXPORT bool zIntListAdd(zIntList *list, int i);
417 
419 
420 #endif /* __ZEDA_LIST_H__ */
Definition: zeda_list.h:60
Definition: zeda_list.h:413
a list of integer numbers
Definition: zeda_list.h:413
#define __END_DECLS
Definition: zeda_defs.h:30
miscellanies.
bool zIntListAdd(zIntList *list, int i)
a list of integer numbers
#define zListPrint(l)
Definition: zeda_list.h:393
#define __BEGIN_DECLS
Definition: zeda_defs.h:26
#define zListClass(list_t, cell_t, data_t)
generate bidirectional ring list class.
Definition: zeda_list.h:48
#define __EXPORT
Definition: zeda_compat.h:32
Definition: zeda_list.h:60
void _zListFPrint(FILE *fp, zList *list)
print connection information of a list.