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