X-Git-Url: https://wimlib.net/git/?p=wimlib;a=blobdiff_plain;f=include%2Fwimlib%2Flist.h;h=d556a56c6a142ddfaf2a732db3e4a4cb2912913b;hp=5e940cc111057d5ff725ec591bea376bc272d201;hb=873a86a1a5097f2a161494341d8d962453a30465;hpb=2b16d2eda8eef17e1b8cdababae37410f87cd544 diff --git a/include/wimlib/list.h b/include/wimlib/list.h index 5e940cc1..d556a56c 100644 --- a/include/wimlib/list.h +++ b/include/wimlib/list.h @@ -9,35 +9,18 @@ #include #include -struct list_head { - struct list_head *next, *prev; -}; -struct hlist_head { - struct hlist_node *first; -}; +/* Simple doubly linked list implementation. */ -struct hlist_node { - struct hlist_node *next, **pprev; +struct list_head { + struct list_head *next; + struct list_head *prev; }; -/* - * Simple doubly linked list implementation. - * - * Some of the internal functions ("__xxx") are useful when - * manipulating whole lists rather than single entries, as - * sometimes we already know the next/prev entries and we can - * generate better code by using them directly rather than - * using the generic single-entry routines. - */ #define LIST_HEAD_INIT(name) { &(name), &(name) } -#ifdef LIST_HEAD /* BSD sys/queue.h defines this... */ -# undef LIST_HEAD -#endif - -#define LIST_HEAD(name) \ - struct list_head name = LIST_HEAD_INIT(name) +#undef LIST_HEAD /* BSD sys/queue.h defines this... */ +#define LIST_HEAD(name) struct list_head name = LIST_HEAD_INIT(name) static inline void INIT_LIST_HEAD(struct list_head *list) @@ -133,8 +116,7 @@ list_empty(const struct list_head *head) static inline void __list_splice(const struct list_head *list, - struct list_head *prev, - struct list_head *next) + struct list_head *prev, struct list_head *next) { struct list_head *first = list->next; struct list_head *last = list->prev; @@ -158,24 +140,6 @@ list_splice(const struct list_head *list, struct list_head *head) __list_splice(list, head, head->next); } -/* Move the entire list @old to the list @new, overwriting it. */ -static inline void -list_transfer(struct list_head *old, struct list_head *new) -{ - struct list_head *prev, *next; - - if (list_empty(old)) { - INIT_LIST_HEAD(new); - } else { - prev = old->prev; - next = old->next; - new->next = next; - new->prev = prev; - prev->next = new; - next->prev = new; - } -} - /** * list_move - delete from one list and add as another's head * @list: the entry to move @@ -310,7 +274,20 @@ list_splice_tail(struct list_head *list, struct list_head *head) * You lose the ability to access the tail in O(1). */ -#define INIT_HLIST_HEAD(ptr) ((ptr)->first = NULL) +struct hlist_head { + struct hlist_node *first; +}; + +struct hlist_node { + struct hlist_node *next; + struct hlist_node **pprev; +}; + +static inline void +INIT_HLIST_HEAD(struct hlist_head *h) +{ + h->first = NULL; +} static inline bool hlist_unhashed(const struct hlist_node *h) @@ -347,31 +324,32 @@ hlist_add_head(struct hlist_node *n, struct hlist_head *h) #define hlist_entry(ptr, type, member) container_of(ptr,type,member) +#define hlist_entry_safe(ptr, type, member) \ + ({ typeof(ptr) ____ptr = (ptr); \ + ____ptr ? hlist_entry(____ptr, type, member) : NULL; \ + }) + /** * hlist_for_each_entry - iterate over list of given type - * @tpos: the type * to use as a loop cursor. - * @pos: the &struct hlist_node to use as a loop cursor. + * @pos: the type * to use as a loop cursor. * @head: the head for your list. * @member: the name of the hlist_node within the struct. */ -#define hlist_for_each_entry(tpos, pos, head, member) \ - for (pos = (head)->first; \ - pos && \ - ({ tpos = hlist_entry(pos, typeof(*tpos), member); 1;}); \ - pos = pos->next) +#define hlist_for_each_entry(pos, head, member) \ + for (pos = hlist_entry_safe((head)->first, typeof(*(pos)), member);\ + pos; \ + pos = hlist_entry_safe((pos)->member.next, typeof(*(pos)), member)) /** * hlist_for_each_entry_safe - iterate over list of given type safe against removal of list entry - * @tpos: the type * to use as a loop cursor. - * @pos: the &struct hlist_node to use as a loop cursor. + * @pos: the type * to use as a loop cursor. * @n: another &struct hlist_node to use as temporary storage * @head: the head for your list. * @member: the name of the hlist_node within the struct. */ -#define hlist_for_each_entry_safe(tpos, pos, n, head, member) \ - for (pos = (head)->first; \ - pos && ({ n = pos->next; 1; }) && \ - ({ tpos = hlist_entry(pos, typeof(*tpos), member); 1;}); \ - pos = n) +#define hlist_for_each_entry_safe(pos, n, head, member) \ + for (pos = hlist_entry_safe((head)->first, typeof(*pos), member);\ + pos && ({ n = pos->member.next; 1; }); \ + pos = hlist_entry_safe(n, typeof(*pos), member)) #endif /* _WIMLIB_LIST_H */