diff options
Diffstat (limited to 'klippy/list.h')
-rw-r--r-- | klippy/list.h | 108 |
1 files changed, 108 insertions, 0 deletions
diff --git a/klippy/list.h b/klippy/list.h new file mode 100644 index 000000000..317a109cf --- /dev/null +++ b/klippy/list.h @@ -0,0 +1,108 @@ +#ifndef __LIST_H +#define __LIST_H + +#define container_of(ptr, type, member) ({ \ + const typeof( ((type *)0)->member ) *__mptr = (ptr); \ + (type *)( (char *)__mptr - offsetof(type,member) );}) + + +/**************************************************************** + * list - Double linked lists + ****************************************************************/ + +struct list_node { + struct list_node *next, *prev; +}; + +struct list_head { + struct list_node root; +}; + +static inline void +list_init(struct list_head *h) +{ + h->root.prev = h->root.next = &h->root; +} + +static inline int +list_empty(const struct list_head *h) +{ + return h->root.next == &h->root; +} + +static inline void +list_del(struct list_node *n) +{ + struct list_node *prev = n->prev; + struct list_node *next = n->next; + next->prev = prev; + prev->next = next; +} + +static inline void +__list_add(struct list_node *n, struct list_node *prev, struct list_node *next) +{ + next->prev = n; + n->next = next; + n->prev = prev; + prev->next = n; +} + +static inline void +list_add_after(struct list_node *n, struct list_node *prev) +{ + __list_add(n, prev, prev->next); +} + +static inline void +list_add_before(struct list_node *n, struct list_node *next) +{ + __list_add(n, next->prev, next); +} + +static inline void +list_add_head(struct list_node *n, struct list_head *h) +{ + list_add_after(n, &h->root); +} + +static inline void +list_add_tail(struct list_node *n, struct list_head *h) +{ + list_add_before(n, &h->root); +} + +static inline void +list_join_tail(struct list_head *add, struct list_head *h) +{ + if (!list_empty(add)) { + struct list_node *prev = h->root.prev; + struct list_node *next = &h->root; + struct list_node *first = add->root.next; + struct list_node *last = add->root.prev; + first->prev = prev; + prev->next = first; + last->next = next; + next->prev = last; + } +} + +#define list_next_entry(pos, member) \ + container_of((pos)->member.next, typeof(*pos), member) + +#define list_first_entry(head, type, member) \ + container_of((head)->root.next, type, member) + +#define list_for_each_entry(pos, head, member) \ + for (pos = list_first_entry((head), typeof(*pos), member) \ + ; &pos->member != &(head)->root \ + ; pos = list_next_entry(pos, member)) + +#define list_for_each_entry_safe(pos, n, head, member) \ + for (pos = list_first_entry((head), typeof(*pos), member) \ + , n = list_next_entry(pos, member) \ + ; &pos->member != &(head)->root \ + ; pos = n, n = list_next_entry(n, member)) + + +#endif // list.h |