diff options
Diffstat (limited to 'src/list.h')
-rw-r--r-- | src/list.h | 83 |
1 files changed, 83 insertions, 0 deletions
diff --git a/src/list.h b/src/list.h new file mode 100644 index 0000000..2a9df61 --- /dev/null +++ b/src/list.h @@ -0,0 +1,83 @@ +#ifndef LIST_H +#define LIST_H + +#define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER) +#define container_of(ptr, type, member) ((type *)((char *)(ptr) - offsetof(type, member))) + +struct list_head { + struct list_head *prev; + struct list_head *next; +}; + +#define LIST_END NULL + +#define LIST_EMPTY(list) do { \ + (list)->next = LIST_END; \ + (list)->prev = LIST_END; \ + } while(0); + +#define list_entry(ptr, type, member) \ + container_of(ptr, type, member) + +#define list_next_entry(entry, type, member) \ + list_entry(entry->member.next, type, member) + +#define list_for_each(pos, start) \ + for(struct list_head *pos = start; pos; pos = pos->next) +#define list_for_each_entry(type, entry, member, start) \ + for(type *entry = list_entry((start), type, member); \ + entry; \ + entry = (entry->member.next == LIST_END ? NULL : \ + list_next_entry(entry, type, member))) + +#define list_for_each_safe(pos, start) \ + for(struct list_head *pos = (start), *__next = LIST_END; \ + pos && (__next = pos->next,1); \ + pos = __next) + +static inline int list_is_head(struct list_head *l) +{ + return l->prev == LIST_END; +} + +static inline int list_is_tail(struct list_head *l) +{ + return l->next == LIST_END; +} + +static inline struct list_head *list_get_head(struct list_head *l) +{ + while(!list_is_head(l)) l = l->prev; + return l; +} + +static inline struct list_head *list_get_tail(struct list_head *l) +{ + while(!list_is_tail(l)) l = l->next; + return l; +} + +static inline struct list_head *list_add( + struct list_head *head, + struct list_head *new) +{ + if(head) { + new->next = head->next; + head->next = new; + } + new->prev = head; + return new; +} + +static inline struct list_head *list_append( + struct list_head *head, + struct list_head *new) +{ + if(head) { + head->next = new; + } + new->prev = head; + return new; +} + +#endif |