xref: /llvm-project/libc/include/llvm-libc-macros/sys-queue-macros.h (revision 88a0a318e80565fef9367728b878641d261acfb6)
1dbc09553SPetr Hosek //===-- Macros defined in sys/queue.h header file -------------------------===//
2dbc09553SPetr Hosek //
3dbc09553SPetr Hosek // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4dbc09553SPetr Hosek // See https://llvm.org/LICENSE.txt for license information.
5dbc09553SPetr Hosek // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6dbc09553SPetr Hosek //
7dbc09553SPetr Hosek //===----------------------------------------------------------------------===//
8dbc09553SPetr Hosek 
9330793c9SNick Desaulniers #ifndef LLVM_LIBC_MACROS_SYS_QUEUE_MACROS_H
10330793c9SNick Desaulniers #define LLVM_LIBC_MACROS_SYS_QUEUE_MACROS_H
11dbc09553SPetr Hosek 
12*88a0a318Slntue #include "containerof-macro.h"
13*88a0a318Slntue #include "null-macro.h"
14dbc09553SPetr Hosek 
15dbc09553SPetr Hosek #ifdef __cplusplus
16dbc09553SPetr Hosek #define QUEUE_TYPEOF(type) type
17dbc09553SPetr Hosek #else
18dbc09553SPetr Hosek #define QUEUE_TYPEOF(type) struct type
19dbc09553SPetr Hosek #endif
20dbc09553SPetr Hosek 
21dbc09553SPetr Hosek // Singly-linked list definitions.
22dbc09553SPetr Hosek 
23dbc09553SPetr Hosek #define SLIST_HEAD(name, type)                                                 \
24dbc09553SPetr Hosek   struct name {                                                                \
255bd0c44bSPetr Hosek     struct type *slh_first;                                                    \
26dbc09553SPetr Hosek   }
27dbc09553SPetr Hosek 
28dbc09553SPetr Hosek #define SLIST_CLASS_HEAD(name, type)                                           \
29dbc09553SPetr Hosek   struct name {                                                                \
305bd0c44bSPetr Hosek     class type *slh_first;                                                     \
31dbc09553SPetr Hosek   }
32dbc09553SPetr Hosek 
33dbc09553SPetr Hosek #define SLIST_HEAD_INITIALIZER(head)                                           \
34dbc09553SPetr Hosek   { NULL }
35dbc09553SPetr Hosek 
36dbc09553SPetr Hosek #define SLIST_ENTRY(type)                                                      \
37dbc09553SPetr Hosek   struct {                                                                     \
38dbc09553SPetr Hosek     struct type *next;                                                         \
39dbc09553SPetr Hosek   }
40dbc09553SPetr Hosek 
41dbc09553SPetr Hosek #define SLIST_CLASS_ENTRY(type)                                                \
42dbc09553SPetr Hosek   struct {                                                                     \
43dbc09553SPetr Hosek     class type *next;                                                          \
44dbc09553SPetr Hosek   }
45dbc09553SPetr Hosek 
46dbc09553SPetr Hosek // Singly-linked list access methods.
47dbc09553SPetr Hosek 
485bd0c44bSPetr Hosek #define SLIST_EMPTY(head) ((head)->slh_first == NULL)
495bd0c44bSPetr Hosek #define SLIST_FIRST(head) ((head)->slh_first)
50dbc09553SPetr Hosek #define SLIST_NEXT(elem, field) ((elem)->field.next)
51dbc09553SPetr Hosek 
52dbc09553SPetr Hosek #define SLIST_FOREACH(var, head, field)                                        \
53dbc09553SPetr Hosek   for ((var) = SLIST_FIRST(head); (var); (var) = SLIST_NEXT(var, field))
54dbc09553SPetr Hosek 
55dbc09553SPetr Hosek #define SLIST_FOREACH_FROM(var, head, field)                                   \
56dbc09553SPetr Hosek   if (!(var))                                                                  \
57dbc09553SPetr Hosek     (var) = SLIST_FIRST(head);                                                 \
58dbc09553SPetr Hosek   for (; (var); (var) = SLIST_NEXT(var, field))
59dbc09553SPetr Hosek 
60dbc09553SPetr Hosek #define SLIST_FOREACH_SAFE(var, head, field, tvar)                             \
61dbc09553SPetr Hosek   for ((var) = SLIST_FIRST(head);                                              \
62dbc09553SPetr Hosek        (var) && ((tvar) = SLIST_NEXT(var, field), 1); (var) = (tvar))
63dbc09553SPetr Hosek 
64dbc09553SPetr Hosek #define SLIST_FOREACH_FROM_SAFE(var, head, field, tvar)                        \
65dbc09553SPetr Hosek   if (!(var))                                                                  \
66dbc09553SPetr Hosek     (var) = SLIST_FIRST(head);                                                 \
67dbc09553SPetr Hosek   for (; (var) && ((tvar) = SLIST_NEXT(var, field), 1); (var) = (tvar))
68dbc09553SPetr Hosek 
69dbc09553SPetr Hosek // Singly-linked list functions.
70dbc09553SPetr Hosek 
71dbc09553SPetr Hosek #define SLIST_CONCAT(head1, head2, type, field)                                \
72dbc09553SPetr Hosek   do {                                                                         \
73dbc09553SPetr Hosek     if (SLIST_EMPTY(head1)) {                                                  \
74dbc09553SPetr Hosek       if ((SLIST_FIRST(head1) = SLIST_FIRST(head2)) != NULL)                   \
75dbc09553SPetr Hosek         SLIST_INIT(head2);                                                     \
76dbc09553SPetr Hosek     } else if (!SLIST_EMPTY(head2)) {                                          \
77dbc09553SPetr Hosek       QUEUE_TYPEOF(type) *cur = SLIST_FIRST(head1);                            \
78dbc09553SPetr Hosek       while (SLIST_NEXT(cur, field) != NULL)                                   \
79dbc09553SPetr Hosek         cur = SLIST_NEXT(cur, field);                                          \
80dbc09553SPetr Hosek       SLIST_NEXT(cur, field) = SLIST_FIRST(head2);                             \
81dbc09553SPetr Hosek       SLIST_INIT(head2);                                                       \
82dbc09553SPetr Hosek     }                                                                          \
83dbc09553SPetr Hosek   } while (0)
84dbc09553SPetr Hosek 
85dbc09553SPetr Hosek #define SLIST_INIT(head)                                                       \
86dbc09553SPetr Hosek   do {                                                                         \
87dbc09553SPetr Hosek     SLIST_FIRST(head) = NULL;                                                  \
88dbc09553SPetr Hosek   } while (0)
89dbc09553SPetr Hosek 
90dbc09553SPetr Hosek #define SLIST_INSERT_AFTER(slistelem, elem, field)                             \
91dbc09553SPetr Hosek   do {                                                                         \
92dbc09553SPetr Hosek     SLIST_NEXT(elem, field) = SLIST_NEXT(slistelem, field);                    \
93dbc09553SPetr Hosek     SLIST_NEXT(slistelem, field) = (elem);                                     \
94dbc09553SPetr Hosek   } while (0)
95dbc09553SPetr Hosek 
96dbc09553SPetr Hosek #define SLIST_INSERT_HEAD(head, elem, field)                                   \
97dbc09553SPetr Hosek   do {                                                                         \
98dbc09553SPetr Hosek     SLIST_NEXT(elem, field) = SLIST_FIRST(head);                               \
99dbc09553SPetr Hosek     SLIST_FIRST(head) = (elem);                                                \
100dbc09553SPetr Hosek   } while (0)
101dbc09553SPetr Hosek 
102dbc09553SPetr Hosek #define SLIST_REMOVE(head, elem, type, field)                                  \
103dbc09553SPetr Hosek   do {                                                                         \
104dbc09553SPetr Hosek     if (SLIST_FIRST(head) == (elem)) {                                         \
105dbc09553SPetr Hosek       SLIST_REMOVE_HEAD(head, field);                                          \
106dbc09553SPetr Hosek     } else {                                                                   \
107dbc09553SPetr Hosek       QUEUE_TYPEOF(type) *cur = SLIST_FIRST(head);                             \
108dbc09553SPetr Hosek       while (SLIST_NEXT(cur, field) != (elem))                                 \
109dbc09553SPetr Hosek         cur = SLIST_NEXT(cur, field);                                          \
110dbc09553SPetr Hosek       SLIST_REMOVE_AFTER(cur, field);                                          \
111dbc09553SPetr Hosek     }                                                                          \
112dbc09553SPetr Hosek   } while (0)
113dbc09553SPetr Hosek 
114dbc09553SPetr Hosek #define SLIST_REMOVE_AFTER(elem, field)                                        \
115dbc09553SPetr Hosek   do {                                                                         \
116dbc09553SPetr Hosek     SLIST_NEXT(elem, field) = SLIST_NEXT(SLIST_NEXT(elem, field), field);      \
117dbc09553SPetr Hosek   } while (0)
118dbc09553SPetr Hosek 
119dbc09553SPetr Hosek #define SLIST_REMOVE_HEAD(head, field)                                         \
120dbc09553SPetr Hosek   do {                                                                         \
121dbc09553SPetr Hosek     SLIST_FIRST(head) = SLIST_NEXT(SLIST_FIRST(head), field);                  \
122dbc09553SPetr Hosek   } while (0)
123dbc09553SPetr Hosek 
124dbc09553SPetr Hosek #define SLIST_SWAP(head1, head2, type)                                         \
125dbc09553SPetr Hosek   do {                                                                         \
126dbc09553SPetr Hosek     QUEUE_TYPEOF(type) *first = SLIST_FIRST(head1);                            \
127dbc09553SPetr Hosek     SLIST_FIRST(head1) = SLIST_FIRST(head2);                                   \
128dbc09553SPetr Hosek     SLIST_FIRST(head2) = first;                                                \
129dbc09553SPetr Hosek   } while (0)
130dbc09553SPetr Hosek 
131dbc09553SPetr Hosek // Singly-linked tail queue definitions.
132dbc09553SPetr Hosek 
133dbc09553SPetr Hosek #define STAILQ_HEAD(name, type)                                                \
134dbc09553SPetr Hosek   struct name {                                                                \
1355bd0c44bSPetr Hosek     struct type *stqh_first;                                                   \
1365bd0c44bSPetr Hosek     struct type **stqh_last;                                                   \
137dbc09553SPetr Hosek   }
138dbc09553SPetr Hosek 
139dbc09553SPetr Hosek #define STAILQ_CLASS_HEAD(name, type)                                          \
140dbc09553SPetr Hosek   struct name {                                                                \
1415bd0c44bSPetr Hosek     class type *stqh_first;                                                    \
1425bd0c44bSPetr Hosek     class type **stqh_last;                                                    \
143dbc09553SPetr Hosek   }
144dbc09553SPetr Hosek 
145dbc09553SPetr Hosek #define STAILQ_HEAD_INITIALIZER(head)                                          \
1465bd0c44bSPetr Hosek   { NULL, &(head).stqh_first }
147dbc09553SPetr Hosek 
148dbc09553SPetr Hosek #define STAILQ_ENTRY(type)                                                     \
149dbc09553SPetr Hosek   struct {                                                                     \
150dbc09553SPetr Hosek     struct type *next;                                                         \
151dbc09553SPetr Hosek   }
152dbc09553SPetr Hosek 
153dbc09553SPetr Hosek #define STAILQ_CLASS_ENTRY(type)                                               \
154dbc09553SPetr Hosek   struct {                                                                     \
155dbc09553SPetr Hosek     class type *next;                                                          \
156dbc09553SPetr Hosek   }
157dbc09553SPetr Hosek 
158dbc09553SPetr Hosek // Singly-linked tail queue access methods.
159dbc09553SPetr Hosek 
1605bd0c44bSPetr Hosek #define STAILQ_EMPTY(head) ((head)->stqh_first == NULL)
1615bd0c44bSPetr Hosek #define STAILQ_FIRST(head) ((head)->stqh_first)
162dbc09553SPetr Hosek #define STAILQ_LAST(head, type, field)                                         \
163c0a74ad9SPetr Hosek   (STAILQ_EMPTY(head)                                                          \
164c0a74ad9SPetr Hosek        ? NULL                                                                  \
1655bd0c44bSPetr Hosek        : __containerof((head)->stqh_last, QUEUE_TYPEOF(type), field.next))
166dbc09553SPetr Hosek #define STAILQ_NEXT(elem, field) ((elem)->field.next)
167dbc09553SPetr Hosek 
168dbc09553SPetr Hosek #define STAILQ_FOREACH(var, head, field)                                       \
169dbc09553SPetr Hosek   for ((var) = STAILQ_FIRST(head); (var); (var) = STAILQ_NEXT(var, field))
170dbc09553SPetr Hosek 
171dbc09553SPetr Hosek #define STAILQ_FOREACH_FROM(var, head, field)                                  \
172dbc09553SPetr Hosek   if (!(var))                                                                  \
173dbc09553SPetr Hosek     (var) = STAILQ_FIRST(head);                                                \
174dbc09553SPetr Hosek   for (; (var); (var) = STAILQ_NEXT(var, field))
175dbc09553SPetr Hosek 
176dbc09553SPetr Hosek #define STAILQ_FOREACH_SAFE(var, head, field, tvar)                            \
177dbc09553SPetr Hosek   for ((var) = STAILQ_FIRST(head);                                             \
178dbc09553SPetr Hosek        (var) && ((tvar) = STAILQ_NEXT(var, field), 1); (var) = (tvar))
179dbc09553SPetr Hosek 
180dbc09553SPetr Hosek #define STAILQ_FOREACH_FROM_SAFE(var, head, field, tvar)                       \
181dbc09553SPetr Hosek   if (!(var))                                                                  \
182dbc09553SPetr Hosek     (var) = STAILQ_FIRST(head);                                                \
183dbc09553SPetr Hosek   for (; (var) && ((tvar) = STAILQ_NEXT(var, field), 1); (var) = (tvar))
184dbc09553SPetr Hosek 
185dbc09553SPetr Hosek // Singly-linked tail queue functions.
186dbc09553SPetr Hosek 
187dbc09553SPetr Hosek #define STAILQ_CONCAT(head1, head2, type, field)                               \
188dbc09553SPetr Hosek   do {                                                                         \
189dbc09553SPetr Hosek     if (!STAILQ_EMPTY(head2)) {                                                \
1905bd0c44bSPetr Hosek       *(head1)->stqh_last = (head2)->stqh_first;                               \
1915bd0c44bSPetr Hosek       (head1)->stqh_last = (head2)->stqh_last;                                 \
192dbc09553SPetr Hosek       STAILQ_INIT(head2);                                                      \
193dbc09553SPetr Hosek     }                                                                          \
194dbc09553SPetr Hosek   } while (0)
195dbc09553SPetr Hosek 
196dbc09553SPetr Hosek #define STAILQ_INIT(head)                                                      \
197dbc09553SPetr Hosek   do {                                                                         \
198dbc09553SPetr Hosek     STAILQ_FIRST(head) = NULL;                                                 \
1995bd0c44bSPetr Hosek     (head)->stqh_last = &STAILQ_FIRST(head);                                   \
200dbc09553SPetr Hosek   } while (0)
201dbc09553SPetr Hosek 
202dbc09553SPetr Hosek #define STAILQ_INSERT_AFTER(head, listelem, elem, field)                       \
203dbc09553SPetr Hosek   do {                                                                         \
204dbc09553SPetr Hosek     if ((STAILQ_NEXT(elem, field) = STAILQ_NEXT(listelem, field)) == NULL)     \
2055bd0c44bSPetr Hosek       (head)->stqh_last = &STAILQ_NEXT(elem, field);                           \
206dbc09553SPetr Hosek     STAILQ_NEXT(listelem, field) = (elem);                                     \
207dbc09553SPetr Hosek   } while (0)
208dbc09553SPetr Hosek 
209dbc09553SPetr Hosek #define STAILQ_INSERT_HEAD(head, elem, field)                                  \
210dbc09553SPetr Hosek   do {                                                                         \
211dbc09553SPetr Hosek     if ((STAILQ_NEXT(elem, field) = STAILQ_FIRST(head)) == NULL)               \
2125bd0c44bSPetr Hosek       (head)->stqh_last = &STAILQ_NEXT(elem, field);                           \
213dbc09553SPetr Hosek     STAILQ_FIRST(head) = (elem);                                               \
214dbc09553SPetr Hosek   } while (0)
215dbc09553SPetr Hosek 
216dbc09553SPetr Hosek #define STAILQ_INSERT_TAIL(head, elem, field)                                  \
217dbc09553SPetr Hosek   do {                                                                         \
218dbc09553SPetr Hosek     STAILQ_NEXT(elem, field) = NULL;                                           \
2195bd0c44bSPetr Hosek     *(head)->stqh_last = (elem);                                               \
2205bd0c44bSPetr Hosek     (head)->stqh_last = &STAILQ_NEXT(elem, field);                             \
221dbc09553SPetr Hosek   } while (0)
222dbc09553SPetr Hosek 
223dbc09553SPetr Hosek #define STAILQ_REMOVE(head, elem, type, field)                                 \
224dbc09553SPetr Hosek   do {                                                                         \
225dbc09553SPetr Hosek     if (STAILQ_FIRST(head) == (elem)) {                                        \
226dbc09553SPetr Hosek       STAILQ_REMOVE_HEAD(head, field);                                         \
227dbc09553SPetr Hosek     } else {                                                                   \
228dbc09553SPetr Hosek       QUEUE_TYPEOF(type) *cur = STAILQ_FIRST(head);                            \
229dbc09553SPetr Hosek       while (STAILQ_NEXT(cur, field) != (elem))                                \
230dbc09553SPetr Hosek         cur = STAILQ_NEXT(cur, field);                                         \
231dbc09553SPetr Hosek       STAILQ_REMOVE_AFTER(head, cur, field);                                   \
232dbc09553SPetr Hosek     }                                                                          \
233dbc09553SPetr Hosek   } while (0)
234dbc09553SPetr Hosek 
235dbc09553SPetr Hosek #define STAILQ_REMOVE_AFTER(head, elem, field)                                 \
236dbc09553SPetr Hosek   do {                                                                         \
237dbc09553SPetr Hosek     if ((STAILQ_NEXT(elem, field) =                                            \
238dbc09553SPetr Hosek              STAILQ_NEXT(STAILQ_NEXT(elem, field), field)) == NULL)            \
2395bd0c44bSPetr Hosek       (head)->stqh_last = &STAILQ_NEXT(elem, field);                           \
240dbc09553SPetr Hosek   } while (0)
241dbc09553SPetr Hosek 
242dbc09553SPetr Hosek #define STAILQ_REMOVE_HEAD(head, field)                                        \
243dbc09553SPetr Hosek   do {                                                                         \
244dbc09553SPetr Hosek     if ((STAILQ_FIRST(head) = STAILQ_NEXT(STAILQ_FIRST(head), field)) == NULL) \
2455bd0c44bSPetr Hosek       (head)->stqh_last = &STAILQ_FIRST(head);                                 \
246dbc09553SPetr Hosek   } while (0)
247dbc09553SPetr Hosek 
248dbc09553SPetr Hosek #define STAILQ_SWAP(head1, head2, type)                                        \
249dbc09553SPetr Hosek   do {                                                                         \
250dbc09553SPetr Hosek     QUEUE_TYPEOF(type) *first = STAILQ_FIRST(head1);                           \
2515bd0c44bSPetr Hosek     QUEUE_TYPEOF(type) **last = (head1)->stqh_last;                            \
252dbc09553SPetr Hosek     STAILQ_FIRST(head1) = STAILQ_FIRST(head2);                                 \
2535bd0c44bSPetr Hosek     (head1)->stqh_last = (head2)->stqh_last;                                   \
254dbc09553SPetr Hosek     STAILQ_FIRST(head2) = first;                                               \
2555bd0c44bSPetr Hosek     (head2)->stqh_last = last;                                                 \
256dbc09553SPetr Hosek     if (STAILQ_EMPTY(head1))                                                   \
2575bd0c44bSPetr Hosek       (head1)->stqh_last = &STAILQ_FIRST(head1);                               \
258dbc09553SPetr Hosek     if (STAILQ_EMPTY(head2))                                                   \
2595bd0c44bSPetr Hosek       (head2)->stqh_last = &STAILQ_FIRST(head2);                               \
260dbc09553SPetr Hosek   } while (0)
261dbc09553SPetr Hosek 
262330793c9SNick Desaulniers #endif // LLVM_LIBC_MACROS_SYS_QUEUE_MACROS_H
263