Home | History | Annotate | Download | only in vendor
      1 /******************************************************************************
      2  *
      3  * Copyright (C) 2008 Jason Evans <jasone (at) 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_ */
    983