Implement simple linked list in macro
This commit is contained in:
parent
3cda78532b
commit
501cac0fef
92
core/list.h
92
core/list.h
@ -191,4 +191,96 @@
|
|||||||
#define list_collapse(list,iterator) \
|
#define list_collapse(list,iterator) \
|
||||||
list_collapse_named(list,iterator,prev,next)
|
list_collapse_named(list,iterator,prev,next)
|
||||||
|
|
||||||
|
/*
|
||||||
|
*/
|
||||||
|
#define slist_init_named(list,next) \
|
||||||
|
((list) = NULL)
|
||||||
|
|
||||||
|
#define slist_singleton_named(list,item,next) ({ \
|
||||||
|
(item)->next = (item); \
|
||||||
|
(list) = (item); \
|
||||||
|
})
|
||||||
|
|
||||||
|
#define slist_is_empty_named(list,next) \
|
||||||
|
((list) == NULL)
|
||||||
|
|
||||||
|
#define slist_is_singleton_named(list,next) \
|
||||||
|
( ((list) != NULL) && ((list) == (list)->next) )
|
||||||
|
|
||||||
|
#define slist_get_head_named(list,next) \
|
||||||
|
(list)
|
||||||
|
|
||||||
|
/** @note After_this and item are expected to be valid ! */
|
||||||
|
#define slist_insert_after_named(list,after_this,item,next) ({ \
|
||||||
|
(item)->next = (after_this)->next; \
|
||||||
|
(after_this)->next = (item); \
|
||||||
|
})
|
||||||
|
|
||||||
|
/** @note NO check whether item really is in list ! */
|
||||||
|
#define slist_delete_named(list,item,before_item, next) ({ \
|
||||||
|
if ( ((item)->next == (item)) ) \
|
||||||
|
(item)->next = (list) = NULL; \
|
||||||
|
else { \
|
||||||
|
if ((before_item)) (before_item)->next = (item)->next; \
|
||||||
|
if ((item) == (list)) (list) = (item)->next; \
|
||||||
|
} \
|
||||||
|
})
|
||||||
|
|
||||||
|
#define slist_pop_head_named(list,next) ({ \
|
||||||
|
typeof(list) __ret_elt = (list); \
|
||||||
|
slist_delete_named(list,__ret_elt,NULL, next); \
|
||||||
|
__ret_elt; })
|
||||||
|
|
||||||
|
/** Loop statement that iterates through all of its elements, from
|
||||||
|
head to tail */
|
||||||
|
#define slist_foreach_named(list,iterator,nb_elements,next) \
|
||||||
|
for (nb_elements=0, (iterator) = (list) ; \
|
||||||
|
(iterator) && (!nb_elements || ((iterator) != (list))) ; \
|
||||||
|
nb_elements++, (iterator) = (iterator)->next )
|
||||||
|
|
||||||
|
/** True when we exitted early from the foreach loop (ie break) */
|
||||||
|
#define slist_foreach_early_break(list,iterator,nb_elements) \
|
||||||
|
((list) && ( \
|
||||||
|
((list) != (iterator)) || \
|
||||||
|
( ((list) == (iterator)) && (nb_elements == 0)) ))
|
||||||
|
|
||||||
|
/*
|
||||||
|
* the same macros : assume that next field is really
|
||||||
|
* named "next"
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define slist_init(list) \
|
||||||
|
slist_init_named(list,prev,next)
|
||||||
|
|
||||||
|
#define slist_singleton(list,item) \
|
||||||
|
slist_singleton_named(list,item,prev,next)
|
||||||
|
|
||||||
|
#define slist_is_empty(list) \
|
||||||
|
slist_is_empty_named(list,prev,next)
|
||||||
|
|
||||||
|
#define slist_is_singleton(list) \
|
||||||
|
slist_is_singleton_named(list,prev,next)
|
||||||
|
|
||||||
|
#define slist_get_head(list) \
|
||||||
|
slist_get_head_named(list,prev,next) \
|
||||||
|
|
||||||
|
#define slist_get_tail(list) \
|
||||||
|
slist_get_tail_named(list,prev,next) \
|
||||||
|
|
||||||
|
/* @note Before_this and item are expected to be valid ! */
|
||||||
|
#define slist_insert_after(list,after_this,item) \
|
||||||
|
slist_insert_after_named(list,after_this,item,prev,next)
|
||||||
|
|
||||||
|
/* @note NO check whether item really is in list ! */
|
||||||
|
#define slist_delete(list,item,before_item) \
|
||||||
|
slist_delete_named(list,item,before_item,next)
|
||||||
|
|
||||||
|
#define slist_pop_head(list) \
|
||||||
|
slist_pop_head_named(list,next)
|
||||||
|
|
||||||
|
#define slist_foreach_forward(list,iterator,nb_elements) \
|
||||||
|
slist_foreach_named(list,iterator,nb_elements,prev,next)
|
||||||
|
|
||||||
|
#define slist_foreach slist_foreach_forward
|
||||||
|
|
||||||
#endif /* _SOS_LIST_H_ */
|
#endif /* _SOS_LIST_H_ */
|
||||||
|
Loading…
Reference in New Issue
Block a user