csnip  0.1
list.h
Go to the documentation of this file.
1 #ifndef CSNIP_LIST_H
2 #define CSNIP_LIST_H
3 
33 #include <assert.h>
34 #include <stddef.h>
35 
36 #include <csnip/preproc.h>
37 
62 #define csnip_dlist_Init(head, tail, mprev, mnext) \
63  do { \
64  (head) = (tail) = NULL; \
65  } while (0)
66 
71 #define csnip_dlist_IsEmpty(head, tail, mprev, mnext) \
72  ((head) == NULL)
73 
75 #define csnip_dlist_PushHead(head, tail, mprev, mnext, el) \
76  do { \
77  assert((el) != NULL); \
78  if ((head) != NULL) { \
79  (head)->mprev = (el); \
80  } else { \
81  assert((tail) == NULL); \
82  (tail) = (el); \
83  } \
84  (el)->mnext = (head); \
85  (el)->mprev = NULL; \
86  (head) = (el); \
87  } while (0)
88 
95 #define csnip_dlist_PopHead(head, tail, mprev, mnext) \
96  do { \
97  assert((head) != NULL); \
98  (head) = (head)->mnext; \
99  if ((head) != NULL) { \
100  (head)->mprev = NULL; \
101  } else { \
102  (tail) = NULL; \
103  } \
104  } while (0)
105 
107 #define csnip_dlist_PushTail(head, tail, mprev, mnext, el) \
108  do { \
109  if ((head) == NULL) { \
110  assert((tail) == NULL); \
111  (head) = (el); \
112  } else { \
113  (tail)->mnext = (el); \
114  } \
115  (el)->mprev = (tail); \
116  (el)->mnext = NULL; \
117  (tail) = el; \
118  } while (0)
119 
124 #define csnip_dlist_PopTail(head, tail, mprev, mnext) \
125  do { \
126  assert((tail) != NULL); \
127  (tail) = (tail)->mprev; \
128  if ((tail) != NULL) { \
129  (tail)->mnext = NULL; \
130  } else { \
131  (head) = NULL; \
132  } \
133  } while (0)
134 
146 #define csnip_dlist_InsertAfter(head, tail, mprev, mnext, loc, el) \
147  do { \
148  (el)->mprev = (loc); \
149  (el)->mnext = (loc)->mnext; \
150  if ((loc)->mnext != NULL) { \
151  (loc)->mnext->mprev = (el); \
152  } else { \
153  assert((loc) == (tail)); \
154  (tail) = (el); \
155  } \
156  (loc)->mnext = (el); \
157  } while (0)
158 
171 #define csnip_dlist_InsertBefore(head, tail, mprev, mnext, loc, el) \
172  do { \
173  (el)->mnext = (loc); \
174  (el)->mprev = (loc)->mprev; \
175  if ((loc)->mprev != NULL) { \
176  (loc)->mprev->mnext = (el); \
177  } else { \
178  assert((loc) == (head)); \
179  (head) = (el); \
180  } \
181  (loc)->mprev = (el); \
182  } while (0)
183 
190 #define csnip_dlist_Remove(head, tail, mprev, mnext, el) \
191  do { \
192  if ((el)->mprev != NULL) { \
193  (el)->mprev->mnext = (el)->mnext; \
194  } else { \
195  assert((el) == (head)); \
196  (head) = (el)->mnext; \
197  } \
198  if ((el)->mnext != NULL) { \
199  (el)->mnext->mprev = (el)->mprev; \
200  } else { \
201  assert((el) == (tail)); \
202  (tail) = (el)->mprev; \
203  } \
204  } while (0)
205 
213 #define CSNIP_DLIST_DECL_FUNCS(scope, prefix, entry_ptr_type, gen_args) \
214  scope void prefix ## init(csnip_pp_list_##gen_args); \
215  scope char prefix ## is_empty(csnip_pp_list_##gen_args); \
216  scope void prefix ## push_head(csnip_pp_prepend_##gen_args \
217  entry_ptr_type csnip_el); \
218  scope void prefix ## pop_head(csnip_pp_list_##gen_args); \
219  scope void prefix ## push_tail(csnip_pp_prepend_##gen_args \
220  entry_ptr_type csnip_el); \
221  scope void prefix ## pop_tail(csnip_pp_list_##gen_args); \
222  scope void prefix ## insert_after(csnip_pp_prepend_##gen_args \
223  entry_ptr_type csnip_loc, \
224  entry_ptr_type csnip_el); \
225  scope void prefix ## insert_before(csnip_pp_prepend_##gen_args \
226  entry_ptr_type csnip_loc, \
227  entry_ptr_type csnip_el); \
228  scope void prefix ## remove(csnip_pp_prepend_##gen_args \
229  entry_ptr_type csnip_el); \
230  \
231  /* functions without corresponding macros */ \
232  scope entry_ptr_type prefix ## head(csnip_pp_list_##gen_args); \
233  scope entry_ptr_type prefix ## tail(csnip_pp_list_##gen_args); \
234  scope entry_ptr_type prefix ## prev(entry_ptr_type csnip_el); \
235  scope entry_ptr_type prefix ## next(entry_ptr_type csnip_el); \
236 
279 #define CSNIP_DLIST_DEF_FUNCS(scope, prefix, entry_ptr_type, gen_args, \
280  phead, ptail, mprev, mnext) \
281  scope void prefix ## init(csnip_pp_list_##gen_args) \
282  { \
283  csnip_dlist_Init(phead, ptail, mprev, mnext); \
284  } \
285  scope char prefix ## is_empty(csnip_pp_list_##gen_args) { \
286  return csnip_dlist_IsEmpty(phead, ptail, mprev, mnext); \
287  } \
288  scope void prefix ## push_head(csnip_pp_prepend_##gen_args \
289  entry_ptr_type csnip_el) \
290  { \
291  csnip_dlist_PushHead(phead, ptail, mprev, mnext, csnip_el); \
292  } \
293  scope void prefix ## pop_head(csnip_pp_list_##gen_args) \
294  { \
295  csnip_dlist_PopHead(phead, ptail, mprev, mnext); \
296  } \
297  scope void prefix ## push_tail(csnip_pp_prepend_##gen_args \
298  entry_ptr_type csnip_el) \
299  { \
300  csnip_dlist_PushTail(phead, ptail, mprev, mnext, csnip_el); \
301  } \
302  scope void prefix ## pop_tail(csnip_pp_list_##gen_args) \
303  { \
304  csnip_dlist_PopTail(phead, ptail, mprev, mnext); \
305  } \
306  scope void prefix ## insert_after(csnip_pp_prepend_##gen_args \
307  entry_ptr_type csnip_loc, \
308  entry_ptr_type csnip_el) \
309  { \
310  csnip_dlist_InsertAfter(phead, ptail, mprev, mnext, \
311  csnip_loc, csnip_el); \
312  } \
313  scope void prefix ## insert_before(csnip_pp_prepend_##gen_args \
314  entry_ptr_type csnip_loc, \
315  entry_ptr_type csnip_el) \
316  { \
317  csnip_dlist_InsertBefore(phead, ptail, mprev, mnext, \
318  csnip_loc, csnip_el); \
319  } \
320  scope void prefix ## remove(csnip_pp_prepend_##gen_args \
321  entry_ptr_type csnip_el) \
322  { \
323  csnip_dlist_Remove(phead, ptail, mprev, mnext, csnip_el); \
324  } \
325  \
326  /* functions without corresponding macros */ \
327  scope entry_ptr_type prefix ## head(csnip_pp_list_##gen_args) { \
328  return phead; \
329  } \
330  scope entry_ptr_type prefix ## tail(csnip_pp_list_##gen_args) { \
331  return ptail; \
332  } \
333  scope entry_ptr_type prefix ## prev(entry_ptr_type csnip_el) { \
334  return csnip_el->mprev; \
335  } \
336  scope entry_ptr_type prefix ## next(entry_ptr_type csnip_el) { \
337  return csnip_el->mnext; \
338  }
339 
347 #define csnip_slist_Init(head, tail, mnext) \
348  do { \
349  (head) = (tail) = NULL; \
350  } while (0)
351 
353 #define csnip_slist_PushHead(head, tail, mnext, el) \
354  do { \
355  (el)->mnext = (head); \
356  if ((tail) == NULL) { \
357  assert((head) == NULL); \
358  (tail) = (el); \
359  } \
360  (head) = (el); \
361  } while (0)
362 
369 #define csnip_slist_PopHead(head, tail, mnext) \
370  do { \
371  assert((head) != NULL); \
372  if ((tail) == (head)) { \
373  (head) = (tail) = NULL; \
374  } else { \
375  (head) = (head)->mnext; \
376  } \
377  } while (0)
378 
380 #define csnip_slist_PushTail(head, tail, mnext, el) \
381  do { \
382  if ((head) == NULL) { \
383  assert((tail) == NULL); \
384  (head) = (tail) = (el); \
385  } else { \
386  (tail)->mnext = (el); \
387  (tail) = (el); \
388  } \
389  (el)->mnext = NULL; \
390  } while (0)
391 
403 #define csnip_slist_InsertAfter(head, tail, mnext, loc, el) \
404  do { \
405  (el)->mnext = (loc)->mnext; \
406  (loc)->mnext = (el); \
407  if ((el)->mnext == NULL) { \
408  (tail) = (el); \
409  } \
410  } while (0)
411 
420 #define CSNIP_SLIST_DECL_FUNCS(scope, prefix, entry_ptr_type, gen_args) \
421  scope void prefix ## init(csnip_pp_list_##gen_args); \
422  scope void prefix ## push_head(csnip_pp_prepend_##gen_args \
423  entry_ptr_type csnip_el); \
424  scope void prefix ## pop_head(csnip_pp_list_##gen_args); \
425  scope void prefix ## push_tail(csnip_pp_prepend_##gen_args \
426  entry_ptr_type csnip_el); \
427  scope void prefix ## insert_after(csnip_pp_prepend_##gen_args \
428  entry_ptr_type csnip_loc, \
429  entry_ptr_type csnip_el); \
430  \
431  /* functions without corresponding macros */ \
432  scope entry_ptr_type prefix ## head(csnip_pp_list_##gen_args); \
433  scope entry_ptr_type prefix ## tail(csnip_pp_list_##gen_args); \
434  scope entry_ptr_type prefix ## next(entry_ptr_type csnip_el); \
435  scope char prefix ## is_empty(csnip_pp_list_##gen_args); \
436 
474 #define CSNIP_SLIST_DEF_FUNCS(scope, prefix, entry_ptr_type, gen_args, \
475  phead, ptail, mnext) \
476  scope void prefix ## init(csnip_pp_list_##gen_args) \
477  { \
478  csnip_slist_Init(phead, ptail, mnext); \
479  } \
480  scope void prefix ## push_head(csnip_pp_prepend_##gen_args \
481  entry_ptr_type csnip_el) \
482  { \
483  csnip_slist_PushHead(phead, ptail, mnext, csnip_el); \
484  } \
485  scope void prefix ## pop_head(csnip_pp_list_##gen_args) \
486  { \
487  csnip_slist_PopHead(phead, ptail, mnext); \
488  } \
489  scope void prefix ## push_tail(csnip_pp_prepend_##gen_args \
490  entry_ptr_type csnip_el) \
491  { \
492  csnip_slist_PushTail(phead, ptail, mnext, csnip_el); \
493  } \
494  scope void prefix ## insert_after(csnip_pp_prepend_##gen_args \
495  entry_ptr_type csnip_loc, \
496  entry_ptr_type csnip_el) \
497  { \
498  csnip_slist_InsertAfter(phead, ptail, mnext, \
499  csnip_loc, csnip_el); \
500  } \
501  \
502  /* functions without corresponding macros */ \
503  scope entry_ptr_type prefix ## head(csnip_pp_list_##gen_args) { \
504  return phead; \
505  } \
506  scope entry_ptr_type prefix ## tail(csnip_pp_list_##gen_args) { \
507  return ptail; \
508  } \
509  scope entry_ptr_type prefix ## next(entry_ptr_type csnip_el) { \
510  return csnip_el->mnext; \
511  } \
512  scope char prefix ## is_empty(csnip_pp_list_##gen_args) { \
513  return phead == NULL; \
514  }
515 
519 #endif /* CSNIP_LIST_H */
520 
521 #if defined(CSNIP_SHORT_NAMES) && !defined(CSNIP_LIST_HAVE_SHORT_NAMES)
522 #define dlist_Init csnip_dlist_Init
523 #define dlist_IsEmpty csnip_dlist_IsEmpty
524 #define dlist_PushHead csnip_dlist_PushHead
525 #define dlist_PopHead csnip_dlist_PopHead
526 #define dlist_PushTail csnip_dlist_PushTail
527 #define dlist_PopTail csnip_dlist_PopTail
528 #define dlist_InsertAfter csnip_dlist_InsertAfter
529 #define dlist_InsertBefore csnip_dlist_InsertBefore
530 #define dlist_Remove csnip_dlist_Remove
531 #define slist_Init csnip_slist_Init
532 #define slist_PushHead csnip_slist_PushHead
533 #define slist_PopHead csnip_slist_PopHead
534 #define slist_PushTail csnip_slist_PushTail
535 #define slist_InsertAfter csnip_slist_InsertAfter
536 #define CSNIP_LIST_HAVE_SHORT_NAMES
537 #endif /* CSNIP_SHORT_NAMES && !CSNIP_LIST_HAVE_SHORT_NAMES */