wintest: add option to select the dns backend
[Samba/gebeck_regimport.git] / lib / ccan / tlist / tlist.h
blob571ed4e797f8dea20f298c426ca22f1198d3aa9f
1 /* Licensed under LGPL - see LICENSE file for details */
2 #ifndef CCAN_TLIST_H
3 #define CCAN_TLIST_H
4 #include <ccan/list/list.h>
5 #include <ccan/tcon/tcon.h>
7 /**
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().
16 * Example:
17 * // Defines struct tlist_children
18 * TLIST_TYPE(children, struct child);
19 * struct parent {
20 * const char *name;
21 * struct tlist_children children;
22 * unsigned int num_children;
23 * };
25 * struct child {
26 * const char *name;
27 * struct ccan_list_node list;
28 * };
30 #define TLIST_TYPE(suffix, type) \
31 struct tlist_##suffix { \
32 struct ccan_list_head raw; \
33 TCON(type *canary); \
36 /**
37 * TLIST_INIT - initalizer for an empty tlist
38 * @name: the name of the list.
40 * Explicit initializer for an empty list.
42 * See also:
43 * tlist_init()
45 * Example:
46 * static struct tlist_children my_list = TLIST_INIT(my_list);
48 #define TLIST_INIT(name) { CCAN_LIST_HEAD_INIT(name.raw) }
50 /**
51 * tlist_check - check head of a list for consistency
52 * @h: the tlist_head
53 * @abortstr: the location to print on aborting, or NULL.
55 * Because list_nodes have redundant information, consistency checking between
56 * the back and forward links can be done. This is useful as a debugging check.
57 * If @abortstr is non-NULL, that will be printed in a diagnostic if the list
58 * is inconsistent, and the function will abort.
60 * Returns non-NULL if the list is consistent, NULL otherwise (it
61 * can never return NULL if @abortstr is set).
63 * See also: ccan_list_check()
65 * Example:
66 * static void dump_parent(struct parent *p)
67 * {
68 * struct child *c;
70 * printf("%s (%u children):\n", p->name, p->num_children);
71 * tlist_check(&p->children, "bad child list");
72 * tlist_for_each(&p->children, c, list)
73 * printf(" -> %s\n", c->name);
74 * }
76 #define tlist_check(h, abortstr) \
77 ccan_list_check(&(h)->raw, (abortstr))
79 /**
80 * tlist_init - initialize a tlist
81 * @h: the tlist to set to the empty list
83 * Example:
84 * ...
85 * struct parent *parent = malloc(sizeof(*parent));
87 * tlist_init(&parent->children);
88 * parent->num_children = 0;
90 #define tlist_init(h) ccan_list_head_init(&(h)->raw)
92 /**
93 * tlist_raw - unwrap the typed list and check the type
94 * @h: the tlist
95 * @expr: the expression to check the type against (not evaluated)
97 * This macro usually causes the compiler to emit a warning if the
98 * variable is of an unexpected type. It is used internally where we
99 * need to access the raw underlying list.
101 #define tlist_raw(h, expr) (&tcon_check((h), canary, (expr))->raw)
104 * tlist_add - add an entry at the start of a linked list.
105 * @h: the tlist to add the node to
106 * @n: the entry to add to the list.
107 * @member: the member of n to add to the list.
109 * The entry's ccan_list_node does not need to be initialized; it will be
110 * overwritten.
111 * Example:
112 * struct child *child = malloc(sizeof(*child));
114 * child->name = "marvin";
115 * tlist_add(&parent->children, child, list);
116 * parent->num_children++;
118 #define tlist_add(h, n, member) ccan_list_add(tlist_raw((h), (n)), &(n)->member)
121 * tlist_add_tail - add an entry at the end of a linked list.
122 * @h: the tlist to add the node to
123 * @n: the entry to add to the list.
124 * @member: the member of n to add to the list.
126 * The ccan_list_node does not need to be initialized; it will be overwritten.
127 * Example:
128 * tlist_add_tail(&parent->children, child, list);
129 * parent->num_children++;
131 #define tlist_add_tail(h, n, member) \
132 ccan_list_add_tail(tlist_raw((h), (n)), &(n)->member)
135 * tlist_del_from - delete an entry from a linked list.
136 * @h: the tlist @n is in
137 * @n: the entry to delete
138 * @member: the member of n to remove from the list.
140 * This explicitly indicates which list a node is expected to be in,
141 * which is better documentation and can catch more bugs.
143 * Note that this leaves @n->@member in an undefined state; it
144 * can be added to another list, but not deleted again.
146 * See also: tlist_del()
148 * Example:
149 * tlist_del_from(&parent->children, child, list);
150 * parent->num_children--;
152 #define tlist_del_from(h, n, member) \
153 ccan_list_del_from(tlist_raw((h), (n)), &(n)->member)
156 * tlist_del - delete an entry from an unknown linked list.
157 * @n: the entry to delete from the list.
158 * @member: the member of @n which is in the list.
160 * Example:
161 * tlist_del(child, list);
162 * parent->num_children--;
164 #define tlist_del(n, member) \
165 ccan_list_del(&(n)->member)
168 * tlist_empty - is a list empty?
169 * @h: the tlist
171 * If the list is empty, returns true.
173 * Example:
174 * assert(tlist_empty(&parent->children) == (parent->num_children == 0));
176 #define tlist_empty(h) ccan_list_empty(&(h)->raw)
179 * tlist_top - get the first entry in a list
180 * @h: the tlist
181 * @member: the ccan_list_node member of the type
183 * If the list is empty, returns NULL.
185 * Example:
186 * struct child *first;
187 * first = tlist_top(&parent->children, list);
189 #define tlist_top(h, member) \
190 ((tcon_type((h), canary)) \
191 ccan_list_top_(&(h)->raw, \
192 (char *)(&(h)->_tcon[0].canary->member) - \
193 (char *)((h)->_tcon[0].canary)))
196 * tlist_tail - get the last entry in a list
197 * @h: the tlist
198 * @member: the ccan_list_node member of the type
200 * If the list is empty, returns NULL.
202 * Example:
203 * struct child *last;
204 * last = tlist_tail(&parent->children, list);
206 #define tlist_tail(h, member) \
207 ((tcon_type((h), canary)) \
208 ccan_list_tail_(&(h)->raw, \
209 (char *)(&(h)->_tcon[0].canary->member) - \
210 (char *)((h)->_tcon[0].canary)))
213 * tlist_for_each - iterate through a list.
214 * @h: the tlist
215 * @i: an iterator of suitable type for this list.
216 * @member: the ccan_list_node member of @i
218 * This is a convenient wrapper to iterate @i over the entire list. It's
219 * a for loop, so you can break and continue as normal.
221 * Example:
222 * tlist_for_each(&parent->children, child, list)
223 * printf("Name: %s\n", child->name);
225 #define tlist_for_each(h, i, member) \
226 ccan_list_for_each(tlist_raw((h), (i)), (i), member)
229 * tlist_for_each - iterate through a list backwards.
230 * @h: the tlist
231 * @i: an iterator of suitable type for this list.
232 * @member: the ccan_list_node member of @i
234 * This is a convenient wrapper to iterate @i over the entire list. It's
235 * a for loop, so you can break and continue as normal.
237 * Example:
238 * tlist_for_each_rev(&parent->children, child, list)
239 * printf("Name: %s\n", child->name);
241 #define tlist_for_each_rev(h, i, member) \
242 ccan_list_for_each_rev(tlist_raw((h), (i)), (i), member)
245 * tlist_for_each_safe - iterate through a list, maybe during deletion
246 * @h: the tlist
247 * @i: an iterator of suitable type for this list.
248 * @nxt: another iterator to store the next entry.
249 * @member: the ccan_list_node member of the structure
251 * This is a convenient wrapper to iterate @i over the entire list. It's
252 * a for loop, so you can break and continue as normal. The extra variable
253 * @nxt is used to hold the next element, so you can delete @i from the list.
255 * Example:
256 * struct child *next;
257 * tlist_for_each_safe(&parent->children, child, next, list) {
258 * tlist_del(child, list);
259 * parent->num_children--;
262 #define tlist_for_each_safe(h, i, nxt, member) \
263 ccan_list_for_each_safe(tlist_raw((h), (i)), (i), (nxt), member)
265 #endif /* CCAN_TLIST_H */