/src/libxlsxwriter/include/xlsxwriter/third_party/tree.h
Line | Count | Source |
1 | | /* $NetBSD: tree.h,v 1.8 2004/03/28 19:38:30 provos Exp $ */ |
2 | | /* $OpenBSD: tree.h,v 1.7 2002/10/17 21:51:54 art Exp $ */ |
3 | | /* $FreeBSD$ */ |
4 | | |
5 | | /*- |
6 | | * Copyright 2002 Niels Provos <provos@citi.umich.edu> |
7 | | * All rights reserved. |
8 | | * |
9 | | * Redistribution and use in source and binary forms, with or without |
10 | | * modification, are permitted provided that the following conditions |
11 | | * are met: |
12 | | * 1. Redistributions of source code must retain the above copyright |
13 | | * notice, this list of conditions and the following disclaimer. |
14 | | * 2. Redistributions in binary form must reproduce the above copyright |
15 | | * notice, this list of conditions and the following disclaimer in the |
16 | | * documentation and/or other materials provided with the distribution. |
17 | | * |
18 | | * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR |
19 | | * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
20 | | * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
21 | | * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, |
22 | | * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
23 | | * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
24 | | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
25 | | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
26 | | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
27 | | * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
28 | | */ |
29 | | |
30 | | #ifndef _SYS_TREE_H_ |
31 | | #define _SYS_TREE_H_ |
32 | | |
33 | | /* #include <sys/cdefs.h> */ |
34 | | |
35 | | /* |
36 | | * This file defines data structures for different types of trees: |
37 | | * splay trees and red-black trees. |
38 | | * |
39 | | * A splay tree is a self-organizing data structure. Every operation |
40 | | * on the tree causes a splay to happen. The splay moves the requested |
41 | | * node to the root of the tree and partly rebalances it. |
42 | | * |
43 | | * This has the benefit that request locality causes faster lookups as |
44 | | * the requested nodes move to the top of the tree. On the other hand, |
45 | | * every lookup causes memory writes. |
46 | | * |
47 | | * The Balance Theorem bounds the total access time for m operations |
48 | | * and n inserts on an initially empty tree as O((m + n)lg n). The |
49 | | * amortized cost for a sequence of m accesses to a splay tree is O(lg n); |
50 | | * |
51 | | * A red-black tree is a binary search tree with the node color as an |
52 | | * extra attribute. It fulfills a set of conditions: |
53 | | * - every search path from the root to a leaf consists of the |
54 | | * same number of black nodes, |
55 | | * - each red node (except for the root) has a black parent, |
56 | | * - each leaf node is black. |
57 | | * |
58 | | * Every operation on a red-black tree is bounded as O(lg n). |
59 | | * The maximum height of a red-black tree is 2lg (n+1). |
60 | | */ |
61 | | |
62 | | #define SPLAY_HEAD(name, type) \ |
63 | | struct name { \ |
64 | | struct type *sph_root; /* root of the tree */ \ |
65 | | } |
66 | | |
67 | | #define SPLAY_INITIALIZER(root) \ |
68 | | { NULL } |
69 | | |
70 | | #define SPLAY_INIT(root) do { \ |
71 | | (root)->sph_root = NULL; \ |
72 | | } while (/*CONSTCOND*/ 0) |
73 | | |
74 | | #define SPLAY_ENTRY(type) \ |
75 | | struct { \ |
76 | | struct type *spe_left; /* left element */ \ |
77 | | struct type *spe_right; /* right element */ \ |
78 | | } |
79 | | |
80 | | #define SPLAY_LEFT(elm, field) (elm)->field.spe_left |
81 | | #define SPLAY_RIGHT(elm, field) (elm)->field.spe_right |
82 | | #define SPLAY_ROOT(head) (head)->sph_root |
83 | | #define SPLAY_EMPTY(head) (SPLAY_ROOT(head) == NULL) |
84 | | |
85 | | /* SPLAY_ROTATE_{LEFT,RIGHT} expect that tmp hold SPLAY_{RIGHT,LEFT} */ |
86 | | #define SPLAY_ROTATE_RIGHT(head, tmp, field) do { \ |
87 | | SPLAY_LEFT((head)->sph_root, field) = SPLAY_RIGHT(tmp, field); \ |
88 | | SPLAY_RIGHT(tmp, field) = (head)->sph_root; \ |
89 | | (head)->sph_root = tmp; \ |
90 | | } while (/*CONSTCOND*/ 0) |
91 | | |
92 | | #define SPLAY_ROTATE_LEFT(head, tmp, field) do { \ |
93 | | SPLAY_RIGHT((head)->sph_root, field) = SPLAY_LEFT(tmp, field); \ |
94 | | SPLAY_LEFT(tmp, field) = (head)->sph_root; \ |
95 | | (head)->sph_root = tmp; \ |
96 | | } while (/*CONSTCOND*/ 0) |
97 | | |
98 | | #define SPLAY_LINKLEFT(head, tmp, field) do { \ |
99 | | SPLAY_LEFT(tmp, field) = (head)->sph_root; \ |
100 | | tmp = (head)->sph_root; \ |
101 | | (head)->sph_root = SPLAY_LEFT((head)->sph_root, field); \ |
102 | | } while (/*CONSTCOND*/ 0) |
103 | | |
104 | | #define SPLAY_LINKRIGHT(head, tmp, field) do { \ |
105 | | SPLAY_RIGHT(tmp, field) = (head)->sph_root; \ |
106 | | tmp = (head)->sph_root; \ |
107 | | (head)->sph_root = SPLAY_RIGHT((head)->sph_root, field); \ |
108 | | } while (/*CONSTCOND*/ 0) |
109 | | |
110 | | #define SPLAY_ASSEMBLE(head, node, left, right, field) do { \ |
111 | | SPLAY_RIGHT(left, field) = SPLAY_LEFT((head)->sph_root, field); \ |
112 | | SPLAY_LEFT(right, field) = SPLAY_RIGHT((head)->sph_root, field);\ |
113 | | SPLAY_LEFT((head)->sph_root, field) = SPLAY_RIGHT(node, field); \ |
114 | | SPLAY_RIGHT((head)->sph_root, field) = SPLAY_LEFT(node, field); \ |
115 | | } while (/*CONSTCOND*/ 0) |
116 | | |
117 | | /* Generates prototypes and inline functions */ |
118 | | |
119 | | #define SPLAY_PROTOTYPE(name, type, field, cmp) \ |
120 | | void name##_SPLAY(struct name *, struct type *); \ |
121 | | void name##_SPLAY_MINMAX(struct name *, int); \ |
122 | | struct type *name##_SPLAY_INSERT(struct name *, struct type *); \ |
123 | | struct type *name##_SPLAY_REMOVE(struct name *, struct type *); \ |
124 | | \ |
125 | | /* Finds the node with the same key as elm */ \ |
126 | | static __inline struct type * \ |
127 | | name##_SPLAY_FIND(struct name *head, struct type *elm) \ |
128 | | { \ |
129 | | if (SPLAY_EMPTY(head)) \ |
130 | | return(NULL); \ |
131 | | name##_SPLAY(head, elm); \ |
132 | | if ((cmp)(elm, (head)->sph_root) == 0) \ |
133 | | return (head->sph_root); \ |
134 | | return (NULL); \ |
135 | | } \ |
136 | | \ |
137 | | static __inline struct type * \ |
138 | | name##_SPLAY_NEXT(struct name *head, struct type *elm) \ |
139 | | { \ |
140 | | name##_SPLAY(head, elm); \ |
141 | | if (SPLAY_RIGHT(elm, field) != NULL) { \ |
142 | | elm = SPLAY_RIGHT(elm, field); \ |
143 | | while (SPLAY_LEFT(elm, field) != NULL) { \ |
144 | | elm = SPLAY_LEFT(elm, field); \ |
145 | | } \ |
146 | | } else \ |
147 | | elm = NULL; \ |
148 | | return (elm); \ |
149 | | } \ |
150 | | \ |
151 | | static __inline struct type * \ |
152 | | name##_SPLAY_MIN_MAX(struct name *head, int val) \ |
153 | | { \ |
154 | | name##_SPLAY_MINMAX(head, val); \ |
155 | | return (SPLAY_ROOT(head)); \ |
156 | | } |
157 | | |
158 | | /* Main splay operation. |
159 | | * Moves node close to the key of elm to top |
160 | | */ |
161 | | #define SPLAY_GENERATE(name, type, field, cmp) \ |
162 | | struct type * \ |
163 | | name##_SPLAY_INSERT(struct name *head, struct type *elm) \ |
164 | | { \ |
165 | | if (SPLAY_EMPTY(head)) { \ |
166 | | SPLAY_LEFT(elm, field) = SPLAY_RIGHT(elm, field) = NULL; \ |
167 | | } else { \ |
168 | | int __comp; \ |
169 | | name##_SPLAY(head, elm); \ |
170 | | __comp = (cmp)(elm, (head)->sph_root); \ |
171 | | if(__comp < 0) { \ |
172 | | SPLAY_LEFT(elm, field) = SPLAY_LEFT((head)->sph_root, field);\ |
173 | | SPLAY_RIGHT(elm, field) = (head)->sph_root; \ |
174 | | SPLAY_LEFT((head)->sph_root, field) = NULL; \ |
175 | | } else if (__comp > 0) { \ |
176 | | SPLAY_RIGHT(elm, field) = SPLAY_RIGHT((head)->sph_root, field);\ |
177 | | SPLAY_LEFT(elm, field) = (head)->sph_root; \ |
178 | | SPLAY_RIGHT((head)->sph_root, field) = NULL; \ |
179 | | } else \ |
180 | | return ((head)->sph_root); \ |
181 | | } \ |
182 | | (head)->sph_root = (elm); \ |
183 | | return (NULL); \ |
184 | | } \ |
185 | | \ |
186 | | struct type * \ |
187 | | name##_SPLAY_REMOVE(struct name *head, struct type *elm) \ |
188 | | { \ |
189 | | struct type *__tmp; \ |
190 | | if (SPLAY_EMPTY(head)) \ |
191 | | return (NULL); \ |
192 | | name##_SPLAY(head, elm); \ |
193 | | if ((cmp)(elm, (head)->sph_root) == 0) { \ |
194 | | if (SPLAY_LEFT((head)->sph_root, field) == NULL) { \ |
195 | | (head)->sph_root = SPLAY_RIGHT((head)->sph_root, field);\ |
196 | | } else { \ |
197 | | __tmp = SPLAY_RIGHT((head)->sph_root, field); \ |
198 | | (head)->sph_root = SPLAY_LEFT((head)->sph_root, field);\ |
199 | | name##_SPLAY(head, elm); \ |
200 | | SPLAY_RIGHT((head)->sph_root, field) = __tmp; \ |
201 | | } \ |
202 | | return (elm); \ |
203 | | } \ |
204 | | return (NULL); \ |
205 | | } \ |
206 | | \ |
207 | | void \ |
208 | | name##_SPLAY(struct name *head, struct type *elm) \ |
209 | | { \ |
210 | | struct type __node, *__left, *__right, *__tmp; \ |
211 | | int __comp; \ |
212 | | \ |
213 | | SPLAY_LEFT(&__node, field) = SPLAY_RIGHT(&__node, field) = NULL;\ |
214 | | __left = __right = &__node; \ |
215 | | \ |
216 | | while ((__comp = (cmp)(elm, (head)->sph_root)) != 0) { \ |
217 | | if (__comp < 0) { \ |
218 | | __tmp = SPLAY_LEFT((head)->sph_root, field); \ |
219 | | if (__tmp == NULL) \ |
220 | | break; \ |
221 | | if ((cmp)(elm, __tmp) < 0){ \ |
222 | | SPLAY_ROTATE_RIGHT(head, __tmp, field); \ |
223 | | if (SPLAY_LEFT((head)->sph_root, field) == NULL)\ |
224 | | break; \ |
225 | | } \ |
226 | | SPLAY_LINKLEFT(head, __right, field); \ |
227 | | } else if (__comp > 0) { \ |
228 | | __tmp = SPLAY_RIGHT((head)->sph_root, field); \ |
229 | | if (__tmp == NULL) \ |
230 | | break; \ |
231 | | if ((cmp)(elm, __tmp) > 0){ \ |
232 | | SPLAY_ROTATE_LEFT(head, __tmp, field); \ |
233 | | if (SPLAY_RIGHT((head)->sph_root, field) == NULL)\ |
234 | | break; \ |
235 | | } \ |
236 | | SPLAY_LINKRIGHT(head, __left, field); \ |
237 | | } \ |
238 | | } \ |
239 | | SPLAY_ASSEMBLE(head, &__node, __left, __right, field); \ |
240 | | } \ |
241 | | \ |
242 | | /* Splay with either the minimum or the maximum element \ |
243 | | * Used to find minimum or maximum element in tree. \ |
244 | | */ \ |
245 | | void name##_SPLAY_MINMAX(struct name *head, int __comp) \ |
246 | | { \ |
247 | | struct type __node, *__left, *__right, *__tmp; \ |
248 | | \ |
249 | | SPLAY_LEFT(&__node, field) = SPLAY_RIGHT(&__node, field) = NULL;\ |
250 | | __left = __right = &__node; \ |
251 | | \ |
252 | | while (1) { \ |
253 | | if (__comp < 0) { \ |
254 | | __tmp = SPLAY_LEFT((head)->sph_root, field); \ |
255 | | if (__tmp == NULL) \ |
256 | | break; \ |
257 | | if (__comp < 0){ \ |
258 | | SPLAY_ROTATE_RIGHT(head, __tmp, field); \ |
259 | | if (SPLAY_LEFT((head)->sph_root, field) == NULL)\ |
260 | | break; \ |
261 | | } \ |
262 | | SPLAY_LINKLEFT(head, __right, field); \ |
263 | | } else if (__comp > 0) { \ |
264 | | __tmp = SPLAY_RIGHT((head)->sph_root, field); \ |
265 | | if (__tmp == NULL) \ |
266 | | break; \ |
267 | | if (__comp > 0) { \ |
268 | | SPLAY_ROTATE_LEFT(head, __tmp, field); \ |
269 | | if (SPLAY_RIGHT((head)->sph_root, field) == NULL)\ |
270 | | break; \ |
271 | | } \ |
272 | | SPLAY_LINKRIGHT(head, __left, field); \ |
273 | | } \ |
274 | | } \ |
275 | | SPLAY_ASSEMBLE(head, &__node, __left, __right, field); \ |
276 | | } |
277 | | |
278 | | #define SPLAY_NEGINF -1 |
279 | | #define SPLAY_INF 1 |
280 | | |
281 | | #define SPLAY_INSERT(name, x, y) name##_SPLAY_INSERT(x, y) |
282 | | #define SPLAY_REMOVE(name, x, y) name##_SPLAY_REMOVE(x, y) |
283 | | #define SPLAY_FIND(name, x, y) name##_SPLAY_FIND(x, y) |
284 | | #define SPLAY_NEXT(name, x, y) name##_SPLAY_NEXT(x, y) |
285 | | #define SPLAY_MIN(name, x) (SPLAY_EMPTY(x) ? NULL \ |
286 | | : name##_SPLAY_MIN_MAX(x, SPLAY_NEGINF)) |
287 | | #define SPLAY_MAX(name, x) (SPLAY_EMPTY(x) ? NULL \ |
288 | | : name##_SPLAY_MIN_MAX(x, SPLAY_INF)) |
289 | | |
290 | | #define SPLAY_FOREACH(x, name, head) \ |
291 | | for ((x) = SPLAY_MIN(name, head); \ |
292 | | (x) != NULL; \ |
293 | | (x) = SPLAY_NEXT(name, head, x)) |
294 | | |
295 | | /* Macros that define a red-black tree */ |
296 | | #define RB_HEAD(name, type) \ |
297 | | struct name { \ |
298 | | struct type *rbh_root; /* root of the tree */ \ |
299 | | } |
300 | | |
301 | | #define RB_INITIALIZER(root) \ |
302 | | { NULL } |
303 | | |
304 | 14.3k | #define RB_INIT(root) do { \ |
305 | 14.3k | (root)->rbh_root = NULL; \ |
306 | 14.3k | } while (/*CONSTCOND*/ 0) |
307 | | |
308 | 481k | #define RB_BLACK 0 |
309 | 545k | #define RB_RED 1 |
310 | | #define RB_ENTRY(type) \ |
311 | | struct { \ |
312 | | struct type *rbe_left; /* left element */ \ |
313 | | struct type *rbe_right; /* right element */ \ |
314 | | struct type *rbe_parent; /* parent element */ \ |
315 | | int rbe_color; /* node color */ \ |
316 | | } |
317 | | |
318 | 1.17M | #define RB_LEFT(elm, field) (elm)->field.rbe_left |
319 | 1.17M | #define RB_RIGHT(elm, field) (elm)->field.rbe_right |
320 | 1.20M | #define RB_PARENT(elm, field) (elm)->field.rbe_parent |
321 | 1.04M | #define RB_COLOR(elm, field) (elm)->field.rbe_color |
322 | 219k | #define RB_ROOT(head) (head)->rbh_root |
323 | 8.74k | #define RB_EMPTY(head) (RB_ROOT(head) == NULL) |
324 | | |
325 | 97.2k | #define RB_SET(elm, parent, field) do { \ |
326 | 97.2k | RB_PARENT(elm, field) = parent; \ |
327 | 97.2k | RB_LEFT(elm, field) = RB_RIGHT(elm, field) = NULL; \ |
328 | 97.2k | RB_COLOR(elm, field) = RB_RED; \ |
329 | 97.2k | } while (/*CONSTCOND*/ 0) |
330 | | |
331 | 118k | #define RB_SET_BLACKRED(black, red, field) do { \ |
332 | 118k | RB_COLOR(black, field) = RB_BLACK; \ |
333 | 118k | RB_COLOR(red, field) = RB_RED; \ |
334 | 118k | } while (/*CONSTCOND*/ 0) |
335 | | |
336 | | #ifndef RB_AUGMENT |
337 | 363k | #define RB_AUGMENT(x) do {} while (0) |
338 | | #endif |
339 | | |
340 | 68.7k | #define RB_ROTATE_LEFT(head, elm, tmp, field) do { \ |
341 | 68.7k | (tmp) = RB_RIGHT(elm, field); \ |
342 | 68.7k | if ((RB_RIGHT(elm, field) = RB_LEFT(tmp, field)) != NULL) { \ |
343 | 32.4k | RB_PARENT(RB_LEFT(tmp, field), field) = (elm); \ |
344 | 32.4k | } \ |
345 | 68.7k | RB_AUGMENT(elm); \ |
346 | 68.7k | if ((RB_PARENT(tmp, field) = RB_PARENT(elm, field)) != NULL) { \ |
347 | 49.0k | if ((elm) == RB_LEFT(RB_PARENT(elm, field), field)) \ |
348 | 49.0k | RB_LEFT(RB_PARENT(elm, field), field) = (tmp); \ |
349 | 49.0k | else \ |
350 | 49.0k | RB_RIGHT(RB_PARENT(elm, field), field) = (tmp); \ |
351 | 49.0k | } else \ |
352 | 68.7k | (head)->rbh_root = (tmp); \ |
353 | 68.7k | RB_LEFT(tmp, field) = (elm); \ |
354 | 68.7k | RB_PARENT(elm, field) = (tmp); \ |
355 | 68.7k | RB_AUGMENT(tmp); \ |
356 | 68.7k | if ((RB_PARENT(tmp, field))) \ |
357 | 68.7k | RB_AUGMENT(RB_PARENT(tmp, field)); \ |
358 | 68.7k | } while (/*CONSTCOND*/ 0) |
359 | | |
360 | 12.9k | #define RB_ROTATE_RIGHT(head, elm, tmp, field) do { \ |
361 | 12.9k | (tmp) = RB_LEFT(elm, field); \ |
362 | 12.9k | if ((RB_LEFT(elm, field) = RB_RIGHT(tmp, field)) != NULL) { \ |
363 | 3.71k | RB_PARENT(RB_RIGHT(tmp, field), field) = (elm); \ |
364 | 3.71k | } \ |
365 | 12.9k | RB_AUGMENT(elm); \ |
366 | 12.9k | if ((RB_PARENT(tmp, field) = RB_PARENT(elm, field)) != NULL) { \ |
367 | 12.7k | if ((elm) == RB_LEFT(RB_PARENT(elm, field), field)) \ |
368 | 12.7k | RB_LEFT(RB_PARENT(elm, field), field) = (tmp); \ |
369 | 12.7k | else \ |
370 | 12.7k | RB_RIGHT(RB_PARENT(elm, field), field) = (tmp); \ |
371 | 12.7k | } else \ |
372 | 12.9k | (head)->rbh_root = (tmp); \ |
373 | 12.9k | RB_RIGHT(tmp, field) = (elm); \ |
374 | 12.9k | RB_PARENT(elm, field) = (tmp); \ |
375 | 12.9k | RB_AUGMENT(tmp); \ |
376 | 12.9k | if ((RB_PARENT(tmp, field))) \ |
377 | 12.9k | RB_AUGMENT(RB_PARENT(tmp, field)); \ |
378 | 12.9k | } while (/*CONSTCOND*/ 0) |
379 | | |
380 | | /* Generates prototypes and inline functions */ |
381 | | #define RB_PROTOTYPE(name, type, field, cmp) \ |
382 | | RB_PROTOTYPE_INTERNAL(name, type, field, cmp,) |
383 | | #define RB_PROTOTYPE_STATIC(name, type, field, cmp) \ |
384 | | RB_PROTOTYPE_INTERNAL(name, type, field, cmp, __unused static) |
385 | | #define RB_PROTOTYPE_INTERNAL(name, type, field, cmp, attr) \ |
386 | | RB_PROTOTYPE_INSERT_COLOR(name, type, attr); \ |
387 | | RB_PROTOTYPE_REMOVE_COLOR(name, type, attr); \ |
388 | | RB_PROTOTYPE_INSERT(name, type, attr); \ |
389 | | RB_PROTOTYPE_REMOVE(name, type, attr); \ |
390 | | RB_PROTOTYPE_FIND(name, type, attr); \ |
391 | | RB_PROTOTYPE_NFIND(name, type, attr); \ |
392 | | RB_PROTOTYPE_NEXT(name, type, attr); \ |
393 | | RB_PROTOTYPE_PREV(name, type, attr); \ |
394 | | RB_PROTOTYPE_MINMAX(name, type, attr); |
395 | | #define RB_PROTOTYPE_INSERT_COLOR(name, type, attr) \ |
396 | | attr void name##_RB_INSERT_COLOR(struct name *, struct type *) |
397 | | #define RB_PROTOTYPE_REMOVE_COLOR(name, type, attr) \ |
398 | | attr void name##_RB_REMOVE_COLOR(struct name *, struct type *, struct type *) |
399 | | #define RB_PROTOTYPE_REMOVE(name, type, attr) \ |
400 | | attr struct type *name##_RB_REMOVE(struct name *, struct type *) |
401 | | #define RB_PROTOTYPE_INSERT(name, type, attr) \ |
402 | | attr struct type *name##_RB_INSERT(struct name *, struct type *) |
403 | | #define RB_PROTOTYPE_FIND(name, type, attr) \ |
404 | | attr struct type *name##_RB_FIND(struct name *, struct type *) |
405 | | #define RB_PROTOTYPE_NFIND(name, type, attr) \ |
406 | | attr struct type *name##_RB_NFIND(struct name *, struct type *) |
407 | | #define RB_PROTOTYPE_NEXT(name, type, attr) \ |
408 | | attr struct type *name##_RB_NEXT(struct type *) |
409 | | #define RB_PROTOTYPE_PREV(name, type, attr) \ |
410 | | attr struct type *name##_RB_PREV(struct type *) |
411 | | #define RB_PROTOTYPE_MINMAX(name, type, attr) \ |
412 | | attr struct type *name##_RB_MINMAX(struct name *, int) |
413 | | |
414 | | /* Main rb operation. |
415 | | * Moves node close to the key of elm to top |
416 | | */ |
417 | | #define RB_GENERATE(name, type, field, cmp) \ |
418 | | RB_GENERATE_INTERNAL(name, type, field, cmp,) |
419 | | #define RB_GENERATE_STATIC(name, type, field, cmp) \ |
420 | | RB_GENERATE_INTERNAL(name, type, field, cmp, __unused static) |
421 | | #define RB_GENERATE_INTERNAL(name, type, field, cmp, attr) \ |
422 | | RB_GENERATE_INSERT_COLOR(name, type, field, attr) \ |
423 | | RB_GENERATE_REMOVE_COLOR(name, type, field, attr) \ |
424 | | RB_GENERATE_INSERT(name, type, field, cmp, attr) \ |
425 | | RB_GENERATE_REMOVE(name, type, field, attr) \ |
426 | | RB_GENERATE_FIND(name, type, field, cmp, attr) \ |
427 | | RB_GENERATE_NFIND(name, type, field, cmp, attr) \ |
428 | | RB_GENERATE_NEXT(name, type, field, attr) \ |
429 | | RB_GENERATE_PREV(name, type, field, attr) \ |
430 | | RB_GENERATE_MINMAX(name, type, field, attr) |
431 | | |
432 | | #define RB_GENERATE_INSERT_COLOR(name, type, field, attr) \ |
433 | | attr void \ |
434 | 97.2k | name##_RB_INSERT_COLOR(struct name *head, struct type *elm) \ |
435 | 97.2k | { \ |
436 | 97.2k | struct type *parent, *gparent, *tmp; \ |
437 | 203k | while ((parent = RB_PARENT(elm, field)) != NULL && \ |
438 | 203k | RB_COLOR(parent, field) == RB_RED) { \ |
439 | 106k | gparent = RB_PARENT(parent, field); \ |
440 | 106k | if (parent == RB_LEFT(gparent, field)) { \ |
441 | 18.5k | tmp = RB_RIGHT(gparent, field); \ |
442 | 18.5k | if (tmp && RB_COLOR(tmp, field) == RB_RED) { \ |
443 | 9.48k | RB_COLOR(tmp, field) = RB_BLACK; \ |
444 | 9.48k | RB_SET_BLACKRED(parent, gparent, field);\ |
445 | 9.48k | elm = gparent; \ |
446 | 9.48k | continue; \ |
447 | 9.48k | } \ |
448 | 18.5k | if (RB_RIGHT(parent, field) == elm) { \ |
449 | 5.03k | RB_ROTATE_LEFT(head, parent, tmp, field);\ |
450 | 5.03k | tmp = parent; \ |
451 | 5.03k | parent = elm; \ |
452 | 5.03k | elm = tmp; \ |
453 | 5.03k | } \ |
454 | 9.02k | RB_SET_BLACKRED(parent, gparent, field); \ |
455 | 9.02k | RB_ROTATE_RIGHT(head, gparent, tmp, field); \ |
456 | 88.0k | } else { \ |
457 | 88.0k | tmp = RB_LEFT(gparent, field); \ |
458 | 88.0k | if (tmp && RB_COLOR(tmp, field) == RB_RED) { \ |
459 | 42.9k | RB_COLOR(tmp, field) = RB_BLACK; \ |
460 | 42.9k | RB_SET_BLACKRED(parent, gparent, field);\ |
461 | 42.9k | elm = gparent; \ |
462 | 42.9k | continue; \ |
463 | 42.9k | } \ |
464 | 88.0k | if (RB_LEFT(parent, field) == elm) { \ |
465 | 3.97k | RB_ROTATE_RIGHT(head, parent, tmp, field);\ |
466 | 3.97k | tmp = parent; \ |
467 | 3.97k | parent = elm; \ |
468 | 3.97k | elm = tmp; \ |
469 | 3.97k | } \ |
470 | 45.0k | RB_SET_BLACKRED(parent, gparent, field); \ |
471 | 45.0k | RB_ROTATE_LEFT(head, gparent, tmp, field); \ |
472 | 45.0k | } \ |
473 | 106k | } \ |
474 | 97.2k | RB_COLOR(head->rbh_root, field) = RB_BLACK; \ |
475 | 97.2k | } |
476 | | |
477 | | #define RB_GENERATE_REMOVE_COLOR(name, type, field, attr) \ |
478 | | attr void \ |
479 | 56.5k | name##_RB_REMOVE_COLOR(struct name *head, struct type *parent, struct type *elm) \ |
480 | 56.5k | { \ |
481 | 56.5k | struct type *tmp; \ |
482 | 88.7k | while ((elm == NULL || RB_COLOR(elm, field) == RB_BLACK) && \ |
483 | 88.7k | elm != RB_ROOT(head)) { \ |
484 | 38.9k | if (RB_LEFT(parent, field) == elm) { \ |
485 | 38.9k | tmp = RB_RIGHT(parent, field); \ |
486 | 38.9k | if (RB_COLOR(tmp, field) == RB_RED) { \ |
487 | 11.7k | RB_SET_BLACKRED(tmp, parent, field); \ |
488 | 11.7k | RB_ROTATE_LEFT(head, parent, tmp, field);\ |
489 | 11.7k | tmp = RB_RIGHT(parent, field); \ |
490 | 11.7k | } \ |
491 | 38.9k | if ((RB_LEFT(tmp, field) == NULL || \ |
492 | 38.9k | RB_COLOR(RB_LEFT(tmp, field), field) == RB_BLACK) &&\ |
493 | 38.9k | (RB_RIGHT(tmp, field) == NULL || \ |
494 | 35.7k | RB_COLOR(RB_RIGHT(tmp, field), field) == RB_BLACK)) {\ |
495 | 32.1k | RB_COLOR(tmp, field) = RB_RED; \ |
496 | 32.1k | elm = parent; \ |
497 | 32.1k | parent = RB_PARENT(elm, field); \ |
498 | 32.1k | } else { \ |
499 | 6.86k | if (RB_RIGHT(tmp, field) == NULL || \ |
500 | 6.86k | RB_COLOR(RB_RIGHT(tmp, field), field) == RB_BLACK) {\ |
501 | 0 | struct type *oleft; \ |
502 | 0 | if ((oleft = RB_LEFT(tmp, field)) \ |
503 | 0 | != NULL) \ |
504 | 0 | RB_COLOR(oleft, field) = RB_BLACK;\ |
505 | 0 | RB_COLOR(tmp, field) = RB_RED; \ |
506 | 0 | RB_ROTATE_RIGHT(head, tmp, oleft, field);\ |
507 | 0 | tmp = RB_RIGHT(parent, field); \ |
508 | 0 | } \ |
509 | 6.86k | RB_COLOR(tmp, field) = RB_COLOR(parent, field);\ |
510 | 6.86k | RB_COLOR(parent, field) = RB_BLACK; \ |
511 | 6.86k | if (RB_RIGHT(tmp, field)) \ |
512 | 6.86k | RB_COLOR(RB_RIGHT(tmp, field), field) = RB_BLACK;\ |
513 | 6.86k | RB_ROTATE_LEFT(head, parent, tmp, field);\ |
514 | 6.86k | elm = RB_ROOT(head); \ |
515 | 6.86k | break; \ |
516 | 6.86k | } \ |
517 | 38.9k | } else { \ |
518 | 0 | tmp = RB_LEFT(parent, field); \ |
519 | 0 | if (RB_COLOR(tmp, field) == RB_RED) { \ |
520 | 0 | RB_SET_BLACKRED(tmp, parent, field); \ |
521 | 0 | RB_ROTATE_RIGHT(head, parent, tmp, field);\ |
522 | 0 | tmp = RB_LEFT(parent, field); \ |
523 | 0 | } \ |
524 | 0 | if ((RB_LEFT(tmp, field) == NULL || \ |
525 | 0 | RB_COLOR(RB_LEFT(tmp, field), field) == RB_BLACK) &&\ |
526 | 0 | (RB_RIGHT(tmp, field) == NULL || \ |
527 | 0 | RB_COLOR(RB_RIGHT(tmp, field), field) == RB_BLACK)) {\ |
528 | 0 | RB_COLOR(tmp, field) = RB_RED; \ |
529 | 0 | elm = parent; \ |
530 | 0 | parent = RB_PARENT(elm, field); \ |
531 | 0 | } else { \ |
532 | 0 | if (RB_LEFT(tmp, field) == NULL || \ |
533 | 0 | RB_COLOR(RB_LEFT(tmp, field), field) == RB_BLACK) {\ |
534 | 0 | struct type *oright; \ |
535 | 0 | if ((oright = RB_RIGHT(tmp, field)) \ |
536 | 0 | != NULL) \ |
537 | 0 | RB_COLOR(oright, field) = RB_BLACK;\ |
538 | 0 | RB_COLOR(tmp, field) = RB_RED; \ |
539 | 0 | RB_ROTATE_LEFT(head, tmp, oright, field);\ |
540 | 0 | tmp = RB_LEFT(parent, field); \ |
541 | 0 | } \ |
542 | 0 | RB_COLOR(tmp, field) = RB_COLOR(parent, field);\ |
543 | 0 | RB_COLOR(parent, field) = RB_BLACK; \ |
544 | 0 | if (RB_LEFT(tmp, field)) \ |
545 | 0 | RB_COLOR(RB_LEFT(tmp, field), field) = RB_BLACK;\ |
546 | 0 | RB_ROTATE_RIGHT(head, parent, tmp, field);\ |
547 | 0 | elm = RB_ROOT(head); \ |
548 | 0 | break; \ |
549 | 0 | } \ |
550 | 0 | } \ |
551 | 38.9k | } \ |
552 | 56.5k | if (elm) \ |
553 | 56.5k | RB_COLOR(elm, field) = RB_BLACK; \ |
554 | 56.5k | } |
555 | | |
556 | | #define RB_GENERATE_REMOVE(name, type, field, attr) \ |
557 | | attr struct type * \ |
558 | 56.8k | name##_RB_REMOVE(struct name *head, struct type *elm) \ |
559 | 56.8k | { \ |
560 | 56.8k | struct type *child, *parent, *old = elm; \ |
561 | 56.8k | int color; \ |
562 | 56.8k | if (RB_LEFT(elm, field) == NULL) \ |
563 | 56.8k | child = RB_RIGHT(elm, field); \ |
564 | 56.8k | else if (RB_RIGHT(elm, field) == NULL) \ |
565 | 0 | child = RB_LEFT(elm, field); \ |
566 | 0 | else { \ |
567 | 0 | struct type *left; \ |
568 | 0 | elm = RB_RIGHT(elm, field); \ |
569 | 0 | while ((left = RB_LEFT(elm, field)) != NULL) \ |
570 | 0 | elm = left; \ |
571 | 0 | child = RB_RIGHT(elm, field); \ |
572 | 0 | parent = RB_PARENT(elm, field); \ |
573 | 0 | color = RB_COLOR(elm, field); \ |
574 | 0 | if (child) \ |
575 | 0 | RB_PARENT(child, field) = parent; \ |
576 | 0 | if (parent) { \ |
577 | 0 | if (RB_LEFT(parent, field) == elm) \ |
578 | 0 | RB_LEFT(parent, field) = child; \ |
579 | 0 | else \ |
580 | 0 | RB_RIGHT(parent, field) = child; \ |
581 | 0 | RB_AUGMENT(parent); \ |
582 | 0 | } else \ |
583 | 0 | RB_ROOT(head) = child; \ |
584 | 0 | if (RB_PARENT(elm, field) == old) \ |
585 | 0 | parent = elm; \ |
586 | 0 | (elm)->field = (old)->field; \ |
587 | 0 | if (RB_PARENT(old, field)) { \ |
588 | 0 | if (RB_LEFT(RB_PARENT(old, field), field) == old)\ |
589 | 0 | RB_LEFT(RB_PARENT(old, field), field) = elm;\ |
590 | 0 | else \ |
591 | 0 | RB_RIGHT(RB_PARENT(old, field), field) = elm;\ |
592 | 0 | RB_AUGMENT(RB_PARENT(old, field)); \ |
593 | 0 | } else \ |
594 | 0 | RB_ROOT(head) = elm; \ |
595 | 0 | RB_PARENT(RB_LEFT(old, field), field) = elm; \ |
596 | 0 | if (RB_RIGHT(old, field)) \ |
597 | 0 | RB_PARENT(RB_RIGHT(old, field), field) = elm; \ |
598 | 0 | if (parent) { \ |
599 | 0 | left = parent; \ |
600 | 0 | do { \ |
601 | 0 | RB_AUGMENT(left); \ |
602 | 0 | } while ((left = RB_PARENT(left, field)) != NULL); \ |
603 | 0 | } \ |
604 | 0 | goto color; \ |
605 | 0 | } \ |
606 | 56.8k | parent = RB_PARENT(elm, field); \ |
607 | 56.8k | color = RB_COLOR(elm, field); \ |
608 | 56.8k | if (child) \ |
609 | 56.8k | RB_PARENT(child, field) = parent; \ |
610 | 56.8k | if (parent) { \ |
611 | 47.7k | if (RB_LEFT(parent, field) == elm) \ |
612 | 47.7k | RB_LEFT(parent, field) = child; \ |
613 | 47.7k | else \ |
614 | 47.7k | RB_RIGHT(parent, field) = child; \ |
615 | 47.7k | RB_AUGMENT(parent); \ |
616 | 47.7k | } else \ |
617 | 56.8k | RB_ROOT(head) = child; \ |
618 | 56.8k | color: \ |
619 | 56.8k | if (color == RB_BLACK) \ |
620 | 56.8k | name##_RB_REMOVE_COLOR(head, parent, child); \ |
621 | 56.8k | return (old); \ |
622 | 56.8k | } \ |
623 | | |
624 | | #define RB_GENERATE_INSERT(name, type, field, cmp, attr) \ |
625 | | /* Inserts a node into the RB tree */ \ |
626 | | attr struct type * \ |
627 | 108k | name##_RB_INSERT(struct name *head, struct type *elm) \ |
628 | 108k | { \ |
629 | 108k | struct type *tmp; \ |
630 | 108k | struct type *parent = NULL; \ |
631 | 108k | int comp = 0; \ |
632 | 108k | tmp = RB_ROOT(head); \ |
633 | 662k | while (tmp) { \ |
634 | 565k | parent = tmp; \ |
635 | 565k | comp = (cmp)(elm, parent); \ |
636 | 565k | if (comp < 0) \ |
637 | 565k | tmp = RB_LEFT(tmp, field); \ |
638 | 565k | else if (comp > 0) \ |
639 | 400k | tmp = RB_RIGHT(tmp, field); \ |
640 | 400k | else \ |
641 | 400k | return (tmp); \ |
642 | 565k | } \ |
643 | 108k | RB_SET(elm, parent, field); \ |
644 | 97.2k | if (parent != NULL) { \ |
645 | 90.9k | if (comp < 0) \ |
646 | 90.9k | RB_LEFT(parent, field) = elm; \ |
647 | 90.9k | else \ |
648 | 90.9k | RB_RIGHT(parent, field) = elm; \ |
649 | 90.9k | RB_AUGMENT(parent); \ |
650 | 90.9k | } else \ |
651 | 97.2k | RB_ROOT(head) = elm; \ |
652 | 97.2k | name##_RB_INSERT_COLOR(head, elm); \ |
653 | 97.2k | return (NULL); \ |
654 | 108k | } |
655 | | |
656 | | #define RB_GENERATE_FIND(name, type, field, cmp, attr) \ |
657 | | /* Finds the node with the same key as elm */ \ |
658 | | attr struct type * \ |
659 | 1.59k | name##_RB_FIND(struct name *head, struct type *elm) \ |
660 | 1.59k | { \ |
661 | 1.59k | struct type *tmp = RB_ROOT(head); \ |
662 | 1.59k | int comp; \ |
663 | 1.59k | while (tmp) { \ |
664 | 0 | comp = cmp(elm, tmp); \ |
665 | 0 | if (comp < 0) \ |
666 | 0 | tmp = RB_LEFT(tmp, field); \ |
667 | 0 | else if (comp > 0) \ |
668 | 0 | tmp = RB_RIGHT(tmp, field); \ |
669 | 0 | else \ |
670 | 0 | return (tmp); \ |
671 | 0 | } \ |
672 | 1.59k | return (NULL); \ |
673 | 1.59k | } |
674 | | |
675 | | #define RB_GENERATE_NFIND(name, type, field, cmp, attr) \ |
676 | | /* Finds the first node greater than or equal to the search key */ \ |
677 | | attr struct type * \ |
678 | | name##_RB_NFIND(struct name *head, struct type *elm) \ |
679 | | { \ |
680 | | struct type *tmp = RB_ROOT(head); \ |
681 | | struct type *res = NULL; \ |
682 | | int comp; \ |
683 | | while (tmp) { \ |
684 | | comp = cmp(elm, tmp); \ |
685 | | if (comp < 0) { \ |
686 | | res = tmp; \ |
687 | | tmp = RB_LEFT(tmp, field); \ |
688 | | } \ |
689 | | else if (comp > 0) \ |
690 | | tmp = RB_RIGHT(tmp, field); \ |
691 | | else \ |
692 | | return (tmp); \ |
693 | | } \ |
694 | | return (res); \ |
695 | | } |
696 | | |
697 | | #define RB_GENERATE_NEXT(name, type, field, attr) \ |
698 | | /* ARGSUSED */ \ |
699 | | attr struct type * \ |
700 | 116k | name##_RB_NEXT(struct type *elm) \ |
701 | 116k | { \ |
702 | 116k | if (RB_RIGHT(elm, field)) { \ |
703 | 53.2k | elm = RB_RIGHT(elm, field); \ |
704 | 71.5k | while (RB_LEFT(elm, field)) \ |
705 | 53.2k | elm = RB_LEFT(elm, field); \ |
706 | 63.5k | } else { \ |
707 | 63.5k | if (RB_PARENT(elm, field) && \ |
708 | 63.5k | (elm == RB_LEFT(RB_PARENT(elm, field), field))) \ |
709 | 63.5k | elm = RB_PARENT(elm, field); \ |
710 | 63.5k | else { \ |
711 | 49.2k | while (RB_PARENT(elm, field) && \ |
712 | 49.2k | (elm == RB_RIGHT(RB_PARENT(elm, field), field)))\ |
713 | 28.2k | elm = RB_PARENT(elm, field); \ |
714 | 21.0k | elm = RB_PARENT(elm, field); \ |
715 | 21.0k | } \ |
716 | 63.5k | } \ |
717 | 116k | return (elm); \ |
718 | 116k | } workbook.c:lxw_worksheet_names_RB_NEXT Line | Count | Source | 700 | 797 | name##_RB_NEXT(struct type *elm) \ | 701 | 797 | { \ | 702 | 797 | if (RB_RIGHT(elm, field)) { \ | 703 | 0 | elm = RB_RIGHT(elm, field); \ | 704 | 0 | while (RB_LEFT(elm, field)) \ | 705 | 0 | elm = RB_LEFT(elm, field); \ | 706 | 797 | } else { \ | 707 | 797 | if (RB_PARENT(elm, field) && \ | 708 | 797 | (elm == RB_LEFT(RB_PARENT(elm, field), field))) \ | 709 | 797 | elm = RB_PARENT(elm, field); \ | 710 | 797 | else { \ | 711 | 797 | while (RB_PARENT(elm, field) && \ | 712 | 797 | (elm == RB_RIGHT(RB_PARENT(elm, field), field)))\ | 713 | 797 | elm = RB_PARENT(elm, field); \ | 714 | 797 | elm = RB_PARENT(elm, field); \ | 715 | 797 | } \ | 716 | 797 | } \ | 717 | 797 | return (elm); \ | 718 | 797 | } |
Unexecuted instantiation: workbook.c:lxw_chartsheet_names_RB_NEXT Unexecuted instantiation: workbook.c:lxw_image_md5s_RB_NEXT worksheet.c:lxw_table_rows_RB_NEXT Line | Count | Source | 700 | 12.0k | name##_RB_NEXT(struct type *elm) \ | 701 | 12.0k | { \ | 702 | 12.0k | if (RB_RIGHT(elm, field)) { \ | 703 | 5.02k | elm = RB_RIGHT(elm, field); \ | 704 | 7.07k | while (RB_LEFT(elm, field)) \ | 705 | 5.02k | elm = RB_LEFT(elm, field); \ | 706 | 6.98k | } else { \ | 707 | 6.98k | if (RB_PARENT(elm, field) && \ | 708 | 6.98k | (elm == RB_LEFT(RB_PARENT(elm, field), field))) \ | 709 | 6.98k | elm = RB_PARENT(elm, field); \ | 710 | 6.98k | else { \ | 711 | 6.77k | while (RB_PARENT(elm, field) && \ | 712 | 6.77k | (elm == RB_RIGHT(RB_PARENT(elm, field), field)))\ | 713 | 3.43k | elm = RB_PARENT(elm, field); \ | 714 | 3.33k | elm = RB_PARENT(elm, field); \ | 715 | 3.33k | } \ | 716 | 6.98k | } \ | 717 | 12.0k | return (elm); \ | 718 | 12.0k | } |
Unexecuted instantiation: worksheet.c:lxw_drawing_rel_ids_RB_NEXT Unexecuted instantiation: worksheet.c:lxw_vml_drawing_rel_ids_RB_NEXT Unexecuted instantiation: worksheet.c:lxw_cond_format_hash_RB_NEXT worksheet.c:lxw_table_cells_RB_NEXT Line | Count | Source | 700 | 104k | name##_RB_NEXT(struct type *elm) \ | 701 | 104k | { \ | 702 | 104k | if (RB_RIGHT(elm, field)) { \ | 703 | 48.2k | elm = RB_RIGHT(elm, field); \ | 704 | 64.4k | while (RB_LEFT(elm, field)) \ | 705 | 48.2k | elm = RB_LEFT(elm, field); \ | 706 | 55.7k | } else { \ | 707 | 55.7k | if (RB_PARENT(elm, field) && \ | 708 | 55.7k | (elm == RB_LEFT(RB_PARENT(elm, field), field))) \ | 709 | 55.7k | elm = RB_PARENT(elm, field); \ | 710 | 55.7k | else { \ | 711 | 41.6k | while (RB_PARENT(elm, field) && \ | 712 | 41.6k | (elm == RB_RIGHT(RB_PARENT(elm, field), field)))\ | 713 | 24.7k | elm = RB_PARENT(elm, field); \ | 714 | 16.9k | elm = RB_PARENT(elm, field); \ | 715 | 16.9k | } \ | 716 | 55.7k | } \ | 717 | 104k | return (elm); \ | 718 | 104k | } |
Unexecuted instantiation: comment.c:lxw_author_ids_RB_NEXT |
719 | | |
720 | | #define RB_GENERATE_PREV(name, type, field, attr) \ |
721 | | /* ARGSUSED */ \ |
722 | | attr struct type * \ |
723 | | name##_RB_PREV(struct type *elm) \ |
724 | | { \ |
725 | | if (RB_LEFT(elm, field)) { \ |
726 | | elm = RB_LEFT(elm, field); \ |
727 | | while (RB_RIGHT(elm, field)) \ |
728 | | elm = RB_RIGHT(elm, field); \ |
729 | | } else { \ |
730 | | if (RB_PARENT(elm, field) && \ |
731 | | (elm == RB_RIGHT(RB_PARENT(elm, field), field))) \ |
732 | | elm = RB_PARENT(elm, field); \ |
733 | | else { \ |
734 | | while (RB_PARENT(elm, field) && \ |
735 | | (elm == RB_LEFT(RB_PARENT(elm, field), field)))\ |
736 | | elm = RB_PARENT(elm, field); \ |
737 | | elm = RB_PARENT(elm, field); \ |
738 | | } \ |
739 | | } \ |
740 | | return (elm); \ |
741 | | } |
742 | | |
743 | | #define RB_GENERATE_MINMAX(name, type, field, attr) \ |
744 | | attr struct type * \ |
745 | 27.1k | name##_RB_MINMAX(struct name *head, int val) \ |
746 | 27.1k | { \ |
747 | 27.1k | struct type *tmp = RB_ROOT(head); \ |
748 | 27.1k | struct type *parent = NULL; \ |
749 | 81.8k | while (tmp) { \ |
750 | 54.7k | parent = tmp; \ |
751 | 54.7k | if (val < 0) \ |
752 | 54.7k | tmp = RB_LEFT(tmp, field); \ |
753 | 54.7k | else \ |
754 | 54.7k | tmp = RB_RIGHT(tmp, field); \ |
755 | 54.7k | } \ |
756 | 27.1k | return (parent); \ |
757 | 27.1k | } |
758 | | |
759 | 23.1k | #define RB_NEGINF -1 |
760 | 4.00k | #define RB_INF 1 |
761 | | |
762 | 108k | #define RB_INSERT(name, x, y) name##_RB_INSERT(x, y) |
763 | 56.8k | #define RB_REMOVE(name, x, y) name##_RB_REMOVE(x, y) |
764 | 1.59k | #define RB_FIND(name, x, y) name##_RB_FIND(x, y) |
765 | | #define RB_NFIND(name, x, y) name##_RB_NFIND(x, y) |
766 | 60.8k | #define RB_NEXT(name, x, y) name##_RB_NEXT(y) |
767 | | #define RB_PREV(name, x, y) name##_RB_PREV(y) |
768 | 23.1k | #define RB_MIN(name, x) name##_RB_MINMAX(x, RB_NEGINF) |
769 | 4.00k | #define RB_MAX(name, x) name##_RB_MINMAX(x, RB_INF) |
770 | | |
771 | | #define RB_FOREACH(x, name, head) \ |
772 | 4.73k | for ((x) = RB_MIN(name, head); \ |
773 | 60.7k | (x) != NULL; \ |
774 | 56.0k | (x) = name##_RB_NEXT(x)) |
775 | | |
776 | | #define RB_FOREACH_FROM(x, name, y) \ |
777 | | for ((x) = (y); \ |
778 | | ((x) != NULL) && ((y) = name##_RB_NEXT(x), (x) != NULL); \ |
779 | | (x) = (y)) |
780 | | |
781 | | #define RB_FOREACH_SAFE(x, name, head, y) \ |
782 | | for ((x) = RB_MIN(name, head); \ |
783 | | ((x) != NULL) && ((y) = name##_RB_NEXT(x), (x) != NULL); \ |
784 | | (x) = (y)) |
785 | | |
786 | | #define RB_FOREACH_REVERSE(x, name, head) \ |
787 | | for ((x) = RB_MAX(name, head); \ |
788 | | (x) != NULL; \ |
789 | | (x) = name##_RB_PREV(x)) |
790 | | |
791 | | #define RB_FOREACH_REVERSE_FROM(x, name, y) \ |
792 | | for ((x) = (y); \ |
793 | | ((x) != NULL) && ((y) = name##_RB_PREV(x), (x) != NULL); \ |
794 | | (x) = (y)) |
795 | | |
796 | | #define RB_FOREACH_REVERSE_SAFE(x, name, head, y) \ |
797 | | for ((x) = RB_MAX(name, head); \ |
798 | | ((x) != NULL) && ((y) = name##_RB_PREV(x), (x) != NULL); \ |
799 | | (x) = (y)) |
800 | | |
801 | | #endif /* _SYS_TREE_H_ */ |