VSF Documented
vsf_list.h
Go to the documentation of this file.
1/*****************************************************************************
2 * Copyright(C)2009-2022 by VSF Team *
3 * *
4 * Licensed under the Apache License, Version 2.0 (the "License"); *
5 * you may not use this file except in compliance with the License. *
6 * You may obtain a copy of the License at *
7 * *
8 * http://www.apache.org/licenses/LICENSE-2.0 *
9 * *
10 * Unless required by applicable law or agreed to in writing, software *
11 * distributed under the License is distributed on an "AS IS" BASIS, *
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. *
13 * See the License for the specific language governing permissions and *
14 * limitations under the License. *
15 * *
16 ****************************************************************************/
17
18#ifndef __VSF_LIST_H__
19#define __VSF_LIST_H__
20
21/*============================ INCLUDES ======================================*/
22#include "../compiler/compiler.h"
23
24#ifdef __cplusplus
25extern "C" {
26#endif
27
28/*============================ MACROS ========================================*/
29
30#if !defined(__STDC_VERSION__) || __STDC_VERSION__ < 199901L
31#define __vsf_when(__cond) (__cond)
32#define vsf_when(__cond) __vsf_when(__cond)
33#else
34#define __vsf_when(...) (__VA_ARGS__)
35#define vsf_when(...) __vsf_when(__VA_ARGS__)
36#endif
37
38#define __vsf_list_tmp_name(__head) VSF_MCONNECT2(__head, __LINE__)
39
40/*-----------------------------------------------------------------------------*
41 * Single Chain List internal macro *
42 *-----------------------------------------------------------------------------*/
43
44#define __vsf_slist_is_empty(__list_ptr) \
45 (NULL == ((vsf_slist_t *)(__list_ptr))->head)
46
47#define __vsf_slist_set_next(__node_ptr, __item_next_ptr) \
48 do { \
49 ((vsf_slist_node_t *)(__node_ptr))->next = (__item_next_ptr); \
50 } while (0)
51
52#define __vsf_slist_ref_next(__node_ptr, __item_ref_ptr) \
53 do { \
54 (*(void **)&(__item_ref_ptr)) = \
55 (((vsf_slist_node_t *)(__node_ptr))->next); \
56 } while (0)
57
58#define __vsf_slist_insert_next(__host_type, __member, __node_ptr, __item_ptr) \
59 do { \
60 __vsf_slist_set_next(&((__item_ptr)->__member), ((__node_ptr)->next)); \
61 __vsf_slist_set_next((__node_ptr), (__item_ptr)); \
62 } while (0)
63
64#define __vsf_slist_remove_next_unsafe( __host_type, \
65 __member, \
66 __node_ptr, \
67 __item_ref_ptr) \
68 do { \
69 __vsf_slist_ref_next((__node_ptr), (__item_ref_ptr)); \
70 __vsf_slist_set_next((__node_ptr), \
71 ((__host_type *)(__item_ref_ptr))->__member.next); \
72 } while (0)
73
74#define __vsf_slist_insert_after( __host_type,/* type of the host object */ \
75 __member, /* the name of the list */ \
76 __item_ptr, /* current item address */ \
77 __item_new_ptr)/* new item address */ \
78 do { \
79 vsf_slist_node_t *__vsf_list_tmp_name(node) = &((__item_ptr)->__member);\
80 __vsf_slist_insert_next(__host_type, __member, \
81 __vsf_list_tmp_name(node), (__item_new_ptr)); \
82 } while (0)
83
84#define __vsf_slist_remove_after( __host_type, /* type of the host object */ \
85 __member, /* the name of the list */ \
86 __item_ptr, /* current item address */ \
87 __item_ref_ptr) /* pointer of host type*/ \
88 do { \
89 vsf_slist_node_t *__vsf_list_tmp_name(node) = &((__item_ptr)->__member);\
90 __vsf_slist_ref_next(__vsf_list_tmp_name(node), (__item_ref_ptr)); \
91 if (NULL != __vsf_list_tmp_name(node)->next) { \
92 __vsf_slist_set_next(__vsf_list_tmp_name(node), \
93 ((__host_type *)(__vsf_list_tmp_name(node)->next))->__member.next);\
94 __vsf_slist_set_next(&((__item_ref_ptr)->__member), NULL); \
95 } \
96 } while (0)
97
98
99#if !defined(__STDC_VERSION__) || __STDC_VERSION__ < 199901L
100# define __vsf_slist_insert( __host_type, /* type of the host object */ \
101 __member, /* the name of the list */ \
102 __list_ptr, /* the address of the list */ \
103 __item_ptr, /* the address of the new item */ \
104 __cond) /* how to find insert point */ \
105 do { \
106 vsf_slist_node_t *__vsf_list_tmp_name(node) = \
107 (vsf_slist_node_t *)(__list_ptr); \
108 vsf_slist_init_node(__host_type, __member, __item_ptr); \
109 for (; __vsf_list_tmp_name(node)->next != NULL;){ \
110 const __host_type * const _ = \
111 (__host_type *)(__vsf_list_tmp_name(node)->next); \
112 /* using __VA_ARGS__ so ',' operation could be supported */ \
113 if (__cond) { \
114 __vsf_slist_insert_next(__host_type, __member, \
115 __vsf_list_tmp_name(node), (__item_ptr)); \
116 break; \
117 } \
118 __vsf_list_tmp_name(node) = (vsf_slist_node_t *)&(_->__member); \
119 } \
120 if (NULL == __vsf_list_tmp_name(node)->next) { \
121 __vsf_slist_insert_next(__host_type, __member, \
122 __vsf_list_tmp_name(node), (__item_ptr)); \
123 break; \
124 } \
125 } while (0)
126#else
127# define __vsf_slist_insert( __host_type, /* type of the host object */ \
128 __member, /* the name of the list */ \
129 __list_ptr, /* the address of the list */ \
130 __item_ptr, /* the address of the new item */ \
131 ...) /* how to find insert point */ \
132 do { \
133 vsf_slist_init_node(__host_type, __member, __item_ptr); \
134 vsf_slist_node_t *__vsf_list_tmp_name(node) = \
135 (vsf_slist_node_t *)(__list_ptr); \
136 for (; __vsf_list_tmp_name(node)->next != NULL;){ \
137 const __host_type * const _ = \
138 (__host_type *)(__vsf_list_tmp_name(node)->next); \
139 /* using __VA_ARGS__ so ',' operation could be supported */ \
140 if (__VA_ARGS__) { \
141 __vsf_slist_insert_next(__host_type, __member, \
142 __vsf_list_tmp_name(node), (__item_ptr)); \
143 break; \
144 } \
145 __vsf_list_tmp_name(node) = (vsf_slist_node_t *)&(_->__member); \
146 } \
147 if (NULL == __vsf_list_tmp_name(node)->next) { \
148 __vsf_slist_insert_next(__host_type, __member, \
149 __vsf_list_tmp_name(node), (__item_ptr)); \
150 break; \
151 } \
152 } while (0)
153#endif
154
155#define __vsf_slist_foreach_unsafe( \
156 __host_type, /* the type of the host type */ \
157 __member, /* the member name of the list */ \
158 __list_ptr) /* the address of the list */ \
159 for ( __host_type *_ = (__host_type *)((__list_ptr)->head); \
160 _ != NULL; \
161 _ = (__host_type *)(_->__member.next))
162
163#define __vsf_slist_foreach_next_unsafe( \
164 __host_type, /* the type of the host type */ \
165 __member, /* the member name of the list */ \
166 __list_ptr) /* the address of the list */ \
167 for ( __host_type *_ = (__host_type *)((__list_ptr)->head), \
168 *__ = _ ? (__host_type *)(_->__member.next) : NULL; \
169 _ != NULL; \
170 _ = __, __ = _ ? (__host_type *)(_->__member.next) : NULL)
171
172
173#define __vsf_slist_foreach(__host_type, /* the type of the host type */ \
174 __member, /* the member name of the list */ \
175 __list_ptr, /* the address of the list */ \
176 __item_ptr) /* the pointer name, e.g. ptarget */\
177 for (__host_type /* loop initialisation */ \
178 *__item_ptr = (__host_type *)(__list_ptr)->head, \
179 *_ = __item_ptr, \
180 *next = __item_ptr \
181 ? (__host_type *) \
182 ((__host_type *)((__list_ptr)->head))->__member.next \
183 : NULL; \
184 __item_ptr != NULL; /* loop condition */ \
185 _ = __item_ptr = next, next = __item_ptr \
186 ? (__host_type *) \
187 ((__host_type *)((__list_ptr)->head))->__member.next \
188 : NULL) /* prepare for next iteration */
189
190#define __vsf_slist_discard_head(__host_type, __member, __list_ptr) \
191 if (NULL != (__list_ptr)->head) { \
192 __host_type *item = (__host_type *)((__list_ptr)->head); \
193 __vsf_slist_set_next( \
194 (__list_ptr), \
195 ((__host_type *)((__list_ptr)->head))->__member.next); \
196 item->__member.next = NULL; \
197 }
198
199
200#define __vsf_slist_queue_init(__queue_ptr) \
201 do { \
202 __vsf_slist_set_next(&((__queue_ptr)->head), NULL); \
203 __vsf_slist_set_next(&((__queue_ptr)->tail), NULL); \
204 } while (0)
205
206#define __vsf_slist_queue_enqueue(__host_type, __member, __queue_ptr, __item_ptr)\
207 do { \
208 __host_type * __vsf_list_tmp_name(host_tail) = \
209 (__host_type *)((__queue_ptr)->tail.next); \
210 __vsf_slist_set_next(&((__queue_ptr)->tail), (__item_ptr)); \
211 if (__vsf_list_tmp_name(host_tail) != NULL) \
212 __vsf_slist_set_next(&__vsf_list_tmp_name(host_tail)->__member, (__item_ptr));\
213 else \
214 __vsf_slist_set_next(&((__queue_ptr)->head), (__item_ptr)); \
215 } while (0)
216
217#define __vsf_slist_queue_dequeue( __host_type, \
218 __member, \
219 __queue_ptr, \
220 __item_ref_ptr) \
221 do { \
222 __vsf_slist_ref_next(&((__queue_ptr)->head), (__item_ref_ptr)); \
223 if (NULL != (__item_ref_ptr)) { \
224 __vsf_slist_set_next( \
225 &((__queue_ptr)->head), \
226 (__item_ref_ptr)->__member.next); \
227 if (__vsf_slist_is_empty(&((__queue_ptr)->head))) \
228 __vsf_slist_set_next(&((__queue_ptr)->tail), NULL); \
229 __vsf_slist_set_next(&((__item_ref_ptr)->__member), NULL); \
230 } \
231 } while (0)
232
233#define __vsf_slist_queue_is_in(__host_type, __member, __queue_ptr, __item_ptr) \
234 vsf_slist_is_in(__host_type, __member, (vsf_slist_t *)&(__queue_ptr)->head, (__item_ptr))
235
236#define __vsf_slist_queue_peek( __host_type, \
237 __member, \
238 __queue_ptr, \
239 __item_ref_ptr) \
240 __vsf_slist_ref_next(&((__queue_ptr)->head), (__item_ref_ptr));
241
242
243#define __vsf_slist_queue_add_to_head( __host_type, \
244 __member, \
245 __queue_ptr, \
246 __item_ptr) \
247 do { \
248 __host_type * __vsf_list_tmp_name(host_head) = \
249 (__host_type *)((__queue_ptr)->head.next); \
250 __vsf_slist_set_next(&(__item_ptr)->__member, \
251 __vsf_list_tmp_name(host_head)); \
252 __vsf_slist_set_next(&((__queue_ptr)->head), (__item_ptr)); \
253 if (NULL == __vsf_list_tmp_name(host_head)) \
254 __vsf_slist_set_next(&((__queue_ptr)->tail), (__item_ptr)); \
255 } while (0)
256
257/*-----------------------------------------------------------------------------*
258 * Double Chain List intenral macro *
259 *-----------------------------------------------------------------------------*/
260
261#define __vsf_dlist_init(__list_ptr) \
262 do { \
263 (__list_ptr)->head = (__list_ptr)->tail = NULL; \
264 } while (0)
265
266#define __vsf_dlist_init_node(__node_ptr) \
267 do { \
268 (__node_ptr)->next = (__node_ptr)->prev = NULL; \
269 } while (0)
270
271#define __vsf_dlist_get_host(__host_type, __member, __node_ptr) \
272 vsf_container_of((__node_ptr), __host_type, __member)
273
274#define __vsf_dlist_get_host_safe(__host_type, __member, __node_ptr) \
275 vsf_safe_container_of((__node_ptr), __host_type, __member)
276
277#define __vsf_dlist_is_empty(__list_ptr) ((__list_ptr)->head == NULL)
278
279#define __vsf_dlist_is_in(__list_ptr, __node_ptr) \
280 __vsf_dlist_is_in_imp((__list_ptr), (__node_ptr))
281
282#define __vsf_dlist_ref(__host_type, __member, __node_ptr, __item_ref_ptr) \
283 do { \
284 (*(__host_type **)&(__item_ref_ptr)) = \
285 __vsf_dlist_get_host(__host_type, __member, __node_ptr); \
286 } while (0)
287
288#define __vsf_dlist_ref_safe(__host_type, __member, __node_ptr, __item_ref_ptr) \
289 do { \
290 (*(__host_type **)&(__item_ref_ptr)) = \
291 __vsf_dlist_get_host_safe(__host_type, __member, __node_ptr); \
292 } while (0)
293
294#define __vsf_dlist_add_to_head(__host_type, __member, __list_ptr, __item_ptr) \
295 __vsf_dlist_add_to_head_imp((__list_ptr), &((__item_ptr)->__member))
296
297#define __vsf_dlist_add_to_tail(__host_type, __member, __list_ptr, __item_ptr) \
298 __vsf_dlist_add_to_tail_imp((__list_ptr), &((__item_ptr)->__member))
299
300#define __vsf_dlist_peek_next(__host_type, __member, __item_ptr, __item_ref_ptr)\
301 do { \
302 vsf_dlist_node_t *__vsf_list_tmp_name(node) = (__item_ptr)->__member.next;\
303 __vsf_dlist_ref_safe(__host_type, __member, \
304 __vsf_list_tmp_name(node), (__item_ref_ptr)); \
305 } while (0)
306
307#define __vsf_dlist_peek_head(__host_type, __member, __list_ptr, __item_ref_ptr)\
308 do { \
309 vsf_dlist_node_t *__vsf_list_tmp_name(node) = (__list_ptr)->head; \
310 __vsf_dlist_ref_safe(__host_type, __member, \
311 __vsf_list_tmp_name(node), (__item_ref_ptr)); \
312 } while (0)
313
314#define __vsf_dlist_remove_head(__host_type, \
315 __member, \
316 __list_ptr, \
317 __item_ref_ptr) \
318 do { \
319 vsf_dlist_node_t *__vsf_list_tmp_name(node) = \
320 __vsf_dlist_remove_head_imp(__list_ptr); \
321 __vsf_dlist_ref_safe(__host_type, __member, \
322 __vsf_list_tmp_name(node), (__item_ref_ptr)); \
323 } while (0)
324
325#define __vsf_dlist_remove_tail(__host_type, \
326 __member, \
327 __list_ptr, \
328 __item_ref_ptr) \
329 do { \
330 vsf_dlist_node_t *__vsf_list_tmp_name(node) = \
331 __vsf_dlist_remove_tail_imp(__list_ptr); \
332 __vsf_dlist_ref_safe(__host_type, __member, \
333 __vsf_list_tmp_name(node), (__item_ref_ptr)); \
334 } while (0)
335
336#define __vsf_dlist_insert_after( \
337 __host_type, __member, __list_ptr, __item_prv_ptr, __item_ptr) \
338 __vsf_dlist_insert_after_imp( \
339 (__list_ptr), \
340 &((__item_prv_ptr)->__member), \
341 &((__item_ptr)->__member))
342
343#define __vsf_dlist_insert_before( \
344 __host_type, __member, __list_ptr, __item_next_ptr, __item_ptr) \
345 __vsf_dlist_insert_before_imp( \
346 (__list_ptr), \
347 &((__item_next_ptr)->__member), \
348 &((__item_ptr)->__member))
349
350#define __vsf_dlist_remove(__host_type, __member, __list_ptr, __item_ptr) \
351 __vsf_dlist_remove_imp((__list_ptr), &((__item_ptr)->__member))
352
353#define __vsf_dlist_remove_after( \
354 __host_type, __member, __list_ptr, __node_ptr, __item_ref_ptr) \
355 do { \
356 vsf_dlist_node_t *__vsf_list_tmp_name(node_nxt) = (__node_ptr)->next; \
357 if (__vsf_list_tmp_name(node_nxt) != NULL) { \
358 __vsf_dlist_remove(__host_type, __member, __list_ptr, \
359 __vsf_list_tmp_name(node_nxt)); \
360 __vsf_dlist_ref(__host_type, __member, \
361 __vsf_list_tmp_name(node_nxt), (__item_ref_ptr)); \
362 } else { \
363 (*(__host_type **)&(__item_ref_ptr)) = NULL; \
364 } \
365 } while (0)
366
367#define __vsf_dlist_remove_before( \
368 __host_type, __member, __list_ptr, __node_ptr, __item_ref_ptr) \
369 do { \
370 vsf_dlist_node_t *__vsf_list_tmp_name(node_prv) = (__node_ptr)->prev; \
371 if (__vsf_list_tmp_name(node_prv) != NULL) { \
372 __vsf_dlist_remove(__host_type, __member, __list_ptr, \
373 __vsf_list_tmp_name(node_prv)); \
374 __vsf_dlist_ref(__host_type, __member, \
375 __vsf_list_tmp_name(node_prv), (__item_ref_ptr)); \
376 } else { \
377 (*(__host_type **)&(__item_ref_ptr)) = NULL; \
378 } \
379 } while (0)
380
381#if !defined(__STDC_VERSION__) || __STDC_VERSION__ < 199901L
382# define __vsf_dlist_insert( __host_type,/* type of the host object */ \
383 __member, /* the name of the list */ \
384 __list_ptr, /* the address of the list */ \
385 __item_ptr, /* the address of the new item */ \
386 __cond) /* how to find insert point */ \
387 do { \
388 vsf_dlist_node_t *__vsf_list_tmp_name(node) = \
389 (vsf_dlist_node_t *)(__list_ptr); \
390 vsf_dlist_init_node(__host_type, __member, __item_ptr); \
391 for (; __vsf_list_tmp_name(node)->next != NULL;){ \
392 const __host_type * const _ = __vsf_dlist_get_host(__host_type, \
393 __member, __vsf_list_tmp_name(node)->next); \
394 /* using __VA_ARGS__ so ',' operation could be supported */ \
395 if (__cond) { \
396 __vsf_dlist_insert_before_imp((__list_ptr), \
397 __vsf_list_tmp_name(node)->next, &((__item_ptr)->__member));\
398 break; \
399 } \
400 __vsf_list_tmp_name(node) = __vsf_list_tmp_name(node)->next; \
401 } \
402 if (NULL == __vsf_list_tmp_name(node)->next) { \
403 __vsf_dlist_add_to_tail( \
404 __host_type, __member, __list_ptr, (__item_ptr)); \
405 } \
406 } while (0)
407#else
408# define __vsf_dlist_insert( __host_type,/* type of the host object */ \
409 __member, /* the name of the list */ \
410 __list_ptr, /* the address of the list */ \
411 __item_ptr, /* the address of the new item */ \
412 ...) /* how to find insert point */ \
413 do { \
414 vsf_dlist_init_node(__host_type, __member, __item_ptr); \
415 vsf_dlist_node_t *__vsf_list_tmp_name(node) = \
416 (vsf_dlist_node_t *)(__list_ptr); \
417 for (; __vsf_list_tmp_name(node)->next != NULL;){ \
418 const __host_type * const _ = __vsf_dlist_get_host(__host_type, \
419 __member, __vsf_list_tmp_name(node)->next); \
420 /* using __VA_ARGS__ so ',' operation could be supported */ \
421 if (__VA_ARGS__) { \
422 __vsf_dlist_insert_before_imp((__list_ptr), \
423 __vsf_list_tmp_name(node)->next, &((__item_ptr)->__member));\
424 break; \
425 } \
426 __vsf_list_tmp_name(node) = __vsf_list_tmp_name(node)->next; \
427 } \
428 if (NULL == __vsf_list_tmp_name(node)->next) { \
429 __vsf_dlist_add_to_tail( \
430 __host_type, __member, __list_ptr, (__item_ptr)); \
431 } \
432 } while (0)
433#endif
434
435#define __vsf_dlist_foreach_unsafe( \
436 __host_type, /* the type of the host type */ \
437 __member, /* the member name of the list */ \
438 __list_ptr) /* the address of the list */ \
439 for ( __host_type *_ = NULL == (__list_ptr)->head ? NULL : \
440 __vsf_dlist_get_host(__host_type, __member, (__list_ptr)->head);\
441 _ != NULL; \
442 _ = NULL == _->__member.next ? NULL : \
443 __vsf_dlist_get_host(__host_type, __member, _->__member.next))
444
445#define __vsf_dlist_foreach_next_unsafe( \
446 __host_type, /* the type of the host type */ \
447 __member, /* the member name of the list */ \
448 __list_ptr) /* the address of the list */ \
449 for ( __host_type \
450 *_ = NULL == (__list_ptr)->head ? NULL : \
451 __vsf_dlist_get_host(__host_type, __member, (__list_ptr)->head),\
452 *__ = (NULL == _ || NULL == _->__member.next) ? NULL : \
453 __vsf_dlist_get_host(__host_type, __member, _->__member.next);\
454 _ != NULL; \
455 _ = __, __ = (NULL == _ || NULL == _->__member.next) ? NULL : \
456 __vsf_dlist_get_host(__host_type, __member, _->__member.next))
457
458/*-----------------------------------------------------------------------------*
459 * Single Chain List *
460 *-----------------------------------------------------------------------------*/
461
464
465#define vsf_slist_init(__list_ptr) /* the address of the list */ \
466 __vsf_slist_set_next((__list_ptr), NULL)
467
468#define vsf_slist_is_empty(__list_ptr) /* the address of the list */ \
469 __vsf_slist_is_empty(__list_ptr)
470
471#define vsf_slist_set_next( __host_type, /* the type of the host type */ \
472 __member, /* the member name of the list */ \
473 __node_ptr, /* the reference node */ \
474 __item_ptr) /* the address of the target item */\
475 __vsf_slist_set_next((__node_ptr), (__item_ptr))
476
477#define vsf_slist_get_length( __host_type,/* the type of the host type */ \
478 __member, /* the member name of the list */ \
479 __list_ptr) /* the address of the list */ \
480 __vsf_slist_get_length_imp( \
481 (__list_ptr), vsf_offset_of(__host_type, __member))
482
483#define vsf_slist_remove_tail( __host_type,/* the type of the host type */ \
484 __member, /* the member name of the list */ \
485 __list_ptr) /* the address of the list */ \
486 __vsf_slist_remove_tail_imp( \
487 (__list_ptr), vsf_offset_of(__host_type, __member))
488
489#define vsf_slist_get_item_by_index( \
490 __host_type,/* the type of the host type */ \
491 __member, /* the member name of the list */ \
492 __list_ptr, /* the address of the list */ \
493 __index) /* index of the item in list */ \
494 __vsf_slist_get_item_by_index_imp( \
495 (__list_ptr), (__index), vsf_offset_of(__host_type, __member))
496
497#define vsf_slist_get_index( __host_type,/* the type of the host type */ \
498 __member, /* the member name of the list */ \
499 __list_ptr, /* the address of the list */ \
500 __item_ptr) /* the address of the target item */\
501 __vsf_slist_get_index_imp( \
502 (__list_ptr), (__item_ptr), vsf_offset_of(__host_type, __member))
503
504#define vsf_slist_append( __host_type, /* the type of the host type */ \
505 __member, /* the member name of the list */ \
506 __list_ptr, /* the address of the list */ \
507 __item_ptr) /* the address of the target item */\
508 __vsf_slist_append_imp( \
509 (__list_ptr), (__item_ptr), vsf_offset_of(__host_type, __member))
510
511#define vsf_slist_is_in( __host_type, /* the type of the host type */ \
512 __member, /* the member name of the list */ \
513 __list_ptr, /* the address of the list */ \
514 __item_ptr) /* the address of the target item */\
515 ( vsf_slist_get_index( \
516 __host_type, __member, (__list_ptr), (__item_ptr)) \
517 >= 0)
518
519#define vsf_slist_init_node(__host_type, /* the type of the host type */ \
520 __member, /* the member name of the list */ \
521 __item_ptr) /* the address of the target item */\
522 __vsf_slist_set_next(&((__item_ptr)->__member), NULL)
523
524#define vsf_slist_remove( __host_type, /* the type of the host type */ \
525 __member, /* the member name of the list*/ \
526 __list_ptr, /* the address of the list */ \
527 __item_ptr) /* the address of the target item */\
528 __vsf_slist_remove_imp( \
529 (__list_ptr), (__item_ptr), vsf_offset_of(__host_type, __member))
530
531#if !defined(__STDC_VERSION__) || __STDC_VERSION__ < 199901L
532# define vsf_slist_insert(__host_type, /* the type of the host type */ \
533 __member, /* the member name of the list */ \
534 __list_ptr, /* the address of the list */ \
535 __item_ptr, /* the address of the target item */\
536 __cond) /* when( condition expression ) */ \
537 __vsf_slist_insert( \
538 __host_type, __member, (__list_ptr), (__item_ptr), (__cond))
539#else
540# define vsf_slist_insert(__host_type, /* the type of the host type */ \
541 __member, /* the member name of the list */ \
542 __list_ptr, /* the address of the list */ \
543 __item_ptr, /* the address of the target item */\
544 ...) /* when( condition expression ) */ \
545 __vsf_slist_insert( \
546 __host_type, __member, (__list_ptr), (__item_ptr), __VA_ARGS__)
547#endif
548
549#define vsf_slist_remove_after( __host_type,/* the type of the host type */ \
550 __member, /* the member name of the list*/ \
551 __item_ptr, /* the address of current item */ \
552 __item_ref_ptr)/* the pointer of host type */ \
553 __vsf_slist_remove_after( \
554 __host_type, __member, (__item_ptr), (__item_ref_ptr))
555
556#define vsf_slist_insert_after( __host_type,/* the type of the host type */ \
557 __member, /* the member name of the list*/ \
558 __item_ptr, /* the address of current item */ \
559 __item_new_ptr)/* the address of new item */ \
560 __vsf_slist_insert_after( \
561 __host_type, __member, (__item_ptr), (__item_new_ptr))
562
564
565
568#define vsf_slist_stack_init(__list_ptr) vsf_slist_init_node(__list_ptr)
569
570#define vsf_slist_stack_pop(__host_type, /* the type of the host type */ \
571 __member, /* the member name of the list */ \
572 __list_ptr, /* the address of the list */ \
573 __item_ref_ptr) /* the pointer of host type */ \
574 vsf_slist_remove_from_head( \
575 __host_type, __member, (__list_ptr), (__item_ref_ptr))
576
577
578#define vsf_slist_stack_push( __host_type,/* the type of the host type */ \
579 __member, /* the member name of the list */ \
580 __list_ptr, /* the address of the list */ \
581 __item_ptr) /* the address of the target item */\
582 vsf_slist_add_to_head( \
583 __host_type, __member, (__list_ptr), (__item_ptr))
584
585
586#define vsf_slist_add_to_head( __host_type,/* the type of the host type */ \
587 __member, /* the member name of the list */ \
588 __list_ptr, /* the address of the list */ \
589 __item_ptr) /* the address of the target item */\
590 __vsf_slist_insert_next( \
591 __host_type, \
592 __member, \
593 (vsf_slist_node_t *)(__list_ptr), \
594 (__item_ptr))
595
596#define vsf_slist_discard_head( __host_type,/* the type of the host type */ \
597 __member, /* the member name of the list */ \
598 __list_ptr) /* the address of the list */ \
599 __vsf_slist_discard_head(__host_type, __member, (__list_ptr))
600
601#define vsf_slist_remove_from_head_unsafe( \
602 __host_type,/* the type of the host type */ \
603 __member, /* the member name of the list*/ \
604 __list_ptr, /* the address of the list */ \
605 __item_ref_ptr)/* the pointer of host type */ \
606 __vsf_slist_remove_next_unsafe( \
607 __host_type, \
608 __member, \
609 (vsf_slist_node_t *)(__list_ptr), \
610 (__item_ref_ptr))
611
612#define vsf_slist_remove_from_head( \
613 __host_type,/* the type of the host type */ \
614 __member, /* the member name of the list*/ \
615 __list_ptr, /* the address of the list */ \
616 __item_ref_ptr)/* the pointer of host type */ \
617 do { \
618 vsf_slist_peek_next(__host_type, __member, (__list_ptr), (__item_ref_ptr));\
619 vsf_slist_discard_head(__host_type, __member, (__list_ptr)); \
620 } while (0)
621#define vsf_slist_remove_head vsf_slist_remove_from_head
622
623#define vsf_slist_peek_next(__host_type, /* the type of the host type */ \
624 __member, /* the member name of the list */ \
625 __node_ptr, /* the reference node */ \
626 __item_ref_ptr) /* the pointer of host type */ \
627 __vsf_slist_ref_next((__node_ptr), (__item_ref_ptr))
629
632#define vsf_slist_foreach( __host_type, /* the type of the host type */ \
633 __member, /* the member name of the list */ \
634 __list_ptr, /* the address of the list */ \
635 __item_ptr) /* the pointer name, e.g. ptarget */\
636 __vsf_slist_foreach(__host_type, __member, (__list_ptr), __item_ptr)
638
639
642#define vsf_slist_queue_is_empty(__queue_ptr) \
643 vsf_slist_is_empty(&(__queue_ptr)->head)
644
645#define vsf_slist_queue_init(__queue_ptr) \
646 __vsf_slist_queue_init((__queue_ptr))/* the address of the queue */
647
648#define vsf_slist_queue_enqueue(__host_type,/* the type of the host type */ \
649 __member, /* the member name of the list*/ \
650 __queue_ptr,/* the address of the queue */ \
651 __item_ptr) /* the address of the target item */\
652 __vsf_slist_queue_enqueue( \
653 __host_type, __member, (__queue_ptr), (__item_ptr))
654
655#define vsf_slist_queue_dequeue(__host_type,/* the type of the host type */ \
656 __member, /* the member name of the list*/ \
657 __queue_ptr,/* the address of the queue */ \
658 __item_ref_ptr)/* the pointer of host type */ \
659 __vsf_slist_queue_dequeue( \
660 __host_type, __member, (__queue_ptr), (__item_ref_ptr))
661
662#define vsf_slist_queue_is_in( __host_type,/* the type of the host type */ \
663 __member, /* the member name of the list*/ \
664 __queue_ptr,/* the address of the queue */ \
665 __item_ptr) /* the address of the target item */\
666 __vsf_slist_queue_is_in( \
667 __host_type, __member, (__queue_ptr), (__item_ptr))
668
669#define vsf_slist_queue_peek( __host_type,/* the type of the host type */ \
670 __member, /* the member name of the list*/ \
671 __queue_ptr,/* the address of the queue */ \
672 __item_ref_ptr)/* the pointer of host type */ \
673 __vsf_slist_queue_peek( \
674 __host_type, __member, (__queue_ptr), (__item_ref_ptr))
675
676#define vsf_slist_queue_add_to_head( \
677 __host_type,/* the type of the host type */ \
678 __member, /* the member name of the list*/ \
679 __queue_ptr,/* the address of the queue */ \
680 __item_ptr) /* the address of the target item */\
681 __vsf_slist_queue_add_to_head( \
682 __host_type, __member, (__queue_ptr), (__item_ptr))
684
685/*-----------------------------------------------------------------------------*
686 * Double Chain List *
687 *-----------------------------------------------------------------------------*/
688
689/* memory layout for dlist
690 dlist:------------------
691|-----------|head tail|--------------|
692| ------------------ |
693| head:---------- tail:---------- |
694------->|forward |----->|forward |--->NULL |
695NULL<---|backward|<-----|backward|<----------
696 ---------- ----------
697*/
698
701
702#define vsf_dlist_init(__list_ptr) /* the address of the list */ \
703 __vsf_dlist_init(__list_ptr)
704
705#define vsf_dlist_is_empty(__list_ptr) /* the address of the list */ \
706 __vsf_dlist_is_empty(__list_ptr)
707
708#define vsf_dlist_get_length( __list_ptr) /* the address of the list */ \
709 __vsf_dlist_get_length_imp(__list_ptr)
710
711#define vsf_dlist_is_in( __host_type,/* the type of the host type */ \
712 __member, /* the member name of the list */ \
713 __list_ptr, /* the address of the list */ \
714 __item_ptr) /* the address of the target item */\
715 __vsf_dlist_is_in((__list_ptr), &(__item_ptr)->__member)
716
717#define vsf_dlist_init_node( __host_type,/* the type of the host type */ \
718 __member, /* the member name of the list */ \
719 __item_ptr) /* the address of the target item */\
720 __vsf_dlist_init_node(&((__item_ptr)->__member))
721
722#define vsf_dlist_add_to_head( __host_type,/* the type of the host type */ \
723 __member, /* the member name of the list */ \
724 __list_ptr, /* the address of the list */ \
725 __item_ptr) /* the address of the target item */\
726 __vsf_dlist_add_to_head(__host_type, \
727 __member, \
728 (__list_ptr), \
729 (__item_ptr))
730
731#define vsf_dlist_add_to_tail( __host_type,/* the type of the host type */ \
732 __member, /* the member name of the list */ \
733 __list_ptr, /* the address of the list */ \
734 __item_ptr) /* the address of the target item */\
735 __vsf_dlist_add_to_tail(__host_type, \
736 __member, \
737 (__list_ptr), \
738 (__item_ptr))
739
740#define vsf_dlist_peek_head( __host_type,/* the type of the host type */ \
741 __member, /* the member name of the list */ \
742 __list_ptr, /* the address of the list */ \
743 __item_ref_ptr)/* the pointer of host type */ \
744 __vsf_dlist_peek_head( \
745 __host_type, __member, (__list_ptr), (__item_ref_ptr))
746
747#define vsf_dlist_peek_next( __host_type,/* the type of the host type */ \
748 __member, /* the member name of the list */ \
749 __item_ptr, /* the address of the target item */\
750 __item_ref_ptr)/* the pointer of host type */ \
751 __vsf_dlist_peek_next( \
752 __host_type, __member, (__item_ptr), (__item_ref_ptr))
753
754#define vsf_dlist_remove_head( __host_type,/* the type of the host type */ \
755 __member, /* the member name of the list */ \
756 __list_ptr, /* the address of the list */ \
757 __item_ref_ptr)/* the pointer of host type */ \
758 __vsf_dlist_remove_head( \
759 __host_type, __member, (__list_ptr), (__item_ref_ptr))
760
761#define vsf_dlist_remove_tail( __host_type,/* the type of the host type */ \
762 __member, /* the member name of the list */ \
763 __list_ptr, /* the address of the list */ \
764 __item_ref_ptr)/* the pointer of host type */ \
765 __vsf_dlist_remove_tail( \
766 __host_type, __member, (__list_ptr), (__item_ref_ptr))
767
768#if !defined(__STDC_VERSION__) || __STDC_VERSION__ < 199901L
769# define vsf_dlist_insert( __host_type,/* the type of the host type */ \
770 __member, /* the member name of the list */ \
771 __list_ptr, /* the address of the list */ \
772 __item_ptr, /* the address of the target item */\
773 __cond) /* when( condition expression ) */ \
774 __vsf_dlist_insert( \
775 __host_type, __member, (__list_ptr), (__item_ptr), (__cond))
776#else
777# define vsf_dlist_insert( __host_type,/* the type of the host type */ \
778 __member, /* the member name of the list */ \
779 __list_ptr, /* the address of the list */ \
780 __item_ptr, /* the address of the target item */\
781 ...) /* when( condition expression ) */ \
782 __vsf_dlist_insert( \
783 __host_type, __member, (__list_ptr), (__item_ptr), __VA_ARGS__)
784#endif
785
786#define vsf_dlist_insert_after( __host_type,/* the type of the host type */ \
787 __member, /* the member name of the list*/ \
788 __list_ptr, /* the address of the list */ \
789 __item_prv_ptr,/* the address of the prev item */\
790 __item_ptr) /* the address of the target item */\
791 __vsf_dlist_insert_after( \
792 __host_type, \
793 __member, \
794 (__list_ptr), \
795 (__item_prv_ptr), \
796 (__item_ptr))
797
798#define vsf_dlist_insert_before(__host_type,/* the type of the host type */ \
799 __member, /* the member name of the list*/ \
800 __list_ptr, /* the address of the list */ \
801 __item_next_ptr,/* the address of the next item */\
802 __item_ptr) /* the address of the target item */\
803 __vsf_dlist_insert_before( \
804 __host_type, \
805 __member, \
806 (__list_ptr), \
807 (__item_next_ptr), \
808 (__item_ptr))
809
810#define vsf_dlist_remove( __host_type,/* the type of the host type */ \
811 __member, /* the member name of the list*/ \
812 __list_ptr, /* the address of the list */ \
813 __item_ptr) /* the address of the target item */\
814 __vsf_dlist_remove(__host_type, __member, (__list_ptr), (__item_ptr))
815
816#define vsf_dlist_remove_after( __host_type,/* the type of the host type */ \
817 __member, /* the member name of the list*/ \
818 __list_ptr, /* the address of the list */ \
819 __node_ptr, /* the reference node */ \
820 __item_ref_ptr)/* the pointer of host type */ \
821 __vsf_dlist_remove_after( \
822 __host_type, \
823 __member, \
824 (__list_ptr), \
825 (__node_ptr), \
826 (__item_ref_ptr))
827
828#define vsf_dlist_remove_before(__host_type,/* the type of the host type */ \
829 __member, /* the member name of the list*/ \
830 __list_ptr, /* the address of the list */ \
831 __node_ptr, /* the reference node */ \
832 __item_ref_ptr)/* the pointer of host type */ \
833 __vsf_dlist_remove_before( \
834 __host_type, \
835 __member, \
836 (__list_ptr), \
837 (__node_ptr), \
838 (__item_ref_ptr))
839
841
844
845#define vsf_dlist_queue_peek( __host_type,/* the type of the host type */ \
846 __member, /* the member name of the list */ \
847 __list_ptr, /* the address of the list */ \
848 __item_ref_ptr)/* the pointer of host type */ \
849 __vsf_dlist_ref_safe( \
850 __host_type, __member, (__list_ptr)->head, (__item_ref_ptr))
851
852#define vsf_dlist_queue_enqueue(__host_type,/* the type of the host type */ \
853 __member, /* the member name of the list*/ \
854 __list_ptr, /* the address of the list */ \
855 __item_ptr) /* the address of the target item */\
856 vsf_dlist_add_to_tail( \
857 __host_type, __member, (__list_ptr), (__item_ptr))
858
859#define vsf_dlist_queue_dequeue(__host_type,/* the type of the host type */ \
860 __member, /* the member name of the list*/ \
861 __list_ptr, /* the address of the list */ \
862 __item_ref_ptr)/* the address of the target item */\
863 vsf_dlist_remove_head( \
864 __host_type, __member, (__list_ptr), (__item_ref_ptr))
865
867
868/*============================ TYPES =========================================*/
869
872typedef struct vsf_slist_t {
873 void *head;
875
876typedef struct vsf_slist_node_t {
877 void *next;
880
883typedef struct vsf_dlist_t {
887
888typedef struct vsf_dlist_node_t {
893
896typedef struct vsf_slist_queue_t {
901
902/*============================ GLOBAL VARIABLES ==============================*/
903/*============================ PROTOTYPES ====================================*/
904
911 vsf_slist_t *this_ptr,
912 size_t list_offset);
913
922 vsf_slist_t *this_ptr,
923 uint_fast16_t index,
924 size_t list_offset);
925
933 void *item,
934 size_t list_offset);
935
943extern void * __vsf_slist_remove_imp( vsf_slist_t *this_ptr,
944 void *item,
945 size_t list_offset);
946
954extern void * __vsf_slist_append_imp( vsf_slist_t *this_ptr,
955 void *item,
956 size_t list_offset);
957
958extern void * __vsf_slist_remove_tail_imp( vsf_slist_t *this_ptr,
959 size_t list_offset);
960
962
963extern bool __vsf_dlist_is_in_imp( vsf_dlist_t *this_ptr,
964 vsf_dlist_node_t *node);
965
966extern void __vsf_dlist_add_to_head_imp(vsf_dlist_t *this_ptr,
967 vsf_dlist_node_t *node);
968
969extern void __vsf_dlist_add_to_tail_imp(vsf_dlist_t *this_ptr,
970 vsf_dlist_node_t *node);
971
973
975
976extern void __vsf_dlist_insert_after_imp( vsf_dlist_t *this_ptr,
977 vsf_dlist_node_t *node_prv,
978 vsf_dlist_node_t *node);
979
980extern void __vsf_dlist_insert_before_imp( vsf_dlist_t *this_ptr,
981 vsf_dlist_node_t *node_nxt,
982 vsf_dlist_node_t *node);
983
984extern void __vsf_dlist_remove_imp(vsf_dlist_t *this_ptr, vsf_dlist_node_t *node);
985
986#ifdef __cplusplus
987}
988#endif
989
990#endif
unsigned short uint_fast16_t
Definition stdint.h:25
short int_fast16_t
Definition stdint.h:24
Definition vsf_list.h:888
struct vsf_dlist_node_t * next
Definition vsf_list.h:889
struct vsf_dlist_node_t * prev
Definition vsf_list.h:890
Definition vsf_list.h:883
struct vsf_dlist_node_t * tail
Definition vsf_list.h:885
struct vsf_dlist_node_t * head
Definition vsf_list.h:884
Definition vsf_list.h:876
void * next
Definition vsf_list.h:877
Definition vsf_list.h:896
vsf_slist_node_t tail
Definition vsf_list.h:898
vsf_slist_node_t head
Definition vsf_list.h:897
Definition vsf_list.h:872
void * head
Definition vsf_list.h:873
void __vsf_dlist_add_to_tail_imp(vsf_dlist_t *this_ptr, vsf_dlist_node_t *node)
Definition vsf_list.c:210
vsf_dlist_node_t * __vsf_dlist_remove_head_imp(vsf_dlist_t *this_ptr)
Definition vsf_list.c:224
void __vsf_dlist_add_to_head_imp(vsf_dlist_t *this_ptr, vsf_dlist_node_t *node)
Definition vsf_list.c:196
void __vsf_dlist_remove_imp(vsf_dlist_t *this_ptr, vsf_dlist_node_t *node)
Definition vsf_list.c:290
uint_fast16_t __vsf_dlist_get_length_imp(vsf_dlist_t *this_ptr)
Definition vsf_list.c:177
vsf_dlist_node_t * __vsf_dlist_remove_tail_imp(vsf_dlist_t *this_ptr)
Definition vsf_list.c:241
void * __vsf_slist_append_imp(vsf_slist_t *this_ptr, void *item, size_t list_offset)
append a item from the target list !
Definition vsf_list.c:151
bool __vsf_dlist_is_in_imp(vsf_dlist_t *this_ptr, vsf_dlist_node_t *node)
Definition vsf_list.c:191
void * __vsf_slist_remove_tail_imp(vsf_slist_t *this_ptr, size_t list_offset)
Definition vsf_list.c:164
int_fast16_t __vsf_slist_get_index_imp(vsf_slist_t *this_ptr, void *item, size_t list_offset)
find the index number of a given item from the target list !
Definition vsf_list.c:98
uint_fast16_t __vsf_slist_get_length_imp(vsf_slist_t *this_ptr, size_t list_offset)
calculate the length of the target list !
Definition vsf_list.c:51
void __vsf_dlist_insert_before_imp(vsf_dlist_t *this_ptr, vsf_dlist_node_t *node_nxt, vsf_dlist_node_t *node)
Definition vsf_list.c:274
void * __vsf_slist_remove_imp(vsf_slist_t *this_ptr, void *item, size_t list_offset)
remove a item from the target list !
Definition vsf_list.c:124
void * __vsf_slist_get_item_by_index_imp(vsf_slist_t *this_ptr, uint_fast16_t index, size_t list_offset)
get the specified item with a given index from the target list !
Definition vsf_list.c:71
void __vsf_dlist_insert_after_imp(vsf_dlist_t *this_ptr, vsf_dlist_node_t *node_prv, vsf_dlist_node_t *node)
Definition vsf_list.c:258