avr-fw-modules/core/include/util/list.h

103 lines
2.4 KiB
C
Executable File

#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;
};