ROOT-Sim core  3.0.0-rc.2
A General-Purpose Multi-threaded Parallel/Distributed Simulation Library
list.h
Go to the documentation of this file.
1 
11 #pragma once
12 
13 #include <assert.h>
14 #include <memory.h>
15 #include <stddef.h>
16 
18 struct list {
20  size_t size;
22  void *head;
24  void *tail;
25 };
26 
28 #define my_offsetof(st, m) ((size_t)( (unsigned char *)&((st)->m ) - (unsigned char *)(st)))
29 
31 #define list(type) type *
32 
39 #define new_list(type) \
40  __extension__({ \
41  void *__lmptr; \
42  __lmptr = malloc(sizeof(struct list)); \
43  memset(__lmptr, 0, sizeof(struct list));\
44  __lmptr;\
45  })
46 
47 // Get the size of the current list.
48 #define list_sizeof(list) ((struct list *)list)->size
49 
55 #define list_head(li) ((__typeof__ (li))(((struct list *)(li))->head))
56 
62 #define list_tail(li) ((__typeof__ (li))(((struct list *)(li))->tail))
63 
69 #define list_next(ptr) ((ptr)->next)
70 
76 #define list_prev(ptr) ((ptr)->prev)
77 
79 #define get_key(data) ({\
80  char *__key_ptr = ((char *)(data) + __key_position);\
81  double *__key_double_ptr = (double *)__key_ptr;\
82  *__key_double_ptr;\
83  })
84 
91 #define list_empty(list) (((struct list *)list)->size == 0)
92 
93 #define list_insert_tail(li, data) \
94  do { \
95  __typeof__(data) __new_n = (data); /* in-block scope variable */\
96  struct list *__l;\
97  __new_n->next = NULL;\
98  __new_n->prev = NULL;\
99  do {\
100  __l = (struct list *)(li);\
101  assert(__l);\
102  if(__l->size == 0) { /* is the list empty? */\
103  __l->head = __new_n;\
104  __l->tail = __new_n;\
105  break; /* leave the inner do-while */\
106  }\
107  __new_n->next = NULL; /* Otherwise add at the end */\
108  __new_n->prev = __l->tail;\
109  ((__typeof__(data))(__l->tail))->next = __new_n;\
110  __l->tail = __new_n;\
111  } while(0);\
112  __l->size++;\
113  } while(0)
114 
115 #define list_insert_head(li, data) \
116  do { \
117  __typeof__(data) __new_n = (data); /* in-block scope variable */\
118  struct list *__l;\
119  __new_n->next = NULL;\
120  __new_n->prev = NULL;\
121  __l = (struct list *)(li);\
122  assert(__l);\
123  if(__l->size == 0) { /* is the list empty? */\
124  __l->head = __new_n;\
125  __l->tail = __new_n;\
126  }else{\
127  __new_n->prev = NULL; /* Otherwise add at the beginning */\
128  __new_n->next = __l->head;\
129  ((__typeof(data))__l->head)->prev = __new_n;\
130  __l->head = __new_n;\
131  }\
132  __l->size++;\
133  } while(0)
134 
136 #define list_insert(li, key_name, data)\
137  do {\
138  __typeof__(data) __n; /* in-block scope variable */\
139  __typeof__(data) __new_n = (data);\
140  size_t __key_position = my_offsetof((li), key_name);\
141  double __key;\
142  size_t __size_before;\
143  struct list *__l;\
144  do {\
145  __l = (struct list *)(li);\
146  assert(__l);\
147  __size_before = __l->size;\
148  if(__l->size == 0) { /* Is the list empty? */\
149  __new_n->prev = NULL;\
150  __new_n->next = NULL;\
151  __l->head = __new_n;\
152  __l->tail = __new_n;\
153  break;\
154  }\
155  __key = get_key(__new_n); /* Retrieve the new node's key */\
156  /* Scan from the tail, as keys are ordered in an increasing order */\
157  __n = __l->tail;\
158  while(__n != NULL && __key < get_key(__n)) {\
159  __n = __n->prev;\
160  }\
161  /* Insert depending on the position */\
162  if(__n == __l->tail) { /* tail */\
163  __new_n->next = NULL;\
164  ((__typeof(data))__l->tail)->next = __new_n;\
165  __new_n->prev = __l->tail;\
166  __l->tail = __new_n;\
167  } else if(__n == NULL) { /* head */\
168  __new_n->prev = NULL;\
169  __new_n->next = __l->head;\
170  ((__typeof(data))__l->head)->prev = __new_n;\
171  __l->head = __new_n;\
172  } else { /* middle */\
173  __new_n->prev = __n;\
174  __new_n->next = __n->next;\
175  __n->next->prev = __new_n;\
176  __n->next = __new_n;\
177  }\
178  } while(0);\
179  __l->size++;\
180  assert(__l->size == (__size_before + 1));\
181  } while(0)
182 
183 #define list_detach_by_content(li, node) \
184  do { \
185  __typeof__(node) __n = (node); /* in-block scope variable */ \
186  struct list *__l; \
187  __l = (struct list *)(li); \
188  assert(__l); \
189  /* Unchain the node */ \
190  if(__l->head == __n) { \
191  __l->head = __n->next; \
192  if(__l->head != NULL) { \
193  ((__typeof(node))__l->head)->prev = NULL; \
194  }\
195  }\
196  if(__l->tail == __n) {\
197  __l->tail = __n->prev;\
198  if(__l->tail != NULL) {\
199  ((__typeof(node))__l->tail)->next = NULL;\
200  }\
201  }\
202  if(__n->next != NULL) {\
203  __n->next->prev = __n->prev;\
204  }\
205  if(__n->prev != NULL) {\
206  __n->prev->next = __n->next;\
207  }\
208  __n->next = (void *)0xBEEFC0DE;\
209  __n->prev = (void *)0xDEADC0DE;\
210  __l->size--;\
211  } while(0)
212 
213 #define list_pop(list)\
214  do {\
215  struct list *__l;\
216  size_t __size_before;\
217  __typeof__ (list) __n;\
218  __typeof__ (list) __n_next;\
219  __l = (struct list *)(list);\
220  assert(__l);\
221  __size_before = __l->size;\
222  __n = __l->head;\
223  if(__n != NULL) {\
224  __l->head = __n->next;\
225  if(__n->next != NULL) {\
226  __n->next->prev = NULL;\
227  }\
228  __n_next = __n->next;\
229  __n->next = (void *)0xDEFEC8ED;\
230  __n->prev = (void *)0xDEFEC8ED;\
231  __n = __n_next;\
232  __l->size--;\
233  assert(__l->size == (__size_before - 1));\
234  }\
235  } while(0)
236 
238 #define list_trunc(list, key_name, key_value, release_fn) \
239  ({\
240  struct list *__l = (struct list *)(list);\
241  __typeof__(list) __n;\
242  __typeof__(list) __n_adjacent;\
243  unsigned int __deleted = 0;\
244  size_t __key_position = my_offsetof((list), key_name);\
245  assert(__l);\
246  size_t __size_before = __l->size;\
247  /* Attempting to truncate an empty list? */\
248  if(__l->size > 0) {\
249  __n = __l->head;\
250  while(__n != NULL && get_key(__n) < (key_value)) {\
251  __deleted++;\
252  __n_adjacent = __n->next;\
253  __n->next = (void *)0xBAADF00D;\
254  __n->prev = (void *)0xBAADF00D;\
255  release_fn(__n);\
256  __n = __n_adjacent;\
257  }\
258  __l->head = __n;\
259  if(__l->head != NULL)\
260  ((__typeof__(list))__l->head)->prev = NULL;\
261  }\
262  __l->size -= __deleted;\
263  assert(__l->size == (__size_before - __deleted));\
264  __deleted;\
265  })
266 
267 #define list_size(li) ((struct list *)(li))->size
This structure defines a generic list. Nodes of the list must have a next/prev pointer properly typed...
Definition: list.h:18
void * head
pointer to the first element
Definition: list.h:22
void * tail
pointer to the last element
Definition: list.h:24
size_t size
the size of the list
Definition: list.h:20