#pragma once /** * util/list.h * * Double Linked Lists for C * * (c) 2016 Harald Christian Joachim Wolff * * API (may be implemented with macros!) : * * */ typedef struct _list { struct _list *next, *prev; } list_t; #define LIST_INIT_STATIC(name) { &(name), &(name) } #define LIST(name) list_t name = LIST_INIT_STATIC(name) static inline void __list_init(list_t *list){ list->next = list->prev = list; } #define list_init(L) __list_init(L); static inline void __list_add(list_t *item,list_t *prev,list_t *next) { prev->next = item; next->prev = item; item->next = next; item->prev = prev; }; static inline void list_remove(list_t *item){ item->prev->next = item->next; item->next->prev = item->prev; item->prev = item->next = item; }; static inline void list_append(list_t* item,list_t* head){ __list_add(item,head->prev,head); }; static inline void list_insert(list_t* item,list_t* head){ __list_add(item,head,head->next); }; static inline list_t* list_next(list_t* item){ return item->next; }; static inline list_t* list_prev(list_t* item){ return item->prev; }; static inline int list_is_empty(list_t *list) { return (list->next == list); }; static inline list_t* list_get(list_t *head,int n){ if (list_is_empty(head)){ return 0L; }; while (n--){ head = head->next; }; return head; }; static inline list_t* list_fetch_first(list_t *head){ if (!list_is_empty(head)){ list_t *f = head->next; list_remove(f); return f; } else { return 0L; }; }; /** * list_entry - get container struct of entry * @P: Pointer to entry * @T: Type of struct * @M: entry member of struct */ #define list_entry(P,T,M) ((T*)(int)(((int)(P)) - (int)(&(((T*)0L)->M)))) #define list_next_entry(P,T,M) list_entry((P)->next,T,M) #define list_prev_entry(P,T,M) list_entry((P)->prev,T,M) #define list_first_entry(P,T,M) ((P)->next != (P) ? list_entry((P)->next,T,M) : NULL) #define list_last_entry(P,T,M) ((P)->prev != (P) ? list_entry((P)->prev,T,M) : NULL) #define for_each_list_entry(pos,list) for (pos = (list)->next; pos != (list); pos = pos->next) #define for_each_list_entry_reverse(pos,list) for (pos = (list)->prev; pos != (list); pos = pos->prev) #define for_each_list_entry_save(pos,tmp,list) for (pos = (list)->next, tmp = pos->next; pos != (list); pos = tmp, tmp = pos->next) static inline int list_count(list_t *head){ list_t *t; int n = 0; for_each_list_entry(t,head){ n++; }; return n; };