From 501cac0fef258b6038ff5f65fc9b74a965a6e1f0 Mon Sep 17 00:00:00 2001 From: Mathieu Maret Date: Sun, 21 Apr 2019 21:57:01 +0200 Subject: [PATCH] Implement simple linked list in macro --- core/list.h | 92 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 92 insertions(+) diff --git a/core/list.h b/core/list.h index 1f4b4d1..aadfdb4 100644 --- a/core/list.h +++ b/core/list.h @@ -191,4 +191,96 @@ #define list_collapse(list,iterator) \ 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_ */