+/* Licensed under LGPLv2.1+ - see LICENSE file for details */
#ifndef CCAN_LIST_H
#define CCAN_LIST_H
#include <stdbool.h>
#endif
/**
- * LIST_HEAD - define and initalize an empty list_head
+ * LIST_HEAD_INIT - initializer for an empty list_head
+ * @name: the name of the list.
+ *
+ * Explicit initializer for an empty list.
+ *
+ * See also:
+ * LIST_HEAD, list_head_init()
+ *
+ * Example:
+ * static struct list_head my_list = LIST_HEAD_INIT(my_list);
+ */
+#define LIST_HEAD_INIT(name) { { &name.n, &name.n } }
+
+/**
+ * LIST_HEAD - define and initialize an empty list_head
* @name: the name of the list.
*
* The LIST_HEAD macro defines a list_head and initializes it to an empty
* list. It can be prepended by "static" to define a static list_head.
*
+ * See also:
+ * LIST_HEAD_INIT, list_head_init()
+ *
* Example:
* static LIST_HEAD(my_global_list);
*/
#define LIST_HEAD(name) \
- struct list_head name = { { &name.n, &name.n } }
+ struct list_head name = LIST_HEAD_INIT(name)
/**
* list_head_init - initialize a list_head
* struct child *first;
* first = list_top(&parent->children, struct child, list);
*/
-#define list_top(h, type, member) \
- (list_empty(h) ? NULL : list_entry((h)->n.next, type, member))
+#define list_top(h, type, member) \
+ ((type *)list_top_((h), container_off((h)->n.next, type, member)))
+
+static inline const void *list_top_(const struct list_head *h, size_t off)
+{
+ if (list_empty(h))
+ return NULL;
+ return (const char *)h->n.next - off;
+}
/**
* list_tail - get the last entry in a list
* last = list_tail(&parent->children, struct child, list);
*/
#define list_tail(h, type, member) \
- (list_empty(h) ? NULL : list_entry((h)->n.prev, type, member))
+ ((type *)list_tail_((h), container_off((h)->n.next, type, member)))
+
+static inline const void *list_tail_(const struct list_head *h, size_t off)
+{
+ if (list_empty(h))
+ return NULL;
+ return (const char *)h->n.prev - off;
+}
/**
* list_for_each - iterate through a list.
- * @h: the list_head
+ * @h: the list_head (warning: evaluated multiple times!)
* @i: the structure containing the list_node
* @member: the list_node member of the structure
*
&i->member != &(h)->n; \
i = container_of_var(i->member.next, i, member))
+/**
+ * list_for_each_rev - iterate through a list backwards.
+ * @h: the list_head
+ * @i: the structure containing the list_node
+ * @member: the list_node member of the structure
+ *
+ * This is a convenient wrapper to iterate @i over the entire list. It's
+ * a for loop, so you can break and continue as normal.
+ *
+ * Example:
+ * list_for_each_rev(&parent->children, child, list)
+ * printf("Name: %s\n", child->name);
+ */
+#define list_for_each_rev(h, i, member) \
+ for (i = container_of_var(list_debug(h)->n.prev, i, member); \
+ &i->member != &(h)->n; \
+ i = container_of_var(i->member.prev, i, member))
+
/**
* list_for_each_safe - iterate through a list, maybe during deletion
* @h: the list_head