- add sources.
[platform/framework/web/crosswalk.git] / src / third_party / jemalloc / vendor / rb.h
1 /******************************************************************************
2  *
3  * Copyright (C) 2008 Jason Evans <jasone@FreeBSD.org>.
4  * All rights reserved.
5  *
6  * Redistribution and use in source and binary forms, with or without
7  * modification, are permitted provided that the following conditions
8  * are met:
9  * 1. Redistributions of source code must retain the above copyright
10  *    notice(s), this list of conditions and the following disclaimer
11  *    unmodified other than the allowable addition of one or more
12  *    copyright notices.
13  * 2. Redistributions in binary form must reproduce the above copyright
14  *    notice(s), this list of conditions and the following disclaimer in
15  *    the documentation and/or other materials provided with the
16  *    distribution.
17  *
18  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER(S) ``AS IS'' AND ANY
19  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
21  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) BE
22  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
23  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
24  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
25  * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
26  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
27  * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
28  * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29  *
30  ******************************************************************************
31  *
32  * cpp macro implementation of left-leaning red-black trees.
33  *
34  * Usage:
35  *
36  *   (Optional.)
37  *   #define SIZEOF_PTR ...
38  *   #define SIZEOF_PTR_2POW ...
39  *   #define RB_NO_C99_VARARRAYS
40  *
41  *   (Optional, see assert(3).)
42  *   #define NDEBUG
43  *
44  *   (Required.)
45  *   #include <assert.h>
46  *   #include <rb.h>
47  *   ...
48  *
49  * All operations are done non-recursively.  Parent pointers are not used, and
50  * color bits are stored in the least significant bit of right-child pointers,
51  * thus making node linkage as compact as is possible for red-black trees.
52  *
53  * Some macros use a comparison function pointer, which is expected to have the
54  * following prototype:
55  *
56  *   int (a_cmp *)(a_type *a_node, a_type *a_other);
57  *                         ^^^^^^
58  *                      or a_key
59  *
60  * Interpretation of comparision function return values:
61  *
62  *   -1 : a_node <  a_other
63  *    0 : a_node == a_other
64  *    1 : a_node >  a_other
65  *
66  * In all cases, the a_node or a_key macro argument is the first argument to the
67  * comparison function, which makes it possible to write comparison functions
68  * that treat the first argument specially.
69  *
70  ******************************************************************************/
71
72 #ifndef RB_H_
73 #define RB_H_
74
75 #if 0
76 #include <sys/cdefs.h>
77 __FBSDID("$FreeBSD: head/lib/libc/stdlib/rb.h 178995 2008-05-14 18:33:13Z jasone $");
78 #endif
79
80 /* Node structure. */
81 #define rb_node(a_type)                                                 \
82 struct {                                                                \
83     a_type *rbn_left;                                                   \
84     a_type *rbn_right_red;                                              \
85 }
86
87 /* Root structure. */
88 #define rb_tree(a_type)                                                 \
89 struct {                                                                \
90     a_type *rbt_root;                                                   \
91     a_type rbt_nil;                                                     \
92 }
93
94 /* Left accessors. */
95 #define rbp_left_get(a_type, a_field, a_node)                           \
96     ((a_node)->a_field.rbn_left)
97 #define rbp_left_set(a_type, a_field, a_node, a_left) do {              \
98     (a_node)->a_field.rbn_left = a_left;                                \
99 } while (0)
100
101 /* Right accessors. */
102 #define rbp_right_get(a_type, a_field, a_node)                          \
103     ((a_type *) (((intptr_t) (a_node)->a_field.rbn_right_red)           \
104       & ((ssize_t)-2)))
105 #define rbp_right_set(a_type, a_field, a_node, a_right) do {            \
106     (a_node)->a_field.rbn_right_red = (a_type *) (((uintptr_t) a_right) \
107       | (((uintptr_t) (a_node)->a_field.rbn_right_red) & ((size_t)1))); \
108 } while (0)
109
110 /* Color accessors. */
111 #define rbp_red_get(a_type, a_field, a_node)                            \
112     ((bool) (((uintptr_t) (a_node)->a_field.rbn_right_red)              \
113       & ((size_t)1)))
114 #define rbp_color_set(a_type, a_field, a_node, a_red) do {              \
115     (a_node)->a_field.rbn_right_red = (a_type *) ((((intptr_t)          \
116       (a_node)->a_field.rbn_right_red) & ((ssize_t)-2))                 \
117       | ((ssize_t)a_red));                                              \
118 } while (0)
119 #define rbp_red_set(a_type, a_field, a_node) do {                       \
120     (a_node)->a_field.rbn_right_red = (a_type *) (((uintptr_t)          \
121       (a_node)->a_field.rbn_right_red) | ((size_t)1));                  \
122 } while (0)
123 #define rbp_black_set(a_type, a_field, a_node) do {                     \
124     (a_node)->a_field.rbn_right_red = (a_type *) (((intptr_t)           \
125       (a_node)->a_field.rbn_right_red) & ((ssize_t)-2));                \
126 } while (0)
127
128 /* Node initializer. */
129 #define rbp_node_new(a_type, a_field, a_tree, a_node) do {              \
130     rbp_left_set(a_type, a_field, (a_node), &(a_tree)->rbt_nil);        \
131     rbp_right_set(a_type, a_field, (a_node), &(a_tree)->rbt_nil);       \
132     rbp_red_set(a_type, a_field, (a_node));                             \
133 } while (0)
134
135 /* Tree initializer. */
136 #define rb_new(a_type, a_field, a_tree) do {                            \
137     (a_tree)->rbt_root = &(a_tree)->rbt_nil;                            \
138     rbp_node_new(a_type, a_field, a_tree, &(a_tree)->rbt_nil);          \
139     rbp_black_set(a_type, a_field, &(a_tree)->rbt_nil);                 \
140 } while (0)
141
142 /* Tree operations. */
143 #define rbp_black_height(a_type, a_field, a_tree, r_height) do {        \
144     a_type *rbp_bh_t;                                                   \
145     for (rbp_bh_t = (a_tree)->rbt_root, (r_height) = 0;                 \
146       rbp_bh_t != &(a_tree)->rbt_nil;                                   \
147       rbp_bh_t = rbp_left_get(a_type, a_field, rbp_bh_t)) {             \
148         if (rbp_red_get(a_type, a_field, rbp_bh_t) == false) {          \
149             (r_height)++;                                               \
150         }                                                               \
151     }                                                                   \
152 } while (0)
153
154 #define rbp_first(a_type, a_field, a_tree, a_root, r_node) do {         \
155     for ((r_node) = (a_root);                                           \
156       rbp_left_get(a_type, a_field, (r_node)) != &(a_tree)->rbt_nil;    \
157       (r_node) = rbp_left_get(a_type, a_field, (r_node))) {             \
158     }                                                                   \
159 } while (0)
160
161 #define rbp_last(a_type, a_field, a_tree, a_root, r_node) do {          \
162     for ((r_node) = (a_root);                                           \
163       rbp_right_get(a_type, a_field, (r_node)) != &(a_tree)->rbt_nil;   \
164       (r_node) = rbp_right_get(a_type, a_field, (r_node))) {            \
165     }                                                                   \
166 } while (0)
167
168 #define rbp_next(a_type, a_field, a_cmp, a_tree, a_node, r_node) do {   \
169     if (rbp_right_get(a_type, a_field, (a_node))                        \
170       != &(a_tree)->rbt_nil) {                                          \
171         rbp_first(a_type, a_field, a_tree, rbp_right_get(a_type,        \
172           a_field, (a_node)), (r_node));                                \
173     } else {                                                            \
174         a_type *rbp_n_t = (a_tree)->rbt_root;                           \
175         assert(rbp_n_t != &(a_tree)->rbt_nil);                          \
176         (r_node) = &(a_tree)->rbt_nil;                                  \
177         while (true) {                                                  \
178             int rbp_n_cmp = (a_cmp)((a_node), rbp_n_t);                 \
179             if (rbp_n_cmp < 0) {                                        \
180                 (r_node) = rbp_n_t;                                     \
181                 rbp_n_t = rbp_left_get(a_type, a_field, rbp_n_t);       \
182             } else if (rbp_n_cmp > 0) {                                 \
183                 rbp_n_t = rbp_right_get(a_type, a_field, rbp_n_t);      \
184             } else {                                                    \
185                 break;                                                  \
186             }                                                           \
187             assert(rbp_n_t != &(a_tree)->rbt_nil);                      \
188         }                                                               \
189     }                                                                   \
190 } while (0)
191
192 #define rbp_prev(a_type, a_field, a_cmp, a_tree, a_node, r_node) do {   \
193     if (rbp_left_get(a_type, a_field, (a_node)) != &(a_tree)->rbt_nil) {\
194         rbp_last(a_type, a_field, a_tree, rbp_left_get(a_type,          \
195           a_field, (a_node)), (r_node));                                \
196     } else {                                                            \
197         a_type *rbp_p_t = (a_tree)->rbt_root;                           \
198         assert(rbp_p_t != &(a_tree)->rbt_nil);                          \
199         (r_node) = &(a_tree)->rbt_nil;                                  \
200         while (true) {                                                  \
201             int rbp_p_cmp = (a_cmp)((a_node), rbp_p_t);                 \
202             if (rbp_p_cmp < 0) {                                        \
203                 rbp_p_t = rbp_left_get(a_type, a_field, rbp_p_t);       \
204             } else if (rbp_p_cmp > 0) {                                 \
205                 (r_node) = rbp_p_t;                                     \
206                 rbp_p_t = rbp_right_get(a_type, a_field, rbp_p_t);      \
207             } else {                                                    \
208                 break;                                                  \
209             }                                                           \
210             assert(rbp_p_t != &(a_tree)->rbt_nil);                      \
211         }                                                               \
212     }                                                                   \
213 } while (0)
214
215 #define rb_first(a_type, a_field, a_tree, r_node) do {                  \
216     rbp_first(a_type, a_field, a_tree, (a_tree)->rbt_root, (r_node));   \
217     if ((r_node) == &(a_tree)->rbt_nil) {                               \
218         (r_node) = NULL;                                                \
219     }                                                                   \
220 } while (0)
221
222 #define rb_last(a_type, a_field, a_tree, r_node) do {                   \
223     rbp_last(a_type, a_field, a_tree, (a_tree)->rbt_root, r_node);      \
224     if ((r_node) == &(a_tree)->rbt_nil) {                               \
225         (r_node) = NULL;                                                \
226     }                                                                   \
227 } while (0)
228
229 #define rb_next(a_type, a_field, a_cmp, a_tree, a_node, r_node) do {    \
230     rbp_next(a_type, a_field, a_cmp, a_tree, (a_node), (r_node));       \
231     if ((r_node) == &(a_tree)->rbt_nil) {                               \
232         (r_node) = NULL;                                                \
233     }                                                                   \
234 } while (0)
235
236 #define rb_prev(a_type, a_field, a_cmp, a_tree, a_node, r_node) do {    \
237     rbp_prev(a_type, a_field, a_cmp, a_tree, (a_node), (r_node));       \
238     if ((r_node) == &(a_tree)->rbt_nil) {                               \
239         (r_node) = NULL;                                                \
240     }                                                                   \
241 } while (0)
242
243 #define rb_search(a_type, a_field, a_cmp, a_tree, a_key, r_node) do {   \
244     int rbp_se_cmp;                                                     \
245     (r_node) = (a_tree)->rbt_root;                                      \
246     while ((r_node) != &(a_tree)->rbt_nil                               \
247       && (rbp_se_cmp = (a_cmp)((a_key), (r_node))) != 0) {              \
248         if (rbp_se_cmp < 0) {                                           \
249             (r_node) = rbp_left_get(a_type, a_field, (r_node));         \
250         } else {                                                        \
251             (r_node) = rbp_right_get(a_type, a_field, (r_node));        \
252         }                                                               \
253     }                                                                   \
254     if ((r_node) == &(a_tree)->rbt_nil) {                               \
255         (r_node) = NULL;                                                \
256     }                                                                   \
257 } while (0)
258
259 /*
260  * Find a match if it exists.  Otherwise, find the next greater node, if one
261  * exists.
262  */
263 #define rb_nsearch(a_type, a_field, a_cmp, a_tree, a_key, r_node) do {  \
264     a_type *rbp_ns_t = (a_tree)->rbt_root;                              \
265     (r_node) = NULL;                                                    \
266     while (rbp_ns_t != &(a_tree)->rbt_nil) {                            \
267         int rbp_ns_cmp = (a_cmp)((a_key), rbp_ns_t);                    \
268         if (rbp_ns_cmp < 0) {                                           \
269             (r_node) = rbp_ns_t;                                        \
270             rbp_ns_t = rbp_left_get(a_type, a_field, rbp_ns_t);         \
271         } else if (rbp_ns_cmp > 0) {                                    \
272             rbp_ns_t = rbp_right_get(a_type, a_field, rbp_ns_t);        \
273         } else {                                                        \
274             (r_node) = rbp_ns_t;                                        \
275             break;                                                      \
276         }                                                               \
277     }                                                                   \
278 } while (0)
279
280 /*
281  * Find a match if it exists.  Otherwise, find the previous lesser node, if one
282  * exists.
283  */
284 #define rb_psearch(a_type, a_field, a_cmp, a_tree, a_key, r_node) do {  \
285     a_type *rbp_ps_t = (a_tree)->rbt_root;                              \
286     (r_node) = NULL;                                                    \
287     while (rbp_ps_t != &(a_tree)->rbt_nil) {                            \
288         int rbp_ps_cmp = (a_cmp)((a_key), rbp_ps_t);                    \
289         if (rbp_ps_cmp < 0) {                                           \
290             rbp_ps_t = rbp_left_get(a_type, a_field, rbp_ps_t);         \
291         } else if (rbp_ps_cmp > 0) {                                    \
292             (r_node) = rbp_ps_t;                                        \
293             rbp_ps_t = rbp_right_get(a_type, a_field, rbp_ps_t);        \
294         } else {                                                        \
295             (r_node) = rbp_ps_t;                                        \
296             break;                                                      \
297         }                                                               \
298     }                                                                   \
299 } while (0)
300
301 #define rbp_rotate_left(a_type, a_field, a_node, r_node) do {           \
302     (r_node) = rbp_right_get(a_type, a_field, (a_node));                \
303     rbp_right_set(a_type, a_field, (a_node),                            \
304       rbp_left_get(a_type, a_field, (r_node)));                         \
305     rbp_left_set(a_type, a_field, (r_node), (a_node));                  \
306 } while (0)
307
308 #define rbp_rotate_right(a_type, a_field, a_node, r_node) do {          \
309     (r_node) = rbp_left_get(a_type, a_field, (a_node));                 \
310     rbp_left_set(a_type, a_field, (a_node),                             \
311       rbp_right_get(a_type, a_field, (r_node)));                        \
312     rbp_right_set(a_type, a_field, (r_node), (a_node));                 \
313 } while (0)
314
315 #define rbp_lean_left(a_type, a_field, a_node, r_node) do {             \
316     bool rbp_ll_red;                                                    \
317     rbp_rotate_left(a_type, a_field, (a_node), (r_node));               \
318     rbp_ll_red = rbp_red_get(a_type, a_field, (a_node));                \
319     rbp_color_set(a_type, a_field, (r_node), rbp_ll_red);               \
320     rbp_red_set(a_type, a_field, (a_node));                             \
321 } while (0)
322
323 #define rbp_lean_right(a_type, a_field, a_node, r_node) do {            \
324     bool rbp_lr_red;                                                    \
325     rbp_rotate_right(a_type, a_field, (a_node), (r_node));              \
326     rbp_lr_red = rbp_red_get(a_type, a_field, (a_node));                \
327     rbp_color_set(a_type, a_field, (r_node), rbp_lr_red);               \
328     rbp_red_set(a_type, a_field, (a_node));                             \
329 } while (0)
330
331 #define rbp_move_red_left(a_type, a_field, a_node, r_node) do {         \
332     a_type *rbp_mrl_t, *rbp_mrl_u;                                      \
333     rbp_mrl_t = rbp_left_get(a_type, a_field, (a_node));                \
334     rbp_red_set(a_type, a_field, rbp_mrl_t);                            \
335     rbp_mrl_t = rbp_right_get(a_type, a_field, (a_node));               \
336     rbp_mrl_u = rbp_left_get(a_type, a_field, rbp_mrl_t);               \
337     if (rbp_red_get(a_type, a_field, rbp_mrl_u)) {                      \
338         rbp_rotate_right(a_type, a_field, rbp_mrl_t, rbp_mrl_u);        \
339         rbp_right_set(a_type, a_field, (a_node), rbp_mrl_u);            \
340         rbp_rotate_left(a_type, a_field, (a_node), (r_node));           \
341         rbp_mrl_t = rbp_right_get(a_type, a_field, (a_node));           \
342         if (rbp_red_get(a_type, a_field, rbp_mrl_t)) {                  \
343             rbp_black_set(a_type, a_field, rbp_mrl_t);                  \
344             rbp_red_set(a_type, a_field, (a_node));                     \
345             rbp_rotate_left(a_type, a_field, (a_node), rbp_mrl_t);      \
346             rbp_left_set(a_type, a_field, (r_node), rbp_mrl_t);         \
347         } else {                                                        \
348             rbp_black_set(a_type, a_field, (a_node));                   \
349         }                                                               \
350     } else {                                                            \
351         rbp_red_set(a_type, a_field, (a_node));                         \
352         rbp_rotate_left(a_type, a_field, (a_node), (r_node));           \
353     }                                                                   \
354 } while (0)
355
356 #define rbp_move_red_right(a_type, a_field, a_node, r_node) do {        \
357     a_type *rbp_mrr_t;                                                  \
358     rbp_mrr_t = rbp_left_get(a_type, a_field, (a_node));                \
359     if (rbp_red_get(a_type, a_field, rbp_mrr_t)) {                      \
360         a_type *rbp_mrr_u, *rbp_mrr_v;                                  \
361         rbp_mrr_u = rbp_right_get(a_type, a_field, rbp_mrr_t);          \
362         rbp_mrr_v = rbp_left_get(a_type, a_field, rbp_mrr_u);           \
363         if (rbp_red_get(a_type, a_field, rbp_mrr_v)) {                  \
364             rbp_color_set(a_type, a_field, rbp_mrr_u,                   \
365               rbp_red_get(a_type, a_field, (a_node)));                  \
366             rbp_black_set(a_type, a_field, rbp_mrr_v);                  \
367             rbp_rotate_left(a_type, a_field, rbp_mrr_t, rbp_mrr_u);     \
368             rbp_left_set(a_type, a_field, (a_node), rbp_mrr_u);         \
369             rbp_rotate_right(a_type, a_field, (a_node), (r_node));      \
370             rbp_rotate_left(a_type, a_field, (a_node), rbp_mrr_t);      \
371             rbp_right_set(a_type, a_field, (r_node), rbp_mrr_t);        \
372         } else {                                                        \
373             rbp_color_set(a_type, a_field, rbp_mrr_t,                   \
374               rbp_red_get(a_type, a_field, (a_node)));                  \
375             rbp_red_set(a_type, a_field, rbp_mrr_u);                    \
376             rbp_rotate_right(a_type, a_field, (a_node), (r_node));      \
377             rbp_rotate_left(a_type, a_field, (a_node), rbp_mrr_t);      \
378             rbp_right_set(a_type, a_field, (r_node), rbp_mrr_t);        \
379         }                                                               \
380         rbp_red_set(a_type, a_field, (a_node));                         \
381     } else {                                                            \
382         rbp_red_set(a_type, a_field, rbp_mrr_t);                        \
383         rbp_mrr_t = rbp_left_get(a_type, a_field, rbp_mrr_t);           \
384         if (rbp_red_get(a_type, a_field, rbp_mrr_t)) {                  \
385             rbp_black_set(a_type, a_field, rbp_mrr_t);                  \
386             rbp_rotate_right(a_type, a_field, (a_node), (r_node));      \
387             rbp_rotate_left(a_type, a_field, (a_node), rbp_mrr_t);      \
388             rbp_right_set(a_type, a_field, (r_node), rbp_mrr_t);        \
389         } else {                                                        \
390             rbp_rotate_left(a_type, a_field, (a_node), (r_node));       \
391         }                                                               \
392     }                                                                   \
393 } while (0)
394
395 #define rb_insert(a_type, a_field, a_cmp, a_tree, a_node) do {          \
396     a_type rbp_i_s;                                                     \
397     a_type *rbp_i_g, *rbp_i_p, *rbp_i_c, *rbp_i_t, *rbp_i_u;            \
398     int rbp_i_cmp = 0;                                                  \
399     rbp_i_g = &(a_tree)->rbt_nil;                                       \
400     rbp_left_set(a_type, a_field, &rbp_i_s, (a_tree)->rbt_root);        \
401     rbp_right_set(a_type, a_field, &rbp_i_s, &(a_tree)->rbt_nil);       \
402     rbp_black_set(a_type, a_field, &rbp_i_s);                           \
403     rbp_i_p = &rbp_i_s;                                                 \
404     rbp_i_c = (a_tree)->rbt_root;                                       \
405     /* Iteratively search down the tree for the insertion point,      */\
406     /* splitting 4-nodes as they are encountered.  At the end of each */\
407     /* iteration, rbp_i_g->rbp_i_p->rbp_i_c is a 3-level path down    */\
408     /* the tree, assuming a sufficiently deep tree.                   */\
409     while (rbp_i_c != &(a_tree)->rbt_nil) {                             \
410         rbp_i_t = rbp_left_get(a_type, a_field, rbp_i_c);               \
411         rbp_i_u = rbp_left_get(a_type, a_field, rbp_i_t);               \
412         if (rbp_red_get(a_type, a_field, rbp_i_t)                       \
413           && rbp_red_get(a_type, a_field, rbp_i_u)) {                   \
414             /* rbp_i_c is the top of a logical 4-node, so split it.   */\
415             /* This iteration does not move down the tree, due to the */\
416             /* disruptiveness of node splitting.                      */\
417             /*                                                        */\
418             /* Rotate right.                                          */\
419             rbp_rotate_right(a_type, a_field, rbp_i_c, rbp_i_t);        \
420             /* Pass red links up one level.                           */\
421             rbp_i_u = rbp_left_get(a_type, a_field, rbp_i_t);           \
422             rbp_black_set(a_type, a_field, rbp_i_u);                    \
423             if (rbp_left_get(a_type, a_field, rbp_i_p) == rbp_i_c) {    \
424                 rbp_left_set(a_type, a_field, rbp_i_p, rbp_i_t);        \
425                 rbp_i_c = rbp_i_t;                                      \
426             } else {                                                    \
427                 /* rbp_i_c was the right child of rbp_i_p, so rotate  */\
428                 /* left in order to maintain the left-leaning         */\
429                 /* invariant.                                         */\
430                 assert(rbp_right_get(a_type, a_field, rbp_i_p)          \
431                   == rbp_i_c);                                          \
432                 rbp_right_set(a_type, a_field, rbp_i_p, rbp_i_t);       \
433                 rbp_lean_left(a_type, a_field, rbp_i_p, rbp_i_u);       \
434                 if (rbp_left_get(a_type, a_field, rbp_i_g) == rbp_i_p) {\
435                     rbp_left_set(a_type, a_field, rbp_i_g, rbp_i_u);    \
436                 } else {                                                \
437                     assert(rbp_right_get(a_type, a_field, rbp_i_g)      \
438                       == rbp_i_p);                                      \
439                     rbp_right_set(a_type, a_field, rbp_i_g, rbp_i_u);   \
440                 }                                                       \
441                 rbp_i_p = rbp_i_u;                                      \
442                 rbp_i_cmp = (a_cmp)((a_node), rbp_i_p);                 \
443                 if (rbp_i_cmp < 0) {                                    \
444                     rbp_i_c = rbp_left_get(a_type, a_field, rbp_i_p);   \
445                 } else {                                                \
446                     assert(rbp_i_cmp > 0);                              \
447                     rbp_i_c = rbp_right_get(a_type, a_field, rbp_i_p);  \
448                 }                                                       \
449                 continue;                                               \
450             }                                                           \
451         }                                                               \
452         rbp_i_g = rbp_i_p;                                              \
453         rbp_i_p = rbp_i_c;                                              \
454         rbp_i_cmp = (a_cmp)((a_node), rbp_i_c);                         \
455         if (rbp_i_cmp < 0) {                                            \
456             rbp_i_c = rbp_left_get(a_type, a_field, rbp_i_c);           \
457         } else {                                                        \
458             assert(rbp_i_cmp > 0);                                      \
459             rbp_i_c = rbp_right_get(a_type, a_field, rbp_i_c);          \
460         }                                                               \
461     }                                                                   \
462     /* rbp_i_p now refers to the node under which to insert.          */\
463     rbp_node_new(a_type, a_field, a_tree, (a_node));                    \
464     if (rbp_i_cmp > 0) {                                                \
465         rbp_right_set(a_type, a_field, rbp_i_p, (a_node));              \
466         rbp_lean_left(a_type, a_field, rbp_i_p, rbp_i_t);               \
467         if (rbp_left_get(a_type, a_field, rbp_i_g) == rbp_i_p) {        \
468             rbp_left_set(a_type, a_field, rbp_i_g, rbp_i_t);            \
469         } else if (rbp_right_get(a_type, a_field, rbp_i_g) == rbp_i_p) {\
470             rbp_right_set(a_type, a_field, rbp_i_g, rbp_i_t);           \
471         }                                                               \
472     } else {                                                            \
473         rbp_left_set(a_type, a_field, rbp_i_p, (a_node));               \
474     }                                                                   \
475     /* Update the root and make sure that it is black.                */\
476     (a_tree)->rbt_root = rbp_left_get(a_type, a_field, &rbp_i_s);       \
477     rbp_black_set(a_type, a_field, (a_tree)->rbt_root);                 \
478 } while (0)
479
480 #define rb_remove(a_type, a_field, a_cmp, a_tree, a_node) do {          \
481     a_type rbp_r_s;                                                     \
482     a_type *rbp_r_p, *rbp_r_c, *rbp_r_xp, *rbp_r_t, *rbp_r_u;           \
483     int rbp_r_cmp;                                                      \
484     rbp_left_set(a_type, a_field, &rbp_r_s, (a_tree)->rbt_root);        \
485     rbp_right_set(a_type, a_field, &rbp_r_s, &(a_tree)->rbt_nil);       \
486     rbp_black_set(a_type, a_field, &rbp_r_s);                           \
487     rbp_r_p = &rbp_r_s;                                                 \
488     rbp_r_c = (a_tree)->rbt_root;                                       \
489     rbp_r_xp = &(a_tree)->rbt_nil;                                      \
490     /* Iterate down the tree, but always transform 2-nodes to 3- or   */\
491     /* 4-nodes in order to maintain the invariant that the current    */\
492     /* node is not a 2-node.  This allows simple deletion once a leaf */\
493     /* is reached.  Handle the root specially though, since there may */\
494     /* be no way to convert it from a 2-node to a 3-node.             */\
495     rbp_r_cmp = (a_cmp)((a_node), rbp_r_c);                             \
496     if (rbp_r_cmp < 0) {                                                \
497         rbp_r_t = rbp_left_get(a_type, a_field, rbp_r_c);               \
498         rbp_r_u = rbp_left_get(a_type, a_field, rbp_r_t);               \
499         if (rbp_red_get(a_type, a_field, rbp_r_t) == false              \
500           && rbp_red_get(a_type, a_field, rbp_r_u) == false) {          \
501             /* Apply standard transform to prepare for left move.     */\
502             rbp_move_red_left(a_type, a_field, rbp_r_c, rbp_r_t);       \
503             rbp_black_set(a_type, a_field, rbp_r_t);                    \
504             rbp_left_set(a_type, a_field, rbp_r_p, rbp_r_t);            \
505             rbp_r_c = rbp_r_t;                                          \
506         } else {                                                        \
507             /* Move left.                                             */\
508             rbp_r_p = rbp_r_c;                                          \
509             rbp_r_c = rbp_left_get(a_type, a_field, rbp_r_c);           \
510         }                                                               \
511     } else {                                                            \
512         if (rbp_r_cmp == 0) {                                           \
513             assert((a_node) == rbp_r_c);                                \
514             if (rbp_right_get(a_type, a_field, rbp_r_c)                 \
515               == &(a_tree)->rbt_nil) {                                  \
516                 /* Delete root node (which is also a leaf node).      */\
517                 if (rbp_left_get(a_type, a_field, rbp_r_c)              \
518                   != &(a_tree)->rbt_nil) {                              \
519                     rbp_lean_right(a_type, a_field, rbp_r_c, rbp_r_t);  \
520                     rbp_right_set(a_type, a_field, rbp_r_t,             \
521                       &(a_tree)->rbt_nil);                              \
522                 } else {                                                \
523                     rbp_r_t = &(a_tree)->rbt_nil;                       \
524                 }                                                       \
525                 rbp_left_set(a_type, a_field, rbp_r_p, rbp_r_t);        \
526             } else {                                                    \
527                 /* This is the node we want to delete, but we will    */\
528                 /* instead swap it with its successor and delete the  */\
529                 /* successor.  Record enough information to do the    */\
530                 /* swap later.  rbp_r_xp is the a_node's parent.      */\
531                 rbp_r_xp = rbp_r_p;                                     \
532                 rbp_r_cmp = 1; /* Note that deletion is incomplete.   */\
533             }                                                           \
534         }                                                               \
535         if (rbp_r_cmp == 1) {                                           \
536             if (rbp_red_get(a_type, a_field, rbp_left_get(a_type,       \
537               a_field, rbp_right_get(a_type, a_field, rbp_r_c)))        \
538               == false) {                                               \
539                 rbp_r_t = rbp_left_get(a_type, a_field, rbp_r_c);       \
540                 if (rbp_red_get(a_type, a_field, rbp_r_t)) {            \
541                     /* Standard transform.                            */\
542                     rbp_move_red_right(a_type, a_field, rbp_r_c,        \
543                       rbp_r_t);                                         \
544                 } else {                                                \
545                     /* Root-specific transform.                       */\
546                     rbp_red_set(a_type, a_field, rbp_r_c);              \
547                     rbp_r_u = rbp_left_get(a_type, a_field, rbp_r_t);   \
548                     if (rbp_red_get(a_type, a_field, rbp_r_u)) {        \
549                         rbp_black_set(a_type, a_field, rbp_r_u);        \
550                         rbp_rotate_right(a_type, a_field, rbp_r_c,      \
551                           rbp_r_t);                                     \
552                         rbp_rotate_left(a_type, a_field, rbp_r_c,       \
553                           rbp_r_u);                                     \
554                         rbp_right_set(a_type, a_field, rbp_r_t,         \
555                           rbp_r_u);                                     \
556                     } else {                                            \
557                         rbp_red_set(a_type, a_field, rbp_r_t);          \
558                         rbp_rotate_left(a_type, a_field, rbp_r_c,       \
559                           rbp_r_t);                                     \
560                     }                                                   \
561                 }                                                       \
562                 rbp_left_set(a_type, a_field, rbp_r_p, rbp_r_t);        \
563                 rbp_r_c = rbp_r_t;                                      \
564             } else {                                                    \
565                 /* Move right.                                        */\
566                 rbp_r_p = rbp_r_c;                                      \
567                 rbp_r_c = rbp_right_get(a_type, a_field, rbp_r_c);      \
568             }                                                           \
569         }                                                               \
570     }                                                                   \
571     if (rbp_r_cmp != 0) {                                               \
572         while (true) {                                                  \
573             assert(rbp_r_p != &(a_tree)->rbt_nil);                      \
574             rbp_r_cmp = (a_cmp)((a_node), rbp_r_c);                     \
575             if (rbp_r_cmp < 0) {                                        \
576                 rbp_r_t = rbp_left_get(a_type, a_field, rbp_r_c);       \
577                 if (rbp_r_t == &(a_tree)->rbt_nil) {                    \
578                     /* rbp_r_c now refers to the successor node to    */\
579                     /* relocate, and rbp_r_xp/a_node refer to the     */\
580                     /* context for the relocation.                    */\
581                     if (rbp_left_get(a_type, a_field, rbp_r_xp)         \
582                       == (a_node)) {                                    \
583                         rbp_left_set(a_type, a_field, rbp_r_xp,         \
584                           rbp_r_c);                                     \
585                     } else {                                            \
586                         assert(rbp_right_get(a_type, a_field,           \
587                           rbp_r_xp) == (a_node));                       \
588                         rbp_right_set(a_type, a_field, rbp_r_xp,        \
589                           rbp_r_c);                                     \
590                     }                                                   \
591                     rbp_left_set(a_type, a_field, rbp_r_c,              \
592                       rbp_left_get(a_type, a_field, (a_node)));         \
593                     rbp_right_set(a_type, a_field, rbp_r_c,             \
594                       rbp_right_get(a_type, a_field, (a_node)));        \
595                     rbp_color_set(a_type, a_field, rbp_r_c,             \
596                       rbp_red_get(a_type, a_field, (a_node)));          \
597                     if (rbp_left_get(a_type, a_field, rbp_r_p)          \
598                       == rbp_r_c) {                                     \
599                         rbp_left_set(a_type, a_field, rbp_r_p,          \
600                           &(a_tree)->rbt_nil);                          \
601                     } else {                                            \
602                         assert(rbp_right_get(a_type, a_field, rbp_r_p)  \
603                           == rbp_r_c);                                  \
604                         rbp_right_set(a_type, a_field, rbp_r_p,         \
605                           &(a_tree)->rbt_nil);                          \
606                     }                                                   \
607                     break;                                              \
608                 }                                                       \
609                 rbp_r_u = rbp_left_get(a_type, a_field, rbp_r_t);       \
610                 if (rbp_red_get(a_type, a_field, rbp_r_t) == false      \
611                   && rbp_red_get(a_type, a_field, rbp_r_u) == false) {  \
612                     rbp_move_red_left(a_type, a_field, rbp_r_c,         \
613                       rbp_r_t);                                         \
614                     if (rbp_left_get(a_type, a_field, rbp_r_p)          \
615                       == rbp_r_c) {                                     \
616                         rbp_left_set(a_type, a_field, rbp_r_p, rbp_r_t);\
617                     } else {                                            \
618                         rbp_right_set(a_type, a_field, rbp_r_p,         \
619                           rbp_r_t);                                     \
620                     }                                                   \
621                     rbp_r_c = rbp_r_t;                                  \
622                 } else {                                                \
623                     rbp_r_p = rbp_r_c;                                  \
624                     rbp_r_c = rbp_left_get(a_type, a_field, rbp_r_c);   \
625                 }                                                       \
626             } else {                                                    \
627                 /* Check whether to delete this node (it has to be    */\
628                 /* the correct node and a leaf node).                 */\
629                 if (rbp_r_cmp == 0) {                                   \
630                     assert((a_node) == rbp_r_c);                        \
631                     if (rbp_right_get(a_type, a_field, rbp_r_c)         \
632                       == &(a_tree)->rbt_nil) {                          \
633                         /* Delete leaf node.                          */\
634                         if (rbp_left_get(a_type, a_field, rbp_r_c)      \
635                           != &(a_tree)->rbt_nil) {                      \
636                             rbp_lean_right(a_type, a_field, rbp_r_c,    \
637                               rbp_r_t);                                 \
638                             rbp_right_set(a_type, a_field, rbp_r_t,     \
639                               &(a_tree)->rbt_nil);                      \
640                         } else {                                        \
641                             rbp_r_t = &(a_tree)->rbt_nil;               \
642                         }                                               \
643                         if (rbp_left_get(a_type, a_field, rbp_r_p)      \
644                           == rbp_r_c) {                                 \
645                             rbp_left_set(a_type, a_field, rbp_r_p,      \
646                               rbp_r_t);                                 \
647                         } else {                                        \
648                             rbp_right_set(a_type, a_field, rbp_r_p,     \
649                               rbp_r_t);                                 \
650                         }                                               \
651                         break;                                          \
652                     } else {                                            \
653                         /* This is the node we want to delete, but we */\
654                         /* will instead swap it with its successor    */\
655                         /* and delete the successor.  Record enough   */\
656                         /* information to do the swap later.          */\
657                         /* rbp_r_xp is a_node's parent.               */\
658                         rbp_r_xp = rbp_r_p;                             \
659                     }                                                   \
660                 }                                                       \
661                 rbp_r_t = rbp_right_get(a_type, a_field, rbp_r_c);      \
662                 rbp_r_u = rbp_left_get(a_type, a_field, rbp_r_t);       \
663                 if (rbp_red_get(a_type, a_field, rbp_r_u) == false) {   \
664                     rbp_move_red_right(a_type, a_field, rbp_r_c,        \
665                       rbp_r_t);                                         \
666                     if (rbp_left_get(a_type, a_field, rbp_r_p)          \
667                       == rbp_r_c) {                                     \
668                         rbp_left_set(a_type, a_field, rbp_r_p, rbp_r_t);\
669                     } else {                                            \
670                         rbp_right_set(a_type, a_field, rbp_r_p,         \
671                           rbp_r_t);                                     \
672                     }                                                   \
673                     rbp_r_c = rbp_r_t;                                  \
674                 } else {                                                \
675                     rbp_r_p = rbp_r_c;                                  \
676                     rbp_r_c = rbp_right_get(a_type, a_field, rbp_r_c);  \
677                 }                                                       \
678             }                                                           \
679         }                                                               \
680     }                                                                   \
681     /* Update root.                                                   */\
682     (a_tree)->rbt_root = rbp_left_get(a_type, a_field, &rbp_r_s);       \
683 } while (0)
684
685 /*
686  * The rb_wrap() macro provides a convenient way to wrap functions around the
687  * cpp macros.  The main benefits of wrapping are that 1) repeated macro
688  * expansion can cause code bloat, especially for rb_{insert,remove)(), and
689  * 2) type, linkage, comparison functions, etc. need not be specified at every
690  * call point.
691  */
692
693 #define rb_wrap(a_attr, a_prefix, a_tree_type, a_type, a_field, a_cmp)  \
694 a_attr void                                                             \
695 a_prefix##new(a_tree_type *tree) {                                      \
696     rb_new(a_type, a_field, tree);                                      \
697 }                                                                       \
698 a_attr a_type *                                                         \
699 a_prefix##first(a_tree_type *tree) {                                    \
700     a_type *ret;                                                        \
701     rb_first(a_type, a_field, tree, ret);                               \
702     return (ret);                                                       \
703 }                                                                       \
704 a_attr a_type *                                                         \
705 a_prefix##last(a_tree_type *tree) {                                     \
706     a_type *ret;                                                        \
707     rb_last(a_type, a_field, tree, ret);                                \
708     return (ret);                                                       \
709 }                                                                       \
710 a_attr a_type *                                                         \
711 a_prefix##next(a_tree_type *tree, a_type *node) {                       \
712     a_type *ret;                                                        \
713     rb_next(a_type, a_field, a_cmp, tree, node, ret);                   \
714     return (ret);                                                       \
715 }                                                                       \
716 a_attr a_type *                                                         \
717 a_prefix##prev(a_tree_type *tree, a_type *node) {                       \
718     a_type *ret;                                                        \
719     rb_prev(a_type, a_field, a_cmp, tree, node, ret);                   \
720     return (ret);                                                       \
721 }                                                                       \
722 a_attr a_type *                                                         \
723 a_prefix##search(a_tree_type *tree, a_type *key) {                      \
724     a_type *ret;                                                        \
725     rb_search(a_type, a_field, a_cmp, tree, key, ret);                  \
726     return (ret);                                                       \
727 }                                                                       \
728 a_attr a_type *                                                         \
729 a_prefix##nsearch(a_tree_type *tree, a_type *key) {                     \
730     a_type *ret;                                                        \
731     rb_nsearch(a_type, a_field, a_cmp, tree, key, ret);                 \
732     return (ret);                                                       \
733 }                                                                       \
734 a_attr a_type *                                                         \
735 a_prefix##psearch(a_tree_type *tree, a_type *key) {                     \
736     a_type *ret;                                                        \
737     rb_psearch(a_type, a_field, a_cmp, tree, key, ret);                 \
738     return (ret);                                                       \
739 }                                                                       \
740 a_attr void                                                             \
741 a_prefix##insert(a_tree_type *tree, a_type *node) {                     \
742     rb_insert(a_type, a_field, a_cmp, tree, node);                      \
743 }                                                                       \
744 a_attr void                                                             \
745 a_prefix##remove(a_tree_type *tree, a_type *node) {                     \
746     rb_remove(a_type, a_field, a_cmp, tree, node);                      \
747 }
748
749 /*
750  * The iterators simulate recursion via an array of pointers that store the
751  * current path.  This is critical to performance, since a series of calls to
752  * rb_{next,prev}() would require time proportional to (n lg n), whereas this
753  * implementation only requires time proportional to (n).
754  *
755  * Since the iterators cache a path down the tree, any tree modification may
756  * cause the cached path to become invalid.  In order to continue iteration,
757  * use something like the following sequence:
758  *
759  *   {
760  *       a_type *node, *tnode;
761  *
762  *       rb_foreach_begin(a_type, a_field, a_tree, node) {
763  *           ...
764  *           rb_next(a_type, a_field, a_cmp, a_tree, node, tnode);
765  *           rb_remove(a_type, a_field, a_cmp, a_tree, node);
766  *           rb_foreach_next(a_type, a_field, a_cmp, a_tree, tnode);
767  *           ...
768  *       } rb_foreach_end(a_type, a_field, a_tree, node)
769  *   }
770  *
771  * Note that this idiom is not advised if every iteration modifies the tree,
772  * since in that case there is no algorithmic complexity improvement over a
773  * series of rb_{next,prev}() calls, thus making the setup overhead wasted
774  * effort.
775  */
776
777 #ifdef RB_NO_C99_VARARRAYS
778    /*
779     * Avoid using variable-length arrays, at the cost of using more stack space.
780     * Size the path arrays such that they are always large enough, even if a
781     * tree consumes all of memory.  Since each node must contain a minimum of
782     * two pointers, there can never be more nodes than:
783     *
784     *   1 << ((SIZEOF_PTR<<3) - (SIZEOF_PTR_2POW+1))
785     *
786     * Since the depth of a tree is limited to 3*lg(#nodes), the maximum depth
787     * is:
788     *
789     *   (3 * ((SIZEOF_PTR<<3) - (SIZEOF_PTR_2POW+1)))
790     *
791     * This works out to a maximum depth of 87 and 180 for 32- and 64-bit
792     * systems, respectively (approximatly 348 and 1440 bytes, respectively).
793     */
794 #  define rbp_compute_f_height(a_type, a_field, a_tree)
795 #  define rbp_f_height  (3 * ((SIZEOF_PTR<<3) - (SIZEOF_PTR_2POW+1)))
796 #  define rbp_compute_fr_height(a_type, a_field, a_tree)
797 #  define rbp_fr_height (3 * ((SIZEOF_PTR<<3) - (SIZEOF_PTR_2POW+1)))
798 #else
799 #  define rbp_compute_f_height(a_type, a_field, a_tree)                 \
800     /* Compute the maximum possible tree depth (3X the black height). */\
801     unsigned rbp_f_height;                                              \
802     rbp_black_height(a_type, a_field, a_tree, rbp_f_height);            \
803     rbp_f_height *= 3;
804 #  define rbp_compute_fr_height(a_type, a_field, a_tree)                \
805     /* Compute the maximum possible tree depth (3X the black height). */\
806     unsigned rbp_fr_height;                                             \
807     rbp_black_height(a_type, a_field, a_tree, rbp_fr_height);           \
808     rbp_fr_height *= 3;
809 #endif
810
811 #define rb_foreach_begin(a_type, a_field, a_tree, a_var) {              \
812     rbp_compute_f_height(a_type, a_field, a_tree)                       \
813     {                                                                   \
814         /* Initialize the path to contain the left spine.             */\
815         a_type *rbp_f_path[rbp_f_height];                               \
816         a_type *rbp_f_node;                                             \
817         bool rbp_f_synced = false;                                      \
818         unsigned rbp_f_depth = 0;                                       \
819         if ((a_tree)->rbt_root != &(a_tree)->rbt_nil) {                 \
820             rbp_f_path[rbp_f_depth] = (a_tree)->rbt_root;               \
821             rbp_f_depth++;                                              \
822             while ((rbp_f_node = rbp_left_get(a_type, a_field,          \
823               rbp_f_path[rbp_f_depth-1])) != &(a_tree)->rbt_nil) {      \
824                 rbp_f_path[rbp_f_depth] = rbp_f_node;                   \
825                 rbp_f_depth++;                                          \
826             }                                                           \
827         }                                                               \
828         /* While the path is non-empty, iterate.                      */\
829         while (rbp_f_depth > 0) {                                       \
830             (a_var) = rbp_f_path[rbp_f_depth-1];
831
832 /* Only use if modifying the tree during iteration. */
833 #define rb_foreach_next(a_type, a_field, a_cmp, a_tree, a_node)         \
834             /* Re-initialize the path to contain the path to a_node.  */\
835             rbp_f_depth = 0;                                            \
836             if (a_node != NULL) {                                       \
837                 if ((a_tree)->rbt_root != &(a_tree)->rbt_nil) {         \
838                     rbp_f_path[rbp_f_depth] = (a_tree)->rbt_root;       \
839                     rbp_f_depth++;                                      \
840                     rbp_f_node = rbp_f_path[0];                         \
841                     while (true) {                                      \
842                         int rbp_f_cmp = (a_cmp)((a_node),               \
843                           rbp_f_path[rbp_f_depth-1]);                   \
844                         if (rbp_f_cmp < 0) {                            \
845                             rbp_f_node = rbp_left_get(a_type, a_field,  \
846                               rbp_f_path[rbp_f_depth-1]);               \
847                         } else if (rbp_f_cmp > 0) {                     \
848                             rbp_f_node = rbp_right_get(a_type, a_field, \
849                               rbp_f_path[rbp_f_depth-1]);               \
850                         } else {                                        \
851                             break;                                      \
852                         }                                               \
853                         assert(rbp_f_node != &(a_tree)->rbt_nil);       \
854                         rbp_f_path[rbp_f_depth] = rbp_f_node;           \
855                         rbp_f_depth++;                                  \
856                     }                                                   \
857                 }                                                       \
858             }                                                           \
859             rbp_f_synced = true;
860
861 #define rb_foreach_end(a_type, a_field, a_tree, a_var)                  \
862             if (rbp_f_synced) {                                         \
863                 rbp_f_synced = false;                                   \
864                 continue;                                               \
865             }                                                           \
866             /* Find the successor.                                    */\
867             if ((rbp_f_node = rbp_right_get(a_type, a_field,            \
868               rbp_f_path[rbp_f_depth-1])) != &(a_tree)->rbt_nil) {      \
869                 /* The successor is the left-most node in the right   */\
870                 /* subtree.                                           */\
871                 rbp_f_path[rbp_f_depth] = rbp_f_node;                   \
872                 rbp_f_depth++;                                          \
873                 while ((rbp_f_node = rbp_left_get(a_type, a_field,      \
874                   rbp_f_path[rbp_f_depth-1])) != &(a_tree)->rbt_nil) {  \
875                     rbp_f_path[rbp_f_depth] = rbp_f_node;               \
876                     rbp_f_depth++;                                      \
877                 }                                                       \
878             } else {                                                    \
879                 /* The successor is above the current node.  Unwind   */\
880                 /* until a left-leaning edge is removed from the      */\
881                 /* path, or the path is empty.                        */\
882                 for (rbp_f_depth--; rbp_f_depth > 0; rbp_f_depth--) {   \
883                     if (rbp_left_get(a_type, a_field,                   \
884                       rbp_f_path[rbp_f_depth-1])                        \
885                       == rbp_f_path[rbp_f_depth]) {                     \
886                         break;                                          \
887                     }                                                   \
888                 }                                                       \
889             }                                                           \
890         }                                                               \
891     }                                                                   \
892 }
893
894 #define rb_foreach_reverse_begin(a_type, a_field, a_tree, a_var) {      \
895     rbp_compute_fr_height(a_type, a_field, a_tree)                      \
896     {                                                                   \
897         /* Initialize the path to contain the right spine.            */\
898         a_type *rbp_fr_path[rbp_fr_height];                             \
899         a_type *rbp_fr_node;                                            \
900         bool rbp_fr_synced = false;                                     \
901         unsigned rbp_fr_depth = 0;                                      \
902         if ((a_tree)->rbt_root != &(a_tree)->rbt_nil) {                 \
903             rbp_fr_path[rbp_fr_depth] = (a_tree)->rbt_root;             \
904             rbp_fr_depth++;                                             \
905             while ((rbp_fr_node = rbp_right_get(a_type, a_field,        \
906               rbp_fr_path[rbp_fr_depth-1])) != &(a_tree)->rbt_nil) {    \
907                 rbp_fr_path[rbp_fr_depth] = rbp_fr_node;                \
908                 rbp_fr_depth++;                                         \
909             }                                                           \
910         }                                                               \
911         /* While the path is non-empty, iterate.                      */\
912         while (rbp_fr_depth > 0) {                                      \
913             (a_var) = rbp_fr_path[rbp_fr_depth-1];
914
915 /* Only use if modifying the tree during iteration. */
916 #define rb_foreach_reverse_prev(a_type, a_field, a_cmp, a_tree, a_node) \
917             /* Re-initialize the path to contain the path to a_node.  */\
918             rbp_fr_depth = 0;                                           \
919             if (a_node != NULL) {                                       \
920                 if ((a_tree)->rbt_root != &(a_tree)->rbt_nil) {         \
921                     rbp_fr_path[rbp_fr_depth] = (a_tree)->rbt_root;     \
922                     rbp_fr_depth++;                                     \
923                     rbp_fr_node = rbp_fr_path[0];                       \
924                     while (true) {                                      \
925                         int rbp_fr_cmp = (a_cmp)((a_node),              \
926                           rbp_fr_path[rbp_fr_depth-1]);                 \
927                         if (rbp_fr_cmp < 0) {                           \
928                             rbp_fr_node = rbp_left_get(a_type, a_field, \
929                               rbp_fr_path[rbp_fr_depth-1]);             \
930                         } else if (rbp_fr_cmp > 0) {                    \
931                             rbp_fr_node = rbp_right_get(a_type, a_field,\
932                               rbp_fr_path[rbp_fr_depth-1]);             \
933                         } else {                                        \
934                             break;                                      \
935                         }                                               \
936                         assert(rbp_fr_node != &(a_tree)->rbt_nil);      \
937                         rbp_fr_path[rbp_fr_depth] = rbp_fr_node;        \
938                         rbp_fr_depth++;                                 \
939                     }                                                   \
940                 }                                                       \
941             }                                                           \
942             rbp_fr_synced = true;
943
944 #define rb_foreach_reverse_end(a_type, a_field, a_tree, a_var)          \
945             if (rbp_fr_synced) {                                        \
946                 rbp_fr_synced = false;                                  \
947                 continue;                                               \
948             }                                                           \
949             if (rbp_fr_depth == 0) {                                    \
950                 /* rb_foreach_reverse_sync() was called with a NULL   */\
951                 /* a_node.                                            */\
952                 break;                                                  \
953             }                                                           \
954             /* Find the predecessor.                                  */\
955             if ((rbp_fr_node = rbp_left_get(a_type, a_field,            \
956               rbp_fr_path[rbp_fr_depth-1])) != &(a_tree)->rbt_nil) {    \
957                 /* The predecessor is the right-most node in the left */\
958                 /* subtree.                                           */\
959                 rbp_fr_path[rbp_fr_depth] = rbp_fr_node;                \
960                 rbp_fr_depth++;                                         \
961                 while ((rbp_fr_node = rbp_right_get(a_type, a_field,    \
962                   rbp_fr_path[rbp_fr_depth-1])) != &(a_tree)->rbt_nil) {\
963                     rbp_fr_path[rbp_fr_depth] = rbp_fr_node;            \
964                     rbp_fr_depth++;                                     \
965                 }                                                       \
966             } else {                                                    \
967                 /* The predecessor is above the current node.  Unwind */\
968                 /* until a right-leaning edge is removed from the     */\
969                 /* path, or the path is empty.                        */\
970                 for (rbp_fr_depth--; rbp_fr_depth > 0; rbp_fr_depth--) {\
971                     if (rbp_right_get(a_type, a_field,                  \
972                       rbp_fr_path[rbp_fr_depth-1])                      \
973                       == rbp_fr_path[rbp_fr_depth]) {                   \
974                         break;                                          \
975                     }                                                   \
976                 }                                                       \
977             }                                                           \
978         }                                                               \
979     }                                                                   \
980 }
981
982 #endif /* RB_H_ */