#define _UTIL_LIST_H_
+#include <stdbool.h>
#include <stddef.h>
+#include <assert.h>
struct list_head
item->prev = item;
}
+static inline bool list_empty(struct list_head *list)
+{
+ return list->next == list;
+}
+
+static inline unsigned list_length(struct list_head *list)
+{
+ struct list_head *node;
+ unsigned length = 0;
+ for (node = list->next; node != list; node = node->next)
+ length++;
+ return length;
+}
+
+static inline void list_validate(struct list_head *list)
+{
+ struct list_head *node;
+ assert(list->next->prev == list && list->prev->next == list);
+ for (node = list->next; node != list; node = node->next)
+ assert(node->next->prev == node && node->prev->next == node);
+}
+
#define LIST_INITHEAD(__item) list_inithead(__item)
#define LIST_ADD(__item, __list) list_add(__item, __list)
#define LIST_ADDTAIL(__item, __list) list_addtail(__item, __list)
- ((char *)&(sample)->member - (char *)(sample)))
#endif
+#define list_first_entry(ptr, type, member) \
+ LIST_ENTRY(type, (ptr)->next, member)
+
+#define list_last_entry(ptr, type, member) \
+ LIST_ENTRY(type, (ptr)->prev, member)
+
+
#define LIST_FOR_EACH_ENTRY(pos, head, member) \
for (pos = NULL, pos = container_of((head)->next, pos, member); \
&pos->member != (head); \
&pos->member != (head); \
pos = container_of(pos->member.prev, pos, member))
+#define list_for_each_entry(type, pos, head, member) \
+ for (type *pos = LIST_ENTRY(type, (head)->next, member); \
+ &pos->member != (head); \
+ pos = LIST_ENTRY(type, pos->member.next, member))
+
+#define list_for_each_entry_safe(type, pos, head, member) \
+ for (type *pos = LIST_ENTRY(type, (head)->next, member), \
+ *__next = LIST_ENTRY(type, pos->member.next, member); \
+ &pos->member != (head); \
+ pos = __next, \
+ __next = LIST_ENTRY(type, __next->member.next, member))
+
+#define list_for_each_entry_rev(type, pos, head, member) \
+ for (type *pos = LIST_ENTRY(type, (head)->prev, member); \
+ &pos->member != (head); \
+ pos = LIST_ENTRY(type, pos->member.prev, member))
+
+#define list_for_each_entry_safe_rev(type, pos, head, member) \
+ for (type *pos = LIST_ENTRY(type, (head)->prev, member), \
+ *__prev = LIST_ENTRY(type, pos->member.prev, member); \
+ &pos->member != (head); \
+ pos = __prev, \
+ __prev = LIST_ENTRY(type, __prev->member.prev, member))
+
+#define list_for_each_entry_from(type, pos, start, head, member) \
+ for (type *pos = LIST_ENTRY(type, (start), member); \
+ &pos->member != (head); \
+ pos = LIST_ENTRY(type, pos->member.next, member))
+
+#define list_for_each_entry_from_rev(type, pos, start, head, member) \
+ for (type *pos = LIST_ENTRY(type, (start), member); \
+ &pos->member != (head); \
+ pos = LIST_ENTRY(type, pos->member.prev, member))
+
#endif /*_UTIL_LIST_H_*/