1 /* Licensed under LGPL - see LICENSE file for details */
4 #include <ccan/list/list.h>
5 #include <ccan/tcon/tcon.h>
8 * TLIST_TYPE - declare a typed list type (struct tlist)
9 * @suffix: the name to use (struct tlist_@suffix)
10 * @type: the type the list will contain (void for any type)
12 * This declares a structure "struct tlist_@suffix" to use for
13 * lists containing this type. The actual list can be accessed using
14 * ".raw" or tlist_raw(). For maximum portability, place tlists
15 * embedded in structures as the last member.
18 * // Defines struct tlist_children
19 * TLIST_TYPE(children, struct child);
22 * unsigned int num_children;
23 * struct tlist_children children;
28 * struct list_node list;
31 #define TLIST_TYPE(suffix, type) \
32 struct tlist_##suffix { \
33 struct list_head raw; \
38 * TLIST_INIT - initalizer for an empty tlist
39 * @name: the name of the list.
41 * Explicit initializer for an empty list.
47 * static struct tlist_children my_list = TLIST_INIT(my_list);
49 #define TLIST_INIT(name) { LIST_HEAD_INIT(name.raw) }
52 * tlist_check - check head of a list for consistency
54 * @abortstr: the location to print on aborting, or NULL.
56 * Because list_nodes have redundant information, consistency checking between
57 * the back and forward links can be done. This is useful as a debugging check.
58 * If @abortstr is non-NULL, that will be printed in a diagnostic if the list
59 * is inconsistent, and the function will abort.
61 * Returns non-NULL if the list is consistent, NULL otherwise (it
62 * can never return NULL if @abortstr is set).
64 * See also: list_check()
67 * static void dump_parent(struct parent *p)
71 * printf("%s (%u children):\n", p->name, p->num_children);
72 * tlist_check(&p->children, "bad child list");
73 * tlist_for_each(&p->children, c, list)
74 * printf(" -> %s\n", c->name);
77 #define tlist_check(h, abortstr) \
78 list_check(&(h)->raw, (abortstr))
81 * tlist_init - initialize a tlist
82 * @h: the tlist to set to the empty list
86 * struct parent *parent = malloc(sizeof(*parent));
88 * tlist_init(&parent->children);
89 * parent->num_children = 0;
91 #define tlist_init(h) list_head_init(&(h)->raw)
94 * tlist_raw - unwrap the typed list and check the type
96 * @expr: the expression to check the type against (not evaluated)
98 * This macro usually causes the compiler to emit a warning if the
99 * variable is of an unexpected type. It is used internally where we
100 * need to access the raw underlying list.
102 #define tlist_raw(h, expr) (&tcon_check((h), canary, (expr))->raw)
105 * tlist_add - add an entry at the start of a linked list.
106 * @h: the tlist to add the node to
107 * @n: the entry to add to the list.
108 * @member: the member of n to add to the list.
110 * The entry's list_node does not need to be initialized; it will be
113 * struct child *child = malloc(sizeof(*child));
115 * child->name = "marvin";
116 * tlist_add(&parent->children, child, list);
117 * parent->num_children++;
119 #define tlist_add(h, n, member) list_add(tlist_raw((h), (n)), &(n)->member)
122 * tlist_add_tail - add an entry at the end of a linked list.
123 * @h: the tlist to add the node to
124 * @n: the entry to add to the list.
125 * @member: the member of n to add to the list.
127 * The list_node does not need to be initialized; it will be overwritten.
129 * tlist_add_tail(&parent->children, child, list);
130 * parent->num_children++;
132 #define tlist_add_tail(h, n, member) \
133 list_add_tail(tlist_raw((h), (n)), &(n)->member)
136 * tlist_del_from - delete an entry from a linked list.
137 * @h: the tlist @n is in
138 * @n: the entry to delete
139 * @member: the member of n to remove from the list.
141 * This explicitly indicates which list a node is expected to be in,
142 * which is better documentation and can catch more bugs.
144 * Note that this leaves @n->@member in an undefined state; it
145 * can be added to another list, but not deleted again.
147 * See also: tlist_del()
150 * tlist_del_from(&parent->children, child, list);
151 * parent->num_children--;
153 #define tlist_del_from(h, n, member) \
154 list_del_from(tlist_raw((h), (n)), &(n)->member)
157 * tlist_del - delete an entry from an unknown linked list.
158 * @n: the entry to delete from the list.
159 * @member: the member of @n which is in the list.
162 * tlist_del(child, list);
163 * parent->num_children--;
165 #define tlist_del(n, member) \
166 list_del(&(n)->member)
169 * tlist_empty - is a list empty?
172 * If the list is empty, returns true.
175 * assert(tlist_empty(&parent->children) == (parent->num_children == 0));
177 #define tlist_empty(h) list_empty(&(h)->raw)
180 * tlist_top - get the first entry in a list
182 * @member: the list_node member of the type
184 * If the list is empty, returns NULL.
187 * struct child *first;
188 * first = tlist_top(&parent->children, list);
190 * printf("Empty list!\n");
192 #define tlist_top(h, member) \
193 ((tcon_type((h), canary)) \
194 list_top_(&(h)->raw, \
195 (char *)(&(h)->_tcon[0].canary->member) - \
196 (char *)((h)->_tcon[0].canary)))
199 * tlist_tail - get the last entry in a list
201 * @member: the list_node member of the type
203 * If the list is empty, returns NULL.
206 * struct child *last;
207 * last = tlist_tail(&parent->children, list);
209 * printf("Empty list!\n");
211 #define tlist_tail(h, member) \
212 ((tcon_type((h), canary)) \
213 list_tail_(&(h)->raw, \
214 (char *)(&(h)->_tcon[0].canary->member) - \
215 (char *)((h)->_tcon[0].canary)))
218 * tlist_next - get the next entry in a list
220 * @n: the list element
221 * @member: the list_node member of the type
223 * Returns the element of list @h immediately after @n, or NULL, if @n
224 * is the last element in the list.
226 #define tlist_next(h, n, member) \
227 list_next(tlist_raw((h), (n)), (n), member)
230 * tlist_prev - get the previous entry in a list
232 * @n: the list element
233 * @member: the list_node member of the type
235 * Returns the element of list @h immediately before @n, or NULL, if
236 * @n is the first element in the list.
238 #define tlist_prev(h, n, member) \
239 list_prev(tlist_raw((h), (n)), (n), member)
242 * tlist_for_each - iterate through a list.
244 * @i: an iterator of suitable type for this list.
245 * @member: the list_node member of @i
247 * This is a convenient wrapper to iterate @i over the entire list. It's
248 * a for loop, so you can break and continue as normal.
251 * tlist_for_each(&parent->children, child, list)
252 * printf("Name: %s\n", child->name);
254 #define tlist_for_each(h, i, member) \
255 list_for_each(tlist_raw((h), (i)), (i), member)
258 * tlist_for_each - iterate through a list backwards.
260 * @i: an iterator of suitable type for this list.
261 * @member: the list_node member of @i
263 * This is a convenient wrapper to iterate @i over the entire list. It's
264 * a for loop, so you can break and continue as normal.
267 * tlist_for_each_rev(&parent->children, child, list)
268 * printf("Name: %s\n", child->name);
270 #define tlist_for_each_rev(h, i, member) \
271 list_for_each_rev(tlist_raw((h), (i)), (i), member)
274 * tlist_for_each_safe - iterate through a list, maybe during deletion
276 * @i: an iterator of suitable type for this list.
277 * @nxt: another iterator to store the next entry.
278 * @member: the list_node member of the structure
280 * This is a convenient wrapper to iterate @i over the entire list. It's
281 * a for loop, so you can break and continue as normal. The extra variable
282 * @nxt is used to hold the next element, so you can delete @i from the list.
285 * struct child *next;
286 * tlist_for_each_safe(&parent->children, child, next, list) {
287 * tlist_del(child, list);
288 * parent->num_children--;
291 #define tlist_for_each_safe(h, i, nxt, member) \
292 list_for_each_safe(tlist_raw((h), (i)), (i), (nxt), member)
294 #endif /* CCAN_TLIST_H */