fork download
  1. #include <stdlib.h>
  2. #include <stdio.h>
  3.  
  4. #define node_add(new, p, n) \
  5.   n->prev = new; \
  6.   new->next = n; \
  7.   new->prev = p; \
  8.   p->next = new
  9.  
  10. #define node_del(p, n) \
  11.   n->prev = p; \
  12.   p->next = n
  13.  
  14. #define list_of(T) \
  15.   struct { \
  16.   T data; \
  17.   void *it; \
  18.   void *prev; \
  19.   void *next; \
  20.   }
  21.  
  22. #define list_alloc(ptr, alloc_func) \
  23.   ({ ptr = alloc_func(sizeof(__typeof__(*ptr))); ptr->prev = ptr; ptr->next = ptr; ptr; })
  24.  
  25. #define list_shift(ptr, value, alloc_func) ({ int __ret = 0; \
  26.   __typeof__(ptr) node = alloc_func(sizeof(__typeof__(*ptr))), next; \
  27.   if (node != NULL) { \
  28.   node->data = value; \
  29.   next = ((__typeof__(ptr)) ptr->next); \
  30.   node_add(node, ptr, next); \
  31.   __ret = 1; \
  32.   }; __ret; })
  33.  
  34. #define list_push(ptr, value, alloc_func) ({ int __ret = 0; \
  35.   __typeof__(ptr) node = alloc_func(sizeof(__typeof__(*ptr))), prev; \
  36.   if (node != NULL) { \
  37.   node->data = value; \
  38.   prev = ((__typeof__(ptr)) ptr->prev); \
  39.   node_add(node, prev, ptr); \
  40.   __ret = 1; \
  41.   }; __ret; })
  42.  
  43. #define list_foreach(ptr, value) for( \
  44.   __typeof__(ptr->data) value = ((__typeof__(ptr))(ptr->it = ptr->next))->data; \
  45.   ptr->it != ptr; \
  46.   value = ((__typeof__(ptr))(ptr->it = ((__typeof__(ptr))ptr->it)->next))->data)
  47.  
  48. #define list_it_free(ptr, free_func) { __typeof__(ptr) it = ptr->it, prev = it->prev, next = it->next; node_del(prev, next); ptr->it = prev; free_func(it); }
  49.  
  50. #define list_clear(ptr, free_func) list_foreach(ptr, value) { list_it_free(ptr, free_func); }
  51.  
  52. #define list_free(ptr, free_func) list_clear(ptr, free_func); free_func(ptr); ptr = NULL
  53.  
  54. int main() {
  55. list_of(int) *list = list_alloc(list, malloc);
  56.  
  57. for (int i = 9; i >= 0; i--) {
  58. list_shift(list, i, malloc);
  59. }
  60. for (int i = 8; i >= 0; i--) {
  61. list_push(list, i, malloc);
  62. }
  63.  
  64. list_foreach(list, value) {
  65. printf("%d\n", value);
  66. if (value % 2 == 0) {
  67. list_it_free(list, free);
  68. }
  69. }
  70.  
  71. printf("\n");
  72. list_foreach(list, value) {
  73. printf("%d\n", value);
  74. }
  75.  
  76. list_clear(list, free);
  77. list_foreach(list, value) {
  78. printf("%d\n", value);
  79. }
  80.  
  81. list_free(list, free);
  82. }
Success #stdin #stdout 0s 2300KB
stdin
Standard input is empty
stdout
0
1
2
3
4
5
6
7
8
9
8
7
6
5
4
3
2
1
0

1
3
5
7
9
7
5
3
1