]> git.ozlabs.org Git - ccan/blob - ccan/tlist/tlist.h
various: add LICENSE comments.
[ccan] / ccan / tlist / tlist.h
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
6 #if HAVE_FLEXIBLE_ARRAY_MEMBER
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)
11  *
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().
15  *
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  *      };
24  *
25  *      struct child {
26  *              const char *name;
27  *              struct list_node list;
28  *      };
29  */
30 #define TLIST_TYPE(suffix, type)                                        \
31         struct tlist_##suffix {                                         \
32                 struct list_head raw;                                   \
33                 const type *tcheck[];                                   \
34         }
35
36 /**
37  * tlist_raw - access the raw list inside a typed list head.
38  * @h: the head of the typed list (struct tlist_@suffix)
39  * @test_var: a pointer to the expected element type.
40  *
41  * This elaborate macro usually causes the compiler to emit a warning
42  * if the variable is of an unexpected type.  It is used internally
43  * where we need to access the raw underlying list.
44  */
45 #define tlist_raw(h, test_var) \
46         (sizeof((h)->tcheck[0] == (test_var)) ? &(h)->raw : &(h)->raw)
47 #else
48 #define TLIST_TYPE(suffix, type)                                        \
49         struct tlist_##suffix {                                         \
50                 struct list_head raw;                                   \
51         }
52 #define tlist_raw(h, test_var) (&(h)->raw)
53 #endif
54
55 /**
56  * TLIST_INIT - initalizer for an empty tlist
57  * @name: the name of the list.
58  *
59  * Explicit initializer for an empty list.
60  *
61  * See also:
62  *      tlist_init()
63  *
64  * Example:
65  *      static struct tlist_children my_list = TLIST_INIT(my_list);
66  */
67 #define TLIST_INIT(name) { LIST_HEAD_INIT(name.raw) }
68
69 /**
70  * tlist_check - check head of a list for consistency
71  * @h: the tlist_head
72  * @abortstr: the location to print on aborting, or NULL.
73  *
74  * Because list_nodes have redundant information, consistency checking between
75  * the back and forward links can be done.  This is useful as a debugging check.
76  * If @abortstr is non-NULL, that will be printed in a diagnostic if the list
77  * is inconsistent, and the function will abort.
78  *
79  * Returns non-NULL if the list is consistent, NULL otherwise (it
80  * can never return NULL if @abortstr is set).
81  *
82  * See also: list_check()
83  *
84  * Example:
85  *      static void dump_parent(struct parent *p)
86  *      {
87  *              struct child *c;
88  *
89  *              printf("%s (%u children):\n", p->name, p->num_children);
90  *              tlist_check(&p->children, "bad child list");
91  *              tlist_for_each(&p->children, c, list)
92  *                      printf(" -> %s\n", c->name);
93  *      }
94  */
95 #define tlist_check(h, abortstr) \
96         list_check(&(h)->raw, (abortstr))
97
98 /**
99  * tlist_init - initialize a tlist
100  * @h: the tlist to set to the empty list
101  *
102  * Example:
103  *      ...
104  *      struct parent *parent = malloc(sizeof(*parent));
105  *
106  *      tlist_init(&parent->children);
107  *      parent->num_children = 0;
108  */
109 #define tlist_init(h) list_head_init(&(h)->raw)
110
111 /**
112  * tlist_add - add an entry at the start of a linked list.
113  * @h: the tlist to add the node to
114  * @n: the entry to add to the list.
115  * @member: the member of n to add to the list.
116  *
117  * The entry's list_node does not need to be initialized; it will be
118  * overwritten.
119  * Example:
120  *      struct child *child = malloc(sizeof(*child));
121  *
122  *      child->name = "marvin";
123  *      tlist_add(&parent->children, child, list);
124  *      parent->num_children++;
125  */
126 #define tlist_add(h, n, member) list_add(tlist_raw((h), (n)), &(n)->member)
127
128 /**
129  * tlist_add_tail - add an entry at the end of a linked list.
130  * @h: the tlist to add the node to
131  * @n: the entry to add to the list.
132  * @member: the member of n to add to the list.
133  *
134  * The list_node does not need to be initialized; it will be overwritten.
135  * Example:
136  *      tlist_add_tail(&parent->children, child, list);
137  *      parent->num_children++;
138  */
139 #define tlist_add_tail(h, n, member) \
140         list_add_tail(tlist_raw((h), (n)), &(n)->member)
141
142 /**
143  * tlist_del_from - delete an entry from a linked list.
144  * @h: the tlist @n is in
145  * @n: the entry to delete
146  * @member: the member of n to remove from the list.
147  *
148  * This explicitly indicates which list a node is expected to be in,
149  * which is better documentation and can catch more bugs.
150  *
151  * Note that this leaves @n->@member in an undefined state; it
152  * can be added to another list, but not deleted again.
153  *
154  * See also: tlist_del()
155  *
156  * Example:
157  *      tlist_del_from(&parent->children, child, list);
158  *      parent->num_children--;
159  */
160 #define tlist_del_from(h, n, member) \
161         list_del_from(tlist_raw((h), (n)), &(n)->member)
162
163 /**
164  * tlist_del - delete an entry from an unknown linked list.
165  * @n: the entry to delete from the list.
166  * @member: the member of @n which is in the list.
167  *
168  * Example:
169  *      tlist_del(child, list);
170  *      parent->num_children--;
171  */
172 #define tlist_del(n, member) \
173         list_del(&(n)->member)
174
175 /**
176  * tlist_empty - is a list empty?
177  * @h: the tlist
178  *
179  * If the list is empty, returns true.
180  *
181  * Example:
182  *      assert(tlist_empty(&parent->children) == (parent->num_children == 0));
183  */
184 #define tlist_empty(h) list_empty(&(h)->raw)
185
186 /**
187  * tlist_top - get the first entry in a list
188  * @h: the tlist
189  * @type: the type of the entry
190  * @member: the list_node member of the type
191  *
192  * If the list is empty, returns NULL.
193  *
194  * Example:
195  *      struct child *first;
196  *      first = tlist_top(&parent->children, struct child, list);
197  */
198 #define tlist_top(h, type, member) \
199         list_top(tlist_raw((h), (type *)NULL), type, member)
200
201 /**
202  * tlist_tail - get the last entry in a list
203  * @h: the tlist
204  * @type: the type of the entry
205  * @member: the list_node member of the type
206  *
207  * If the list is empty, returns NULL.
208  *
209  * Example:
210  *      struct child *last;
211  *      last = tlist_tail(&parent->children, struct child, list);
212  */
213 #define tlist_tail(h, type, member) \
214         list_tail(tlist_raw((h), (type *)NULL), type, member)
215
216 /**
217  * tlist_for_each - iterate through a list.
218  * @h: the tlist
219  * @i: an iterator of suitable type for this list.
220  * @member: the list_node member of @i
221  *
222  * This is a convenient wrapper to iterate @i over the entire list.  It's
223  * a for loop, so you can break and continue as normal.
224  *
225  * Example:
226  *      tlist_for_each(&parent->children, child, list)
227  *              printf("Name: %s\n", child->name);
228  */
229 #define tlist_for_each(h, i, member)                                    \
230         list_for_each(tlist_raw((h), (i)), (i), member)
231
232 /**
233  * tlist_for_each_safe - iterate through a list, maybe during deletion
234  * @h: the tlist
235  * @i: an iterator of suitable type for this list.
236  * @nxt: another iterator to store the next entry.
237  * @member: the list_node member of the structure
238  *
239  * This is a convenient wrapper to iterate @i over the entire list.  It's
240  * a for loop, so you can break and continue as normal.  The extra variable
241  * @nxt is used to hold the next element, so you can delete @i from the list.
242  *
243  * Example:
244  *      struct child *next;
245  *      tlist_for_each_safe(&parent->children, child, next, list) {
246  *              tlist_del(child, list);
247  *              parent->num_children--;
248  *      }
249  */
250 #define tlist_for_each_safe(h, i, nxt, member)                          \
251         list_for_each_safe(tlist_raw((h), (i)), (i), (nxt), member)
252
253 #endif /* CCAN_TLIST_H */