xref: /aosp_15_r20/external/jemalloc_new/include/jemalloc/internal/rb.h (revision 1208bc7e437ced7eb82efac44ba17e3beba411da)
1*1208bc7eSAndroid Build Coastguard Worker /*-
2*1208bc7eSAndroid Build Coastguard Worker  *******************************************************************************
3*1208bc7eSAndroid Build Coastguard Worker  *
4*1208bc7eSAndroid Build Coastguard Worker  * cpp macro implementation of left-leaning 2-3 red-black trees.  Parent
5*1208bc7eSAndroid Build Coastguard Worker  * pointers are not used, and color bits are stored in the least significant
6*1208bc7eSAndroid Build Coastguard Worker  * bit of right-child pointers (if RB_COMPACT is defined), thus making node
7*1208bc7eSAndroid Build Coastguard Worker  * linkage as compact as is possible for red-black trees.
8*1208bc7eSAndroid Build Coastguard Worker  *
9*1208bc7eSAndroid Build Coastguard Worker  * Usage:
10*1208bc7eSAndroid Build Coastguard Worker  *
11*1208bc7eSAndroid Build Coastguard Worker  *   #include <stdint.h>
12*1208bc7eSAndroid Build Coastguard Worker  *   #include <stdbool.h>
13*1208bc7eSAndroid Build Coastguard Worker  *   #define NDEBUG // (Optional, see assert(3).)
14*1208bc7eSAndroid Build Coastguard Worker  *   #include <assert.h>
15*1208bc7eSAndroid Build Coastguard Worker  *   #define RB_COMPACT // (Optional, embed color bits in right-child pointers.)
16*1208bc7eSAndroid Build Coastguard Worker  *   #include <rb.h>
17*1208bc7eSAndroid Build Coastguard Worker  *   ...
18*1208bc7eSAndroid Build Coastguard Worker  *
19*1208bc7eSAndroid Build Coastguard Worker  *******************************************************************************
20*1208bc7eSAndroid Build Coastguard Worker  */
21*1208bc7eSAndroid Build Coastguard Worker 
22*1208bc7eSAndroid Build Coastguard Worker #ifndef RB_H_
23*1208bc7eSAndroid Build Coastguard Worker #define RB_H_
24*1208bc7eSAndroid Build Coastguard Worker 
25*1208bc7eSAndroid Build Coastguard Worker #ifndef __PGI
26*1208bc7eSAndroid Build Coastguard Worker #define RB_COMPACT
27*1208bc7eSAndroid Build Coastguard Worker #endif
28*1208bc7eSAndroid Build Coastguard Worker 
29*1208bc7eSAndroid Build Coastguard Worker #ifdef RB_COMPACT
30*1208bc7eSAndroid Build Coastguard Worker /* Node structure. */
31*1208bc7eSAndroid Build Coastguard Worker #define rb_node(a_type)							\
32*1208bc7eSAndroid Build Coastguard Worker struct {								\
33*1208bc7eSAndroid Build Coastguard Worker     a_type *rbn_left;							\
34*1208bc7eSAndroid Build Coastguard Worker     a_type *rbn_right_red;						\
35*1208bc7eSAndroid Build Coastguard Worker }
36*1208bc7eSAndroid Build Coastguard Worker #else
37*1208bc7eSAndroid Build Coastguard Worker #define rb_node(a_type)							\
38*1208bc7eSAndroid Build Coastguard Worker struct {								\
39*1208bc7eSAndroid Build Coastguard Worker     a_type *rbn_left;							\
40*1208bc7eSAndroid Build Coastguard Worker     a_type *rbn_right;							\
41*1208bc7eSAndroid Build Coastguard Worker     bool rbn_red;							\
42*1208bc7eSAndroid Build Coastguard Worker }
43*1208bc7eSAndroid Build Coastguard Worker #endif
44*1208bc7eSAndroid Build Coastguard Worker 
45*1208bc7eSAndroid Build Coastguard Worker /* Root structure. */
46*1208bc7eSAndroid Build Coastguard Worker #define rb_tree(a_type)							\
47*1208bc7eSAndroid Build Coastguard Worker struct {								\
48*1208bc7eSAndroid Build Coastguard Worker     a_type *rbt_root;							\
49*1208bc7eSAndroid Build Coastguard Worker }
50*1208bc7eSAndroid Build Coastguard Worker 
51*1208bc7eSAndroid Build Coastguard Worker /* Left accessors. */
52*1208bc7eSAndroid Build Coastguard Worker #define rbtn_left_get(a_type, a_field, a_node)				\
53*1208bc7eSAndroid Build Coastguard Worker     ((a_node)->a_field.rbn_left)
54*1208bc7eSAndroid Build Coastguard Worker #define rbtn_left_set(a_type, a_field, a_node, a_left) do {		\
55*1208bc7eSAndroid Build Coastguard Worker     (a_node)->a_field.rbn_left = a_left;				\
56*1208bc7eSAndroid Build Coastguard Worker } while (0)
57*1208bc7eSAndroid Build Coastguard Worker 
58*1208bc7eSAndroid Build Coastguard Worker #ifdef RB_COMPACT
59*1208bc7eSAndroid Build Coastguard Worker /* Right accessors. */
60*1208bc7eSAndroid Build Coastguard Worker #define rbtn_right_get(a_type, a_field, a_node)				\
61*1208bc7eSAndroid Build Coastguard Worker     ((a_type *) (((intptr_t) (a_node)->a_field.rbn_right_red)		\
62*1208bc7eSAndroid Build Coastguard Worker       & ((ssize_t)-2)))
63*1208bc7eSAndroid Build Coastguard Worker #define rbtn_right_set(a_type, a_field, a_node, a_right) do {		\
64*1208bc7eSAndroid Build Coastguard Worker     (a_node)->a_field.rbn_right_red = (a_type *) (((uintptr_t) a_right)	\
65*1208bc7eSAndroid Build Coastguard Worker       | (((uintptr_t) (a_node)->a_field.rbn_right_red) & ((size_t)1)));	\
66*1208bc7eSAndroid Build Coastguard Worker } while (0)
67*1208bc7eSAndroid Build Coastguard Worker 
68*1208bc7eSAndroid Build Coastguard Worker /* Color accessors. */
69*1208bc7eSAndroid Build Coastguard Worker #define rbtn_red_get(a_type, a_field, a_node)				\
70*1208bc7eSAndroid Build Coastguard Worker     ((bool) (((uintptr_t) (a_node)->a_field.rbn_right_red)		\
71*1208bc7eSAndroid Build Coastguard Worker       & ((size_t)1)))
72*1208bc7eSAndroid Build Coastguard Worker #define rbtn_color_set(a_type, a_field, a_node, a_red) do {		\
73*1208bc7eSAndroid Build Coastguard Worker     (a_node)->a_field.rbn_right_red = (a_type *) ((((intptr_t)		\
74*1208bc7eSAndroid Build Coastguard Worker       (a_node)->a_field.rbn_right_red) & ((ssize_t)-2))			\
75*1208bc7eSAndroid Build Coastguard Worker       | ((ssize_t)a_red));						\
76*1208bc7eSAndroid Build Coastguard Worker } while (0)
77*1208bc7eSAndroid Build Coastguard Worker #define rbtn_red_set(a_type, a_field, a_node) do {			\
78*1208bc7eSAndroid Build Coastguard Worker     (a_node)->a_field.rbn_right_red = (a_type *) (((uintptr_t)		\
79*1208bc7eSAndroid Build Coastguard Worker       (a_node)->a_field.rbn_right_red) | ((size_t)1));			\
80*1208bc7eSAndroid Build Coastguard Worker } while (0)
81*1208bc7eSAndroid Build Coastguard Worker #define rbtn_black_set(a_type, a_field, a_node) do {			\
82*1208bc7eSAndroid Build Coastguard Worker     (a_node)->a_field.rbn_right_red = (a_type *) (((intptr_t)		\
83*1208bc7eSAndroid Build Coastguard Worker       (a_node)->a_field.rbn_right_red) & ((ssize_t)-2));		\
84*1208bc7eSAndroid Build Coastguard Worker } while (0)
85*1208bc7eSAndroid Build Coastguard Worker 
86*1208bc7eSAndroid Build Coastguard Worker /* Node initializer. */
87*1208bc7eSAndroid Build Coastguard Worker #define rbt_node_new(a_type, a_field, a_rbt, a_node) do {		\
88*1208bc7eSAndroid Build Coastguard Worker     /* Bookkeeping bit cannot be used by node pointer. */		\
89*1208bc7eSAndroid Build Coastguard Worker     assert(((uintptr_t)(a_node) & 0x1) == 0);				\
90*1208bc7eSAndroid Build Coastguard Worker     rbtn_left_set(a_type, a_field, (a_node), NULL);	\
91*1208bc7eSAndroid Build Coastguard Worker     rbtn_right_set(a_type, a_field, (a_node), NULL);	\
92*1208bc7eSAndroid Build Coastguard Worker     rbtn_red_set(a_type, a_field, (a_node));				\
93*1208bc7eSAndroid Build Coastguard Worker } while (0)
94*1208bc7eSAndroid Build Coastguard Worker #else
95*1208bc7eSAndroid Build Coastguard Worker /* Right accessors. */
96*1208bc7eSAndroid Build Coastguard Worker #define rbtn_right_get(a_type, a_field, a_node)				\
97*1208bc7eSAndroid Build Coastguard Worker     ((a_node)->a_field.rbn_right)
98*1208bc7eSAndroid Build Coastguard Worker #define rbtn_right_set(a_type, a_field, a_node, a_right) do {		\
99*1208bc7eSAndroid Build Coastguard Worker     (a_node)->a_field.rbn_right = a_right;				\
100*1208bc7eSAndroid Build Coastguard Worker } while (0)
101*1208bc7eSAndroid Build Coastguard Worker 
102*1208bc7eSAndroid Build Coastguard Worker /* Color accessors. */
103*1208bc7eSAndroid Build Coastguard Worker #define rbtn_red_get(a_type, a_field, a_node)				\
104*1208bc7eSAndroid Build Coastguard Worker     ((a_node)->a_field.rbn_red)
105*1208bc7eSAndroid Build Coastguard Worker #define rbtn_color_set(a_type, a_field, a_node, a_red) do {		\
106*1208bc7eSAndroid Build Coastguard Worker     (a_node)->a_field.rbn_red = (a_red);				\
107*1208bc7eSAndroid Build Coastguard Worker } while (0)
108*1208bc7eSAndroid Build Coastguard Worker #define rbtn_red_set(a_type, a_field, a_node) do {			\
109*1208bc7eSAndroid Build Coastguard Worker     (a_node)->a_field.rbn_red = true;					\
110*1208bc7eSAndroid Build Coastguard Worker } while (0)
111*1208bc7eSAndroid Build Coastguard Worker #define rbtn_black_set(a_type, a_field, a_node) do {			\
112*1208bc7eSAndroid Build Coastguard Worker     (a_node)->a_field.rbn_red = false;					\
113*1208bc7eSAndroid Build Coastguard Worker } while (0)
114*1208bc7eSAndroid Build Coastguard Worker 
115*1208bc7eSAndroid Build Coastguard Worker /* Node initializer. */
116*1208bc7eSAndroid Build Coastguard Worker #define rbt_node_new(a_type, a_field, a_rbt, a_node) do {		\
117*1208bc7eSAndroid Build Coastguard Worker     rbtn_left_set(a_type, a_field, (a_node), NULL);	\
118*1208bc7eSAndroid Build Coastguard Worker     rbtn_right_set(a_type, a_field, (a_node), NULL);	\
119*1208bc7eSAndroid Build Coastguard Worker     rbtn_red_set(a_type, a_field, (a_node));				\
120*1208bc7eSAndroid Build Coastguard Worker } while (0)
121*1208bc7eSAndroid Build Coastguard Worker #endif
122*1208bc7eSAndroid Build Coastguard Worker 
123*1208bc7eSAndroid Build Coastguard Worker /* Tree initializer. */
124*1208bc7eSAndroid Build Coastguard Worker #define rb_new(a_type, a_field, a_rbt) do {				\
125*1208bc7eSAndroid Build Coastguard Worker     (a_rbt)->rbt_root = NULL;						\
126*1208bc7eSAndroid Build Coastguard Worker } while (0)
127*1208bc7eSAndroid Build Coastguard Worker 
128*1208bc7eSAndroid Build Coastguard Worker /* Internal utility macros. */
129*1208bc7eSAndroid Build Coastguard Worker #define rbtn_first(a_type, a_field, a_rbt, a_root, r_node) do {		\
130*1208bc7eSAndroid Build Coastguard Worker     (r_node) = (a_root);						\
131*1208bc7eSAndroid Build Coastguard Worker     if ((r_node) != NULL) {						\
132*1208bc7eSAndroid Build Coastguard Worker 	for (;								\
133*1208bc7eSAndroid Build Coastguard Worker 	  rbtn_left_get(a_type, a_field, (r_node)) != NULL;		\
134*1208bc7eSAndroid Build Coastguard Worker 	  (r_node) = rbtn_left_get(a_type, a_field, (r_node))) {	\
135*1208bc7eSAndroid Build Coastguard Worker 	}								\
136*1208bc7eSAndroid Build Coastguard Worker     }									\
137*1208bc7eSAndroid Build Coastguard Worker } while (0)
138*1208bc7eSAndroid Build Coastguard Worker 
139*1208bc7eSAndroid Build Coastguard Worker #define rbtn_last(a_type, a_field, a_rbt, a_root, r_node) do {		\
140*1208bc7eSAndroid Build Coastguard Worker     (r_node) = (a_root);						\
141*1208bc7eSAndroid Build Coastguard Worker     if ((r_node) != NULL) {						\
142*1208bc7eSAndroid Build Coastguard Worker 	for (; rbtn_right_get(a_type, a_field, (r_node)) != NULL;	\
143*1208bc7eSAndroid Build Coastguard Worker 	  (r_node) = rbtn_right_get(a_type, a_field, (r_node))) {	\
144*1208bc7eSAndroid Build Coastguard Worker 	}								\
145*1208bc7eSAndroid Build Coastguard Worker     }									\
146*1208bc7eSAndroid Build Coastguard Worker } while (0)
147*1208bc7eSAndroid Build Coastguard Worker 
148*1208bc7eSAndroid Build Coastguard Worker #define rbtn_rotate_left(a_type, a_field, a_node, r_node) do {		\
149*1208bc7eSAndroid Build Coastguard Worker     (r_node) = rbtn_right_get(a_type, a_field, (a_node));		\
150*1208bc7eSAndroid Build Coastguard Worker     rbtn_right_set(a_type, a_field, (a_node),				\
151*1208bc7eSAndroid Build Coastguard Worker       rbtn_left_get(a_type, a_field, (r_node)));			\
152*1208bc7eSAndroid Build Coastguard Worker     rbtn_left_set(a_type, a_field, (r_node), (a_node));			\
153*1208bc7eSAndroid Build Coastguard Worker } while (0)
154*1208bc7eSAndroid Build Coastguard Worker 
155*1208bc7eSAndroid Build Coastguard Worker #define rbtn_rotate_right(a_type, a_field, a_node, r_node) do {		\
156*1208bc7eSAndroid Build Coastguard Worker     (r_node) = rbtn_left_get(a_type, a_field, (a_node));		\
157*1208bc7eSAndroid Build Coastguard Worker     rbtn_left_set(a_type, a_field, (a_node),				\
158*1208bc7eSAndroid Build Coastguard Worker       rbtn_right_get(a_type, a_field, (r_node)));			\
159*1208bc7eSAndroid Build Coastguard Worker     rbtn_right_set(a_type, a_field, (r_node), (a_node));		\
160*1208bc7eSAndroid Build Coastguard Worker } while (0)
161*1208bc7eSAndroid Build Coastguard Worker 
162*1208bc7eSAndroid Build Coastguard Worker /*
163*1208bc7eSAndroid Build Coastguard Worker  * The rb_proto() macro generates function prototypes that correspond to the
164*1208bc7eSAndroid Build Coastguard Worker  * functions generated by an equivalently parameterized call to rb_gen().
165*1208bc7eSAndroid Build Coastguard Worker  */
166*1208bc7eSAndroid Build Coastguard Worker 
167*1208bc7eSAndroid Build Coastguard Worker #define rb_proto(a_attr, a_prefix, a_rbt_type, a_type)			\
168*1208bc7eSAndroid Build Coastguard Worker a_attr void								\
169*1208bc7eSAndroid Build Coastguard Worker a_prefix##new(a_rbt_type *rbtree);					\
170*1208bc7eSAndroid Build Coastguard Worker a_attr bool								\
171*1208bc7eSAndroid Build Coastguard Worker a_prefix##empty(a_rbt_type *rbtree);					\
172*1208bc7eSAndroid Build Coastguard Worker a_attr a_type *								\
173*1208bc7eSAndroid Build Coastguard Worker a_prefix##first(a_rbt_type *rbtree);					\
174*1208bc7eSAndroid Build Coastguard Worker a_attr a_type *								\
175*1208bc7eSAndroid Build Coastguard Worker a_prefix##last(a_rbt_type *rbtree);					\
176*1208bc7eSAndroid Build Coastguard Worker a_attr a_type *								\
177*1208bc7eSAndroid Build Coastguard Worker a_prefix##next(a_rbt_type *rbtree, a_type *node);			\
178*1208bc7eSAndroid Build Coastguard Worker a_attr a_type *								\
179*1208bc7eSAndroid Build Coastguard Worker a_prefix##prev(a_rbt_type *rbtree, a_type *node);			\
180*1208bc7eSAndroid Build Coastguard Worker a_attr a_type *								\
181*1208bc7eSAndroid Build Coastguard Worker a_prefix##search(a_rbt_type *rbtree, const a_type *key);		\
182*1208bc7eSAndroid Build Coastguard Worker a_attr a_type *								\
183*1208bc7eSAndroid Build Coastguard Worker a_prefix##nsearch(a_rbt_type *rbtree, const a_type *key);		\
184*1208bc7eSAndroid Build Coastguard Worker a_attr a_type *								\
185*1208bc7eSAndroid Build Coastguard Worker a_prefix##psearch(a_rbt_type *rbtree, const a_type *key);		\
186*1208bc7eSAndroid Build Coastguard Worker a_attr void								\
187*1208bc7eSAndroid Build Coastguard Worker a_prefix##insert(a_rbt_type *rbtree, a_type *node);			\
188*1208bc7eSAndroid Build Coastguard Worker a_attr void								\
189*1208bc7eSAndroid Build Coastguard Worker a_prefix##remove(a_rbt_type *rbtree, a_type *node);			\
190*1208bc7eSAndroid Build Coastguard Worker a_attr a_type *								\
191*1208bc7eSAndroid Build Coastguard Worker a_prefix##iter(a_rbt_type *rbtree, a_type *start, a_type *(*cb)(	\
192*1208bc7eSAndroid Build Coastguard Worker   a_rbt_type *, a_type *, void *), void *arg);				\
193*1208bc7eSAndroid Build Coastguard Worker a_attr a_type *								\
194*1208bc7eSAndroid Build Coastguard Worker a_prefix##reverse_iter(a_rbt_type *rbtree, a_type *start,		\
195*1208bc7eSAndroid Build Coastguard Worker   a_type *(*cb)(a_rbt_type *, a_type *, void *), void *arg);		\
196*1208bc7eSAndroid Build Coastguard Worker a_attr void								\
197*1208bc7eSAndroid Build Coastguard Worker a_prefix##destroy(a_rbt_type *rbtree, void (*cb)(a_type *, void *),	\
198*1208bc7eSAndroid Build Coastguard Worker   void *arg);
199*1208bc7eSAndroid Build Coastguard Worker 
200*1208bc7eSAndroid Build Coastguard Worker /*
201*1208bc7eSAndroid Build Coastguard Worker  * The rb_gen() macro generates a type-specific red-black tree implementation,
202*1208bc7eSAndroid Build Coastguard Worker  * based on the above cpp macros.
203*1208bc7eSAndroid Build Coastguard Worker  *
204*1208bc7eSAndroid Build Coastguard Worker  * Arguments:
205*1208bc7eSAndroid Build Coastguard Worker  *
206*1208bc7eSAndroid Build Coastguard Worker  *   a_attr    : Function attribute for generated functions (ex: static).
207*1208bc7eSAndroid Build Coastguard Worker  *   a_prefix  : Prefix for generated functions (ex: ex_).
208*1208bc7eSAndroid Build Coastguard Worker  *   a_rb_type : Type for red-black tree data structure (ex: ex_t).
209*1208bc7eSAndroid Build Coastguard Worker  *   a_type    : Type for red-black tree node data structure (ex: ex_node_t).
210*1208bc7eSAndroid Build Coastguard Worker  *   a_field   : Name of red-black tree node linkage (ex: ex_link).
211*1208bc7eSAndroid Build Coastguard Worker  *   a_cmp     : Node comparison function name, with the following prototype:
212*1208bc7eSAndroid Build Coastguard Worker  *                 int (a_cmp *)(a_type *a_node, a_type *a_other);
213*1208bc7eSAndroid Build Coastguard Worker  *                                       ^^^^^^
214*1208bc7eSAndroid Build Coastguard Worker  *                                    or a_key
215*1208bc7eSAndroid Build Coastguard Worker  *               Interpretation of comparison function return values:
216*1208bc7eSAndroid Build Coastguard Worker  *                 -1 : a_node <  a_other
217*1208bc7eSAndroid Build Coastguard Worker  *                  0 : a_node == a_other
218*1208bc7eSAndroid Build Coastguard Worker  *                  1 : a_node >  a_other
219*1208bc7eSAndroid Build Coastguard Worker  *               In all cases, the a_node or a_key macro argument is the first
220*1208bc7eSAndroid Build Coastguard Worker  *               argument to the comparison function, which makes it possible
221*1208bc7eSAndroid Build Coastguard Worker  *               to write comparison functions that treat the first argument
222*1208bc7eSAndroid Build Coastguard Worker  *               specially.
223*1208bc7eSAndroid Build Coastguard Worker  *
224*1208bc7eSAndroid Build Coastguard Worker  * Assuming the following setup:
225*1208bc7eSAndroid Build Coastguard Worker  *
226*1208bc7eSAndroid Build Coastguard Worker  *   typedef struct ex_node_s ex_node_t;
227*1208bc7eSAndroid Build Coastguard Worker  *   struct ex_node_s {
228*1208bc7eSAndroid Build Coastguard Worker  *       rb_node(ex_node_t) ex_link;
229*1208bc7eSAndroid Build Coastguard Worker  *   };
230*1208bc7eSAndroid Build Coastguard Worker  *   typedef rb_tree(ex_node_t) ex_t;
231*1208bc7eSAndroid Build Coastguard Worker  *   rb_gen(static, ex_, ex_t, ex_node_t, ex_link, ex_cmp)
232*1208bc7eSAndroid Build Coastguard Worker  *
233*1208bc7eSAndroid Build Coastguard Worker  * The following API is generated:
234*1208bc7eSAndroid Build Coastguard Worker  *
235*1208bc7eSAndroid Build Coastguard Worker  *   static void
236*1208bc7eSAndroid Build Coastguard Worker  *   ex_new(ex_t *tree);
237*1208bc7eSAndroid Build Coastguard Worker  *       Description: Initialize a red-black tree structure.
238*1208bc7eSAndroid Build Coastguard Worker  *       Args:
239*1208bc7eSAndroid Build Coastguard Worker  *         tree: Pointer to an uninitialized red-black tree object.
240*1208bc7eSAndroid Build Coastguard Worker  *
241*1208bc7eSAndroid Build Coastguard Worker  *   static bool
242*1208bc7eSAndroid Build Coastguard Worker  *   ex_empty(ex_t *tree);
243*1208bc7eSAndroid Build Coastguard Worker  *       Description: Determine whether tree is empty.
244*1208bc7eSAndroid Build Coastguard Worker  *       Args:
245*1208bc7eSAndroid Build Coastguard Worker  *         tree: Pointer to an initialized red-black tree object.
246*1208bc7eSAndroid Build Coastguard Worker  *       Ret: True if tree is empty, false otherwise.
247*1208bc7eSAndroid Build Coastguard Worker  *
248*1208bc7eSAndroid Build Coastguard Worker  *   static ex_node_t *
249*1208bc7eSAndroid Build Coastguard Worker  *   ex_first(ex_t *tree);
250*1208bc7eSAndroid Build Coastguard Worker  *   static ex_node_t *
251*1208bc7eSAndroid Build Coastguard Worker  *   ex_last(ex_t *tree);
252*1208bc7eSAndroid Build Coastguard Worker  *       Description: Get the first/last node in tree.
253*1208bc7eSAndroid Build Coastguard Worker  *       Args:
254*1208bc7eSAndroid Build Coastguard Worker  *         tree: Pointer to an initialized red-black tree object.
255*1208bc7eSAndroid Build Coastguard Worker  *       Ret: First/last node in tree, or NULL if tree is empty.
256*1208bc7eSAndroid Build Coastguard Worker  *
257*1208bc7eSAndroid Build Coastguard Worker  *   static ex_node_t *
258*1208bc7eSAndroid Build Coastguard Worker  *   ex_next(ex_t *tree, ex_node_t *node);
259*1208bc7eSAndroid Build Coastguard Worker  *   static ex_node_t *
260*1208bc7eSAndroid Build Coastguard Worker  *   ex_prev(ex_t *tree, ex_node_t *node);
261*1208bc7eSAndroid Build Coastguard Worker  *       Description: Get node's successor/predecessor.
262*1208bc7eSAndroid Build Coastguard Worker  *       Args:
263*1208bc7eSAndroid Build Coastguard Worker  *         tree: Pointer to an initialized red-black tree object.
264*1208bc7eSAndroid Build Coastguard Worker  *         node: A node in tree.
265*1208bc7eSAndroid Build Coastguard Worker  *       Ret: node's successor/predecessor in tree, or NULL if node is
266*1208bc7eSAndroid Build Coastguard Worker  *            last/first.
267*1208bc7eSAndroid Build Coastguard Worker  *
268*1208bc7eSAndroid Build Coastguard Worker  *   static ex_node_t *
269*1208bc7eSAndroid Build Coastguard Worker  *   ex_search(ex_t *tree, const ex_node_t *key);
270*1208bc7eSAndroid Build Coastguard Worker  *       Description: Search for node that matches key.
271*1208bc7eSAndroid Build Coastguard Worker  *       Args:
272*1208bc7eSAndroid Build Coastguard Worker  *         tree: Pointer to an initialized red-black tree object.
273*1208bc7eSAndroid Build Coastguard Worker  *         key : Search key.
274*1208bc7eSAndroid Build Coastguard Worker  *       Ret: Node in tree that matches key, or NULL if no match.
275*1208bc7eSAndroid Build Coastguard Worker  *
276*1208bc7eSAndroid Build Coastguard Worker  *   static ex_node_t *
277*1208bc7eSAndroid Build Coastguard Worker  *   ex_nsearch(ex_t *tree, const ex_node_t *key);
278*1208bc7eSAndroid Build Coastguard Worker  *   static ex_node_t *
279*1208bc7eSAndroid Build Coastguard Worker  *   ex_psearch(ex_t *tree, const ex_node_t *key);
280*1208bc7eSAndroid Build Coastguard Worker  *       Description: Search for node that matches key.  If no match is found,
281*1208bc7eSAndroid Build Coastguard Worker  *                    return what would be key's successor/predecessor, were
282*1208bc7eSAndroid Build Coastguard Worker  *                    key in tree.
283*1208bc7eSAndroid Build Coastguard Worker  *       Args:
284*1208bc7eSAndroid Build Coastguard Worker  *         tree: Pointer to an initialized red-black tree object.
285*1208bc7eSAndroid Build Coastguard Worker  *         key : Search key.
286*1208bc7eSAndroid Build Coastguard Worker  *       Ret: Node in tree that matches key, or if no match, hypothetical node's
287*1208bc7eSAndroid Build Coastguard Worker  *            successor/predecessor (NULL if no successor/predecessor).
288*1208bc7eSAndroid Build Coastguard Worker  *
289*1208bc7eSAndroid Build Coastguard Worker  *   static void
290*1208bc7eSAndroid Build Coastguard Worker  *   ex_insert(ex_t *tree, ex_node_t *node);
291*1208bc7eSAndroid Build Coastguard Worker  *       Description: Insert node into tree.
292*1208bc7eSAndroid Build Coastguard Worker  *       Args:
293*1208bc7eSAndroid Build Coastguard Worker  *         tree: Pointer to an initialized red-black tree object.
294*1208bc7eSAndroid Build Coastguard Worker  *         node: Node to be inserted into tree.
295*1208bc7eSAndroid Build Coastguard Worker  *
296*1208bc7eSAndroid Build Coastguard Worker  *   static void
297*1208bc7eSAndroid Build Coastguard Worker  *   ex_remove(ex_t *tree, ex_node_t *node);
298*1208bc7eSAndroid Build Coastguard Worker  *       Description: Remove node from tree.
299*1208bc7eSAndroid Build Coastguard Worker  *       Args:
300*1208bc7eSAndroid Build Coastguard Worker  *         tree: Pointer to an initialized red-black tree object.
301*1208bc7eSAndroid Build Coastguard Worker  *         node: Node in tree to be removed.
302*1208bc7eSAndroid Build Coastguard Worker  *
303*1208bc7eSAndroid Build Coastguard Worker  *   static ex_node_t *
304*1208bc7eSAndroid Build Coastguard Worker  *   ex_iter(ex_t *tree, ex_node_t *start, ex_node_t *(*cb)(ex_t *,
305*1208bc7eSAndroid Build Coastguard Worker  *     ex_node_t *, void *), void *arg);
306*1208bc7eSAndroid Build Coastguard Worker  *   static ex_node_t *
307*1208bc7eSAndroid Build Coastguard Worker  *   ex_reverse_iter(ex_t *tree, ex_node_t *start, ex_node *(*cb)(ex_t *,
308*1208bc7eSAndroid Build Coastguard Worker  *     ex_node_t *, void *), void *arg);
309*1208bc7eSAndroid Build Coastguard Worker  *       Description: Iterate forward/backward over tree, starting at node.  If
310*1208bc7eSAndroid Build Coastguard Worker  *                    tree is modified, iteration must be immediately
311*1208bc7eSAndroid Build Coastguard Worker  *                    terminated by the callback function that causes the
312*1208bc7eSAndroid Build Coastguard Worker  *                    modification.
313*1208bc7eSAndroid Build Coastguard Worker  *       Args:
314*1208bc7eSAndroid Build Coastguard Worker  *         tree : Pointer to an initialized red-black tree object.
315*1208bc7eSAndroid Build Coastguard Worker  *         start: Node at which to start iteration, or NULL to start at
316*1208bc7eSAndroid Build Coastguard Worker  *                first/last node.
317*1208bc7eSAndroid Build Coastguard Worker  *         cb   : Callback function, which is called for each node during
318*1208bc7eSAndroid Build Coastguard Worker  *                iteration.  Under normal circumstances the callback function
319*1208bc7eSAndroid Build Coastguard Worker  *                should return NULL, which causes iteration to continue.  If a
320*1208bc7eSAndroid Build Coastguard Worker  *                callback function returns non-NULL, iteration is immediately
321*1208bc7eSAndroid Build Coastguard Worker  *                terminated and the non-NULL return value is returned by the
322*1208bc7eSAndroid Build Coastguard Worker  *                iterator.  This is useful for re-starting iteration after
323*1208bc7eSAndroid Build Coastguard Worker  *                modifying tree.
324*1208bc7eSAndroid Build Coastguard Worker  *         arg  : Opaque pointer passed to cb().
325*1208bc7eSAndroid Build Coastguard Worker  *       Ret: NULL if iteration completed, or the non-NULL callback return value
326*1208bc7eSAndroid Build Coastguard Worker  *            that caused termination of the iteration.
327*1208bc7eSAndroid Build Coastguard Worker  *
328*1208bc7eSAndroid Build Coastguard Worker  *   static void
329*1208bc7eSAndroid Build Coastguard Worker  *   ex_destroy(ex_t *tree, void (*cb)(ex_node_t *, void *), void *arg);
330*1208bc7eSAndroid Build Coastguard Worker  *       Description: Iterate over the tree with post-order traversal, remove
331*1208bc7eSAndroid Build Coastguard Worker  *                    each node, and run the callback if non-null.  This is
332*1208bc7eSAndroid Build Coastguard Worker  *                    used for destroying a tree without paying the cost to
333*1208bc7eSAndroid Build Coastguard Worker  *                    rebalance it.  The tree must not be otherwise altered
334*1208bc7eSAndroid Build Coastguard Worker  *                    during traversal.
335*1208bc7eSAndroid Build Coastguard Worker  *       Args:
336*1208bc7eSAndroid Build Coastguard Worker  *         tree: Pointer to an initialized red-black tree object.
337*1208bc7eSAndroid Build Coastguard Worker  *         cb  : Callback function, which, if non-null, is called for each node
338*1208bc7eSAndroid Build Coastguard Worker  *               during iteration.  There is no way to stop iteration once it
339*1208bc7eSAndroid Build Coastguard Worker  *               has begun.
340*1208bc7eSAndroid Build Coastguard Worker  *         arg : Opaque pointer passed to cb().
341*1208bc7eSAndroid Build Coastguard Worker  */
342*1208bc7eSAndroid Build Coastguard Worker #define rb_gen(a_attr, a_prefix, a_rbt_type, a_type, a_field, a_cmp)	\
343*1208bc7eSAndroid Build Coastguard Worker a_attr void								\
344*1208bc7eSAndroid Build Coastguard Worker a_prefix##new(a_rbt_type *rbtree) {					\
345*1208bc7eSAndroid Build Coastguard Worker     rb_new(a_type, a_field, rbtree);					\
346*1208bc7eSAndroid Build Coastguard Worker }									\
347*1208bc7eSAndroid Build Coastguard Worker a_attr bool								\
348*1208bc7eSAndroid Build Coastguard Worker a_prefix##empty(a_rbt_type *rbtree) {					\
349*1208bc7eSAndroid Build Coastguard Worker     return (rbtree->rbt_root == NULL);					\
350*1208bc7eSAndroid Build Coastguard Worker }									\
351*1208bc7eSAndroid Build Coastguard Worker a_attr a_type *								\
352*1208bc7eSAndroid Build Coastguard Worker a_prefix##first(a_rbt_type *rbtree) {					\
353*1208bc7eSAndroid Build Coastguard Worker     a_type *ret;							\
354*1208bc7eSAndroid Build Coastguard Worker     rbtn_first(a_type, a_field, rbtree, rbtree->rbt_root, ret);		\
355*1208bc7eSAndroid Build Coastguard Worker     return ret;								\
356*1208bc7eSAndroid Build Coastguard Worker }									\
357*1208bc7eSAndroid Build Coastguard Worker a_attr a_type *								\
358*1208bc7eSAndroid Build Coastguard Worker a_prefix##last(a_rbt_type *rbtree) {					\
359*1208bc7eSAndroid Build Coastguard Worker     a_type *ret;							\
360*1208bc7eSAndroid Build Coastguard Worker     rbtn_last(a_type, a_field, rbtree, rbtree->rbt_root, ret);		\
361*1208bc7eSAndroid Build Coastguard Worker     return ret;								\
362*1208bc7eSAndroid Build Coastguard Worker }									\
363*1208bc7eSAndroid Build Coastguard Worker a_attr a_type *								\
364*1208bc7eSAndroid Build Coastguard Worker a_prefix##next(a_rbt_type *rbtree, a_type *node) {			\
365*1208bc7eSAndroid Build Coastguard Worker     a_type *ret;							\
366*1208bc7eSAndroid Build Coastguard Worker     if (rbtn_right_get(a_type, a_field, node) != NULL) {		\
367*1208bc7eSAndroid Build Coastguard Worker 	rbtn_first(a_type, a_field, rbtree, rbtn_right_get(a_type,	\
368*1208bc7eSAndroid Build Coastguard Worker 	  a_field, node), ret);						\
369*1208bc7eSAndroid Build Coastguard Worker     } else {								\
370*1208bc7eSAndroid Build Coastguard Worker 	a_type *tnode = rbtree->rbt_root;				\
371*1208bc7eSAndroid Build Coastguard Worker 	assert(tnode != NULL);						\
372*1208bc7eSAndroid Build Coastguard Worker 	ret = NULL;							\
373*1208bc7eSAndroid Build Coastguard Worker 	while (true) {							\
374*1208bc7eSAndroid Build Coastguard Worker 	    int cmp = (a_cmp)(node, tnode);				\
375*1208bc7eSAndroid Build Coastguard Worker 	    if (cmp < 0) {						\
376*1208bc7eSAndroid Build Coastguard Worker 		ret = tnode;						\
377*1208bc7eSAndroid Build Coastguard Worker 		tnode = rbtn_left_get(a_type, a_field, tnode);		\
378*1208bc7eSAndroid Build Coastguard Worker 	    } else if (cmp > 0) {					\
379*1208bc7eSAndroid Build Coastguard Worker 		tnode = rbtn_right_get(a_type, a_field, tnode);		\
380*1208bc7eSAndroid Build Coastguard Worker 	    } else {							\
381*1208bc7eSAndroid Build Coastguard Worker 		break;							\
382*1208bc7eSAndroid Build Coastguard Worker 	    }								\
383*1208bc7eSAndroid Build Coastguard Worker 	    assert(tnode != NULL);					\
384*1208bc7eSAndroid Build Coastguard Worker 	}								\
385*1208bc7eSAndroid Build Coastguard Worker     }									\
386*1208bc7eSAndroid Build Coastguard Worker     return ret;								\
387*1208bc7eSAndroid Build Coastguard Worker }									\
388*1208bc7eSAndroid Build Coastguard Worker a_attr a_type *								\
389*1208bc7eSAndroid Build Coastguard Worker a_prefix##prev(a_rbt_type *rbtree, a_type *node) {			\
390*1208bc7eSAndroid Build Coastguard Worker     a_type *ret;							\
391*1208bc7eSAndroid Build Coastguard Worker     if (rbtn_left_get(a_type, a_field, node) != NULL) {			\
392*1208bc7eSAndroid Build Coastguard Worker 	rbtn_last(a_type, a_field, rbtree, rbtn_left_get(a_type,	\
393*1208bc7eSAndroid Build Coastguard Worker 	  a_field, node), ret);						\
394*1208bc7eSAndroid Build Coastguard Worker     } else {								\
395*1208bc7eSAndroid Build Coastguard Worker 	a_type *tnode = rbtree->rbt_root;				\
396*1208bc7eSAndroid Build Coastguard Worker 	assert(tnode != NULL);						\
397*1208bc7eSAndroid Build Coastguard Worker 	ret = NULL;							\
398*1208bc7eSAndroid Build Coastguard Worker 	while (true) {							\
399*1208bc7eSAndroid Build Coastguard Worker 	    int cmp = (a_cmp)(node, tnode);				\
400*1208bc7eSAndroid Build Coastguard Worker 	    if (cmp < 0) {						\
401*1208bc7eSAndroid Build Coastguard Worker 		tnode = rbtn_left_get(a_type, a_field, tnode);		\
402*1208bc7eSAndroid Build Coastguard Worker 	    } else if (cmp > 0) {					\
403*1208bc7eSAndroid Build Coastguard Worker 		ret = tnode;						\
404*1208bc7eSAndroid Build Coastguard Worker 		tnode = rbtn_right_get(a_type, a_field, tnode);		\
405*1208bc7eSAndroid Build Coastguard Worker 	    } else {							\
406*1208bc7eSAndroid Build Coastguard Worker 		break;							\
407*1208bc7eSAndroid Build Coastguard Worker 	    }								\
408*1208bc7eSAndroid Build Coastguard Worker 	    assert(tnode != NULL);					\
409*1208bc7eSAndroid Build Coastguard Worker 	}								\
410*1208bc7eSAndroid Build Coastguard Worker     }									\
411*1208bc7eSAndroid Build Coastguard Worker     return ret;								\
412*1208bc7eSAndroid Build Coastguard Worker }									\
413*1208bc7eSAndroid Build Coastguard Worker a_attr a_type *								\
414*1208bc7eSAndroid Build Coastguard Worker a_prefix##search(a_rbt_type *rbtree, const a_type *key) {		\
415*1208bc7eSAndroid Build Coastguard Worker     a_type *ret;							\
416*1208bc7eSAndroid Build Coastguard Worker     int cmp;								\
417*1208bc7eSAndroid Build Coastguard Worker     ret = rbtree->rbt_root;						\
418*1208bc7eSAndroid Build Coastguard Worker     while (ret != NULL							\
419*1208bc7eSAndroid Build Coastguard Worker       && (cmp = (a_cmp)(key, ret)) != 0) {				\
420*1208bc7eSAndroid Build Coastguard Worker 	if (cmp < 0) {							\
421*1208bc7eSAndroid Build Coastguard Worker 	    ret = rbtn_left_get(a_type, a_field, ret);			\
422*1208bc7eSAndroid Build Coastguard Worker 	} else {							\
423*1208bc7eSAndroid Build Coastguard Worker 	    ret = rbtn_right_get(a_type, a_field, ret);			\
424*1208bc7eSAndroid Build Coastguard Worker 	}								\
425*1208bc7eSAndroid Build Coastguard Worker     }									\
426*1208bc7eSAndroid Build Coastguard Worker     return ret;								\
427*1208bc7eSAndroid Build Coastguard Worker }									\
428*1208bc7eSAndroid Build Coastguard Worker a_attr a_type *								\
429*1208bc7eSAndroid Build Coastguard Worker a_prefix##nsearch(a_rbt_type *rbtree, const a_type *key) {		\
430*1208bc7eSAndroid Build Coastguard Worker     a_type *ret;							\
431*1208bc7eSAndroid Build Coastguard Worker     a_type *tnode = rbtree->rbt_root;					\
432*1208bc7eSAndroid Build Coastguard Worker     ret = NULL;								\
433*1208bc7eSAndroid Build Coastguard Worker     while (tnode != NULL) {						\
434*1208bc7eSAndroid Build Coastguard Worker 	int cmp = (a_cmp)(key, tnode);					\
435*1208bc7eSAndroid Build Coastguard Worker 	if (cmp < 0) {							\
436*1208bc7eSAndroid Build Coastguard Worker 	    ret = tnode;						\
437*1208bc7eSAndroid Build Coastguard Worker 	    tnode = rbtn_left_get(a_type, a_field, tnode);		\
438*1208bc7eSAndroid Build Coastguard Worker 	} else if (cmp > 0) {						\
439*1208bc7eSAndroid Build Coastguard Worker 	    tnode = rbtn_right_get(a_type, a_field, tnode);		\
440*1208bc7eSAndroid Build Coastguard Worker 	} else {							\
441*1208bc7eSAndroid Build Coastguard Worker 	    ret = tnode;						\
442*1208bc7eSAndroid Build Coastguard Worker 	    break;							\
443*1208bc7eSAndroid Build Coastguard Worker 	}								\
444*1208bc7eSAndroid Build Coastguard Worker     }									\
445*1208bc7eSAndroid Build Coastguard Worker     return ret;								\
446*1208bc7eSAndroid Build Coastguard Worker }									\
447*1208bc7eSAndroid Build Coastguard Worker a_attr a_type *								\
448*1208bc7eSAndroid Build Coastguard Worker a_prefix##psearch(a_rbt_type *rbtree, const a_type *key) {		\
449*1208bc7eSAndroid Build Coastguard Worker     a_type *ret;							\
450*1208bc7eSAndroid Build Coastguard Worker     a_type *tnode = rbtree->rbt_root;					\
451*1208bc7eSAndroid Build Coastguard Worker     ret = NULL;								\
452*1208bc7eSAndroid Build Coastguard Worker     while (tnode != NULL) {						\
453*1208bc7eSAndroid Build Coastguard Worker 	int cmp = (a_cmp)(key, tnode);					\
454*1208bc7eSAndroid Build Coastguard Worker 	if (cmp < 0) {							\
455*1208bc7eSAndroid Build Coastguard Worker 	    tnode = rbtn_left_get(a_type, a_field, tnode);		\
456*1208bc7eSAndroid Build Coastguard Worker 	} else if (cmp > 0) {						\
457*1208bc7eSAndroid Build Coastguard Worker 	    ret = tnode;						\
458*1208bc7eSAndroid Build Coastguard Worker 	    tnode = rbtn_right_get(a_type, a_field, tnode);		\
459*1208bc7eSAndroid Build Coastguard Worker 	} else {							\
460*1208bc7eSAndroid Build Coastguard Worker 	    ret = tnode;						\
461*1208bc7eSAndroid Build Coastguard Worker 	    break;							\
462*1208bc7eSAndroid Build Coastguard Worker 	}								\
463*1208bc7eSAndroid Build Coastguard Worker     }									\
464*1208bc7eSAndroid Build Coastguard Worker     return ret;								\
465*1208bc7eSAndroid Build Coastguard Worker }									\
466*1208bc7eSAndroid Build Coastguard Worker a_attr void								\
467*1208bc7eSAndroid Build Coastguard Worker a_prefix##insert(a_rbt_type *rbtree, a_type *node) {			\
468*1208bc7eSAndroid Build Coastguard Worker     struct {								\
469*1208bc7eSAndroid Build Coastguard Worker 	a_type *node;							\
470*1208bc7eSAndroid Build Coastguard Worker 	int cmp;							\
471*1208bc7eSAndroid Build Coastguard Worker     } path[sizeof(void *) << 4], *pathp;				\
472*1208bc7eSAndroid Build Coastguard Worker     rbt_node_new(a_type, a_field, rbtree, node);			\
473*1208bc7eSAndroid Build Coastguard Worker     /* Wind. */								\
474*1208bc7eSAndroid Build Coastguard Worker     path->node = rbtree->rbt_root;					\
475*1208bc7eSAndroid Build Coastguard Worker     for (pathp = path; pathp->node != NULL; pathp++) {			\
476*1208bc7eSAndroid Build Coastguard Worker 	int cmp = pathp->cmp = a_cmp(node, pathp->node);		\
477*1208bc7eSAndroid Build Coastguard Worker 	assert(cmp != 0);						\
478*1208bc7eSAndroid Build Coastguard Worker 	if (cmp < 0) {							\
479*1208bc7eSAndroid Build Coastguard Worker 	    pathp[1].node = rbtn_left_get(a_type, a_field,		\
480*1208bc7eSAndroid Build Coastguard Worker 	      pathp->node);						\
481*1208bc7eSAndroid Build Coastguard Worker 	} else {							\
482*1208bc7eSAndroid Build Coastguard Worker 	    pathp[1].node = rbtn_right_get(a_type, a_field,		\
483*1208bc7eSAndroid Build Coastguard Worker 	      pathp->node);						\
484*1208bc7eSAndroid Build Coastguard Worker 	}								\
485*1208bc7eSAndroid Build Coastguard Worker     }									\
486*1208bc7eSAndroid Build Coastguard Worker     pathp->node = node;							\
487*1208bc7eSAndroid Build Coastguard Worker     /* Unwind. */							\
488*1208bc7eSAndroid Build Coastguard Worker     for (pathp--; (uintptr_t)pathp >= (uintptr_t)path; pathp--) {	\
489*1208bc7eSAndroid Build Coastguard Worker 	a_type *cnode = pathp->node;					\
490*1208bc7eSAndroid Build Coastguard Worker 	if (pathp->cmp < 0) {						\
491*1208bc7eSAndroid Build Coastguard Worker 	    a_type *left = pathp[1].node;				\
492*1208bc7eSAndroid Build Coastguard Worker 	    rbtn_left_set(a_type, a_field, cnode, left);		\
493*1208bc7eSAndroid Build Coastguard Worker 	    if (rbtn_red_get(a_type, a_field, left)) {			\
494*1208bc7eSAndroid Build Coastguard Worker 		a_type *leftleft = rbtn_left_get(a_type, a_field, left);\
495*1208bc7eSAndroid Build Coastguard Worker 		if (leftleft != NULL && rbtn_red_get(a_type, a_field,	\
496*1208bc7eSAndroid Build Coastguard Worker 		  leftleft)) {						\
497*1208bc7eSAndroid Build Coastguard Worker 		    /* Fix up 4-node. */				\
498*1208bc7eSAndroid Build Coastguard Worker 		    a_type *tnode;					\
499*1208bc7eSAndroid Build Coastguard Worker 		    rbtn_black_set(a_type, a_field, leftleft);		\
500*1208bc7eSAndroid Build Coastguard Worker 		    rbtn_rotate_right(a_type, a_field, cnode, tnode);	\
501*1208bc7eSAndroid Build Coastguard Worker 		    cnode = tnode;					\
502*1208bc7eSAndroid Build Coastguard Worker 		}							\
503*1208bc7eSAndroid Build Coastguard Worker 	    } else {							\
504*1208bc7eSAndroid Build Coastguard Worker 		return;							\
505*1208bc7eSAndroid Build Coastguard Worker 	    }								\
506*1208bc7eSAndroid Build Coastguard Worker 	} else {							\
507*1208bc7eSAndroid Build Coastguard Worker 	    a_type *right = pathp[1].node;				\
508*1208bc7eSAndroid Build Coastguard Worker 	    rbtn_right_set(a_type, a_field, cnode, right);		\
509*1208bc7eSAndroid Build Coastguard Worker 	    if (rbtn_red_get(a_type, a_field, right)) {			\
510*1208bc7eSAndroid Build Coastguard Worker 		a_type *left = rbtn_left_get(a_type, a_field, cnode);	\
511*1208bc7eSAndroid Build Coastguard Worker 		if (left != NULL && rbtn_red_get(a_type, a_field,	\
512*1208bc7eSAndroid Build Coastguard Worker 		  left)) {						\
513*1208bc7eSAndroid Build Coastguard Worker 		    /* Split 4-node. */					\
514*1208bc7eSAndroid Build Coastguard Worker 		    rbtn_black_set(a_type, a_field, left);		\
515*1208bc7eSAndroid Build Coastguard Worker 		    rbtn_black_set(a_type, a_field, right);		\
516*1208bc7eSAndroid Build Coastguard Worker 		    rbtn_red_set(a_type, a_field, cnode);		\
517*1208bc7eSAndroid Build Coastguard Worker 		} else {						\
518*1208bc7eSAndroid Build Coastguard Worker 		    /* Lean left. */					\
519*1208bc7eSAndroid Build Coastguard Worker 		    a_type *tnode;					\
520*1208bc7eSAndroid Build Coastguard Worker 		    bool tred = rbtn_red_get(a_type, a_field, cnode);	\
521*1208bc7eSAndroid Build Coastguard Worker 		    rbtn_rotate_left(a_type, a_field, cnode, tnode);	\
522*1208bc7eSAndroid Build Coastguard Worker 		    rbtn_color_set(a_type, a_field, tnode, tred);	\
523*1208bc7eSAndroid Build Coastguard Worker 		    rbtn_red_set(a_type, a_field, cnode);		\
524*1208bc7eSAndroid Build Coastguard Worker 		    cnode = tnode;					\
525*1208bc7eSAndroid Build Coastguard Worker 		}							\
526*1208bc7eSAndroid Build Coastguard Worker 	    } else {							\
527*1208bc7eSAndroid Build Coastguard Worker 		return;							\
528*1208bc7eSAndroid Build Coastguard Worker 	    }								\
529*1208bc7eSAndroid Build Coastguard Worker 	}								\
530*1208bc7eSAndroid Build Coastguard Worker 	pathp->node = cnode;						\
531*1208bc7eSAndroid Build Coastguard Worker     }									\
532*1208bc7eSAndroid Build Coastguard Worker     /* Set root, and make it black. */					\
533*1208bc7eSAndroid Build Coastguard Worker     rbtree->rbt_root = path->node;					\
534*1208bc7eSAndroid Build Coastguard Worker     rbtn_black_set(a_type, a_field, rbtree->rbt_root);			\
535*1208bc7eSAndroid Build Coastguard Worker }									\
536*1208bc7eSAndroid Build Coastguard Worker a_attr void								\
537*1208bc7eSAndroid Build Coastguard Worker a_prefix##remove(a_rbt_type *rbtree, a_type *node) {			\
538*1208bc7eSAndroid Build Coastguard Worker     struct {								\
539*1208bc7eSAndroid Build Coastguard Worker 	a_type *node;							\
540*1208bc7eSAndroid Build Coastguard Worker 	int cmp;							\
541*1208bc7eSAndroid Build Coastguard Worker     } *pathp, *nodep, path[sizeof(void *) << 4];			\
542*1208bc7eSAndroid Build Coastguard Worker     /* Wind. */								\
543*1208bc7eSAndroid Build Coastguard Worker     nodep = NULL; /* Silence compiler warning. */			\
544*1208bc7eSAndroid Build Coastguard Worker     path->node = rbtree->rbt_root;					\
545*1208bc7eSAndroid Build Coastguard Worker     for (pathp = path; pathp->node != NULL; pathp++) {			\
546*1208bc7eSAndroid Build Coastguard Worker 	int cmp = pathp->cmp = a_cmp(node, pathp->node);		\
547*1208bc7eSAndroid Build Coastguard Worker 	if (cmp < 0) {							\
548*1208bc7eSAndroid Build Coastguard Worker 	    pathp[1].node = rbtn_left_get(a_type, a_field,		\
549*1208bc7eSAndroid Build Coastguard Worker 	      pathp->node);						\
550*1208bc7eSAndroid Build Coastguard Worker 	} else {							\
551*1208bc7eSAndroid Build Coastguard Worker 	    pathp[1].node = rbtn_right_get(a_type, a_field,		\
552*1208bc7eSAndroid Build Coastguard Worker 	      pathp->node);						\
553*1208bc7eSAndroid Build Coastguard Worker 	    if (cmp == 0) {						\
554*1208bc7eSAndroid Build Coastguard Worker 	        /* Find node's successor, in preparation for swap. */	\
555*1208bc7eSAndroid Build Coastguard Worker 		pathp->cmp = 1;						\
556*1208bc7eSAndroid Build Coastguard Worker 		nodep = pathp;						\
557*1208bc7eSAndroid Build Coastguard Worker 		for (pathp++; pathp->node != NULL; pathp++) {		\
558*1208bc7eSAndroid Build Coastguard Worker 		    pathp->cmp = -1;					\
559*1208bc7eSAndroid Build Coastguard Worker 		    pathp[1].node = rbtn_left_get(a_type, a_field,	\
560*1208bc7eSAndroid Build Coastguard Worker 		      pathp->node);					\
561*1208bc7eSAndroid Build Coastguard Worker 		}							\
562*1208bc7eSAndroid Build Coastguard Worker 		break;							\
563*1208bc7eSAndroid Build Coastguard Worker 	    }								\
564*1208bc7eSAndroid Build Coastguard Worker 	}								\
565*1208bc7eSAndroid Build Coastguard Worker     }									\
566*1208bc7eSAndroid Build Coastguard Worker     assert(nodep->node == node);					\
567*1208bc7eSAndroid Build Coastguard Worker     pathp--;								\
568*1208bc7eSAndroid Build Coastguard Worker     if (pathp->node != node) {						\
569*1208bc7eSAndroid Build Coastguard Worker 	/* Swap node with its successor. */				\
570*1208bc7eSAndroid Build Coastguard Worker 	bool tred = rbtn_red_get(a_type, a_field, pathp->node);		\
571*1208bc7eSAndroid Build Coastguard Worker 	rbtn_color_set(a_type, a_field, pathp->node,			\
572*1208bc7eSAndroid Build Coastguard Worker 	  rbtn_red_get(a_type, a_field, node));				\
573*1208bc7eSAndroid Build Coastguard Worker 	rbtn_left_set(a_type, a_field, pathp->node,			\
574*1208bc7eSAndroid Build Coastguard Worker 	  rbtn_left_get(a_type, a_field, node));			\
575*1208bc7eSAndroid Build Coastguard Worker 	/* If node's successor is its right child, the following code */\
576*1208bc7eSAndroid Build Coastguard Worker 	/* will do the wrong thing for the right child pointer.       */\
577*1208bc7eSAndroid Build Coastguard Worker 	/* However, it doesn't matter, because the pointer will be    */\
578*1208bc7eSAndroid Build Coastguard Worker 	/* properly set when the successor is pruned.                 */\
579*1208bc7eSAndroid Build Coastguard Worker 	rbtn_right_set(a_type, a_field, pathp->node,			\
580*1208bc7eSAndroid Build Coastguard Worker 	  rbtn_right_get(a_type, a_field, node));			\
581*1208bc7eSAndroid Build Coastguard Worker 	rbtn_color_set(a_type, a_field, node, tred);			\
582*1208bc7eSAndroid Build Coastguard Worker 	/* The pruned leaf node's child pointers are never accessed   */\
583*1208bc7eSAndroid Build Coastguard Worker 	/* again, so don't bother setting them to nil.                */\
584*1208bc7eSAndroid Build Coastguard Worker 	nodep->node = pathp->node;					\
585*1208bc7eSAndroid Build Coastguard Worker 	pathp->node = node;						\
586*1208bc7eSAndroid Build Coastguard Worker 	if (nodep == path) {						\
587*1208bc7eSAndroid Build Coastguard Worker 	    rbtree->rbt_root = nodep->node;				\
588*1208bc7eSAndroid Build Coastguard Worker 	} else {							\
589*1208bc7eSAndroid Build Coastguard Worker 	    if (nodep[-1].cmp < 0) {					\
590*1208bc7eSAndroid Build Coastguard Worker 		rbtn_left_set(a_type, a_field, nodep[-1].node,		\
591*1208bc7eSAndroid Build Coastguard Worker 		  nodep->node);						\
592*1208bc7eSAndroid Build Coastguard Worker 	    } else {							\
593*1208bc7eSAndroid Build Coastguard Worker 		rbtn_right_set(a_type, a_field, nodep[-1].node,		\
594*1208bc7eSAndroid Build Coastguard Worker 		  nodep->node);						\
595*1208bc7eSAndroid Build Coastguard Worker 	    }								\
596*1208bc7eSAndroid Build Coastguard Worker 	}								\
597*1208bc7eSAndroid Build Coastguard Worker     } else {								\
598*1208bc7eSAndroid Build Coastguard Worker 	a_type *left = rbtn_left_get(a_type, a_field, node);		\
599*1208bc7eSAndroid Build Coastguard Worker 	if (left != NULL) {						\
600*1208bc7eSAndroid Build Coastguard Worker 	    /* node has no successor, but it has a left child.        */\
601*1208bc7eSAndroid Build Coastguard Worker 	    /* Splice node out, without losing the left child.        */\
602*1208bc7eSAndroid Build Coastguard Worker 	    assert(!rbtn_red_get(a_type, a_field, node));		\
603*1208bc7eSAndroid Build Coastguard Worker 	    assert(rbtn_red_get(a_type, a_field, left));		\
604*1208bc7eSAndroid Build Coastguard Worker 	    rbtn_black_set(a_type, a_field, left);			\
605*1208bc7eSAndroid Build Coastguard Worker 	    if (pathp == path) {					\
606*1208bc7eSAndroid Build Coastguard Worker 		rbtree->rbt_root = left;				\
607*1208bc7eSAndroid Build Coastguard Worker 	    } else {							\
608*1208bc7eSAndroid Build Coastguard Worker 		if (pathp[-1].cmp < 0) {				\
609*1208bc7eSAndroid Build Coastguard Worker 		    rbtn_left_set(a_type, a_field, pathp[-1].node,	\
610*1208bc7eSAndroid Build Coastguard Worker 		      left);						\
611*1208bc7eSAndroid Build Coastguard Worker 		} else {						\
612*1208bc7eSAndroid Build Coastguard Worker 		    rbtn_right_set(a_type, a_field, pathp[-1].node,	\
613*1208bc7eSAndroid Build Coastguard Worker 		      left);						\
614*1208bc7eSAndroid Build Coastguard Worker 		}							\
615*1208bc7eSAndroid Build Coastguard Worker 	    }								\
616*1208bc7eSAndroid Build Coastguard Worker 	    return;							\
617*1208bc7eSAndroid Build Coastguard Worker 	} else if (pathp == path) {					\
618*1208bc7eSAndroid Build Coastguard Worker 	    /* The tree only contained one node. */			\
619*1208bc7eSAndroid Build Coastguard Worker 	    rbtree->rbt_root = NULL;					\
620*1208bc7eSAndroid Build Coastguard Worker 	    return;							\
621*1208bc7eSAndroid Build Coastguard Worker 	}								\
622*1208bc7eSAndroid Build Coastguard Worker     }									\
623*1208bc7eSAndroid Build Coastguard Worker     if (rbtn_red_get(a_type, a_field, pathp->node)) {			\
624*1208bc7eSAndroid Build Coastguard Worker 	/* Prune red node, which requires no fixup. */			\
625*1208bc7eSAndroid Build Coastguard Worker 	assert(pathp[-1].cmp < 0);					\
626*1208bc7eSAndroid Build Coastguard Worker 	rbtn_left_set(a_type, a_field, pathp[-1].node, NULL);		\
627*1208bc7eSAndroid Build Coastguard Worker 	return;								\
628*1208bc7eSAndroid Build Coastguard Worker     }									\
629*1208bc7eSAndroid Build Coastguard Worker     /* The node to be pruned is black, so unwind until balance is     */\
630*1208bc7eSAndroid Build Coastguard Worker     /* restored.                                                      */\
631*1208bc7eSAndroid Build Coastguard Worker     pathp->node = NULL;							\
632*1208bc7eSAndroid Build Coastguard Worker     for (pathp--; (uintptr_t)pathp >= (uintptr_t)path; pathp--) {	\
633*1208bc7eSAndroid Build Coastguard Worker 	assert(pathp->cmp != 0);					\
634*1208bc7eSAndroid Build Coastguard Worker 	if (pathp->cmp < 0) {						\
635*1208bc7eSAndroid Build Coastguard Worker 	    rbtn_left_set(a_type, a_field, pathp->node,			\
636*1208bc7eSAndroid Build Coastguard Worker 	      pathp[1].node);						\
637*1208bc7eSAndroid Build Coastguard Worker 	    if (rbtn_red_get(a_type, a_field, pathp->node)) {		\
638*1208bc7eSAndroid Build Coastguard Worker 		a_type *right = rbtn_right_get(a_type, a_field,		\
639*1208bc7eSAndroid Build Coastguard Worker 		  pathp->node);						\
640*1208bc7eSAndroid Build Coastguard Worker 		a_type *rightleft = rbtn_left_get(a_type, a_field,	\
641*1208bc7eSAndroid Build Coastguard Worker 		  right);						\
642*1208bc7eSAndroid Build Coastguard Worker 		a_type *tnode;						\
643*1208bc7eSAndroid Build Coastguard Worker 		if (rightleft != NULL && rbtn_red_get(a_type, a_field,	\
644*1208bc7eSAndroid Build Coastguard Worker 		  rightleft)) {						\
645*1208bc7eSAndroid Build Coastguard Worker 		    /* In the following diagrams, ||, //, and \\      */\
646*1208bc7eSAndroid Build Coastguard Worker 		    /* indicate the path to the removed node.         */\
647*1208bc7eSAndroid Build Coastguard Worker 		    /*                                                */\
648*1208bc7eSAndroid Build Coastguard Worker 		    /*      ||                                        */\
649*1208bc7eSAndroid Build Coastguard Worker 		    /*    pathp(r)                                    */\
650*1208bc7eSAndroid Build Coastguard Worker 		    /*  //        \                                   */\
651*1208bc7eSAndroid Build Coastguard Worker 		    /* (b)        (b)                                 */\
652*1208bc7eSAndroid Build Coastguard Worker 		    /*           /                                    */\
653*1208bc7eSAndroid Build Coastguard Worker 		    /*          (r)                                   */\
654*1208bc7eSAndroid Build Coastguard Worker 		    /*                                                */\
655*1208bc7eSAndroid Build Coastguard Worker 		    rbtn_black_set(a_type, a_field, pathp->node);	\
656*1208bc7eSAndroid Build Coastguard Worker 		    rbtn_rotate_right(a_type, a_field, right, tnode);	\
657*1208bc7eSAndroid Build Coastguard Worker 		    rbtn_right_set(a_type, a_field, pathp->node, tnode);\
658*1208bc7eSAndroid Build Coastguard Worker 		    rbtn_rotate_left(a_type, a_field, pathp->node,	\
659*1208bc7eSAndroid Build Coastguard Worker 		      tnode);						\
660*1208bc7eSAndroid Build Coastguard Worker 		} else {						\
661*1208bc7eSAndroid Build Coastguard Worker 		    /*      ||                                        */\
662*1208bc7eSAndroid Build Coastguard Worker 		    /*    pathp(r)                                    */\
663*1208bc7eSAndroid Build Coastguard Worker 		    /*  //        \                                   */\
664*1208bc7eSAndroid Build Coastguard Worker 		    /* (b)        (b)                                 */\
665*1208bc7eSAndroid Build Coastguard Worker 		    /*           /                                    */\
666*1208bc7eSAndroid Build Coastguard Worker 		    /*          (b)                                   */\
667*1208bc7eSAndroid Build Coastguard Worker 		    /*                                                */\
668*1208bc7eSAndroid Build Coastguard Worker 		    rbtn_rotate_left(a_type, a_field, pathp->node,	\
669*1208bc7eSAndroid Build Coastguard Worker 		      tnode);						\
670*1208bc7eSAndroid Build Coastguard Worker 		}							\
671*1208bc7eSAndroid Build Coastguard Worker 		/* Balance restored, but rotation modified subtree    */\
672*1208bc7eSAndroid Build Coastguard Worker 		/* root.                                              */\
673*1208bc7eSAndroid Build Coastguard Worker 		assert((uintptr_t)pathp > (uintptr_t)path);		\
674*1208bc7eSAndroid Build Coastguard Worker 		if (pathp[-1].cmp < 0) {				\
675*1208bc7eSAndroid Build Coastguard Worker 		    rbtn_left_set(a_type, a_field, pathp[-1].node,	\
676*1208bc7eSAndroid Build Coastguard Worker 		      tnode);						\
677*1208bc7eSAndroid Build Coastguard Worker 		} else {						\
678*1208bc7eSAndroid Build Coastguard Worker 		    rbtn_right_set(a_type, a_field, pathp[-1].node,	\
679*1208bc7eSAndroid Build Coastguard Worker 		      tnode);						\
680*1208bc7eSAndroid Build Coastguard Worker 		}							\
681*1208bc7eSAndroid Build Coastguard Worker 		return;							\
682*1208bc7eSAndroid Build Coastguard Worker 	    } else {							\
683*1208bc7eSAndroid Build Coastguard Worker 		a_type *right = rbtn_right_get(a_type, a_field,		\
684*1208bc7eSAndroid Build Coastguard Worker 		  pathp->node);						\
685*1208bc7eSAndroid Build Coastguard Worker 		a_type *rightleft = rbtn_left_get(a_type, a_field,	\
686*1208bc7eSAndroid Build Coastguard Worker 		  right);						\
687*1208bc7eSAndroid Build Coastguard Worker 		if (rightleft != NULL && rbtn_red_get(a_type, a_field,	\
688*1208bc7eSAndroid Build Coastguard Worker 		  rightleft)) {						\
689*1208bc7eSAndroid Build Coastguard Worker 		    /*      ||                                        */\
690*1208bc7eSAndroid Build Coastguard Worker 		    /*    pathp(b)                                    */\
691*1208bc7eSAndroid Build Coastguard Worker 		    /*  //        \                                   */\
692*1208bc7eSAndroid Build Coastguard Worker 		    /* (b)        (b)                                 */\
693*1208bc7eSAndroid Build Coastguard Worker 		    /*           /                                    */\
694*1208bc7eSAndroid Build Coastguard Worker 		    /*          (r)                                   */\
695*1208bc7eSAndroid Build Coastguard Worker 		    a_type *tnode;					\
696*1208bc7eSAndroid Build Coastguard Worker 		    rbtn_black_set(a_type, a_field, rightleft);		\
697*1208bc7eSAndroid Build Coastguard Worker 		    rbtn_rotate_right(a_type, a_field, right, tnode);	\
698*1208bc7eSAndroid Build Coastguard Worker 		    rbtn_right_set(a_type, a_field, pathp->node, tnode);\
699*1208bc7eSAndroid Build Coastguard Worker 		    rbtn_rotate_left(a_type, a_field, pathp->node,	\
700*1208bc7eSAndroid Build Coastguard Worker 		      tnode);						\
701*1208bc7eSAndroid Build Coastguard Worker 		    /* Balance restored, but rotation modified        */\
702*1208bc7eSAndroid Build Coastguard Worker 		    /* subtree root, which may actually be the tree   */\
703*1208bc7eSAndroid Build Coastguard Worker 		    /* root.                                          */\
704*1208bc7eSAndroid Build Coastguard Worker 		    if (pathp == path) {				\
705*1208bc7eSAndroid Build Coastguard Worker 			/* Set root. */					\
706*1208bc7eSAndroid Build Coastguard Worker 			rbtree->rbt_root = tnode;			\
707*1208bc7eSAndroid Build Coastguard Worker 		    } else {						\
708*1208bc7eSAndroid Build Coastguard Worker 			if (pathp[-1].cmp < 0) {			\
709*1208bc7eSAndroid Build Coastguard Worker 			    rbtn_left_set(a_type, a_field,		\
710*1208bc7eSAndroid Build Coastguard Worker 			      pathp[-1].node, tnode);			\
711*1208bc7eSAndroid Build Coastguard Worker 			} else {					\
712*1208bc7eSAndroid Build Coastguard Worker 			    rbtn_right_set(a_type, a_field,		\
713*1208bc7eSAndroid Build Coastguard Worker 			      pathp[-1].node, tnode);			\
714*1208bc7eSAndroid Build Coastguard Worker 			}						\
715*1208bc7eSAndroid Build Coastguard Worker 		    }							\
716*1208bc7eSAndroid Build Coastguard Worker 		    return;						\
717*1208bc7eSAndroid Build Coastguard Worker 		} else {						\
718*1208bc7eSAndroid Build Coastguard Worker 		    /*      ||                                        */\
719*1208bc7eSAndroid Build Coastguard Worker 		    /*    pathp(b)                                    */\
720*1208bc7eSAndroid Build Coastguard Worker 		    /*  //        \                                   */\
721*1208bc7eSAndroid Build Coastguard Worker 		    /* (b)        (b)                                 */\
722*1208bc7eSAndroid Build Coastguard Worker 		    /*           /                                    */\
723*1208bc7eSAndroid Build Coastguard Worker 		    /*          (b)                                   */\
724*1208bc7eSAndroid Build Coastguard Worker 		    a_type *tnode;					\
725*1208bc7eSAndroid Build Coastguard Worker 		    rbtn_red_set(a_type, a_field, pathp->node);		\
726*1208bc7eSAndroid Build Coastguard Worker 		    rbtn_rotate_left(a_type, a_field, pathp->node,	\
727*1208bc7eSAndroid Build Coastguard Worker 		      tnode);						\
728*1208bc7eSAndroid Build Coastguard Worker 		    pathp->node = tnode;				\
729*1208bc7eSAndroid Build Coastguard Worker 		}							\
730*1208bc7eSAndroid Build Coastguard Worker 	    }								\
731*1208bc7eSAndroid Build Coastguard Worker 	} else {							\
732*1208bc7eSAndroid Build Coastguard Worker 	    a_type *left;						\
733*1208bc7eSAndroid Build Coastguard Worker 	    rbtn_right_set(a_type, a_field, pathp->node,		\
734*1208bc7eSAndroid Build Coastguard Worker 	      pathp[1].node);						\
735*1208bc7eSAndroid Build Coastguard Worker 	    left = rbtn_left_get(a_type, a_field, pathp->node);		\
736*1208bc7eSAndroid Build Coastguard Worker 	    if (rbtn_red_get(a_type, a_field, left)) {			\
737*1208bc7eSAndroid Build Coastguard Worker 		a_type *tnode;						\
738*1208bc7eSAndroid Build Coastguard Worker 		a_type *leftright = rbtn_right_get(a_type, a_field,	\
739*1208bc7eSAndroid Build Coastguard Worker 		  left);						\
740*1208bc7eSAndroid Build Coastguard Worker 		a_type *leftrightleft = rbtn_left_get(a_type, a_field,	\
741*1208bc7eSAndroid Build Coastguard Worker 		  leftright);						\
742*1208bc7eSAndroid Build Coastguard Worker 		if (leftrightleft != NULL && rbtn_red_get(a_type,	\
743*1208bc7eSAndroid Build Coastguard Worker 		  a_field, leftrightleft)) {				\
744*1208bc7eSAndroid Build Coastguard Worker 		    /*      ||                                        */\
745*1208bc7eSAndroid Build Coastguard Worker 		    /*    pathp(b)                                    */\
746*1208bc7eSAndroid Build Coastguard Worker 		    /*   /        \\                                  */\
747*1208bc7eSAndroid Build Coastguard Worker 		    /* (r)        (b)                                 */\
748*1208bc7eSAndroid Build Coastguard Worker 		    /*   \                                            */\
749*1208bc7eSAndroid Build Coastguard Worker 		    /*   (b)                                          */\
750*1208bc7eSAndroid Build Coastguard Worker 		    /*   /                                            */\
751*1208bc7eSAndroid Build Coastguard Worker 		    /* (r)                                            */\
752*1208bc7eSAndroid Build Coastguard Worker 		    a_type *unode;					\
753*1208bc7eSAndroid Build Coastguard Worker 		    rbtn_black_set(a_type, a_field, leftrightleft);	\
754*1208bc7eSAndroid Build Coastguard Worker 		    rbtn_rotate_right(a_type, a_field, pathp->node,	\
755*1208bc7eSAndroid Build Coastguard Worker 		      unode);						\
756*1208bc7eSAndroid Build Coastguard Worker 		    rbtn_rotate_right(a_type, a_field, pathp->node,	\
757*1208bc7eSAndroid Build Coastguard Worker 		      tnode);						\
758*1208bc7eSAndroid Build Coastguard Worker 		    rbtn_right_set(a_type, a_field, unode, tnode);	\
759*1208bc7eSAndroid Build Coastguard Worker 		    rbtn_rotate_left(a_type, a_field, unode, tnode);	\
760*1208bc7eSAndroid Build Coastguard Worker 		} else {						\
761*1208bc7eSAndroid Build Coastguard Worker 		    /*      ||                                        */\
762*1208bc7eSAndroid Build Coastguard Worker 		    /*    pathp(b)                                    */\
763*1208bc7eSAndroid Build Coastguard Worker 		    /*   /        \\                                  */\
764*1208bc7eSAndroid Build Coastguard Worker 		    /* (r)        (b)                                 */\
765*1208bc7eSAndroid Build Coastguard Worker 		    /*   \                                            */\
766*1208bc7eSAndroid Build Coastguard Worker 		    /*   (b)                                          */\
767*1208bc7eSAndroid Build Coastguard Worker 		    /*   /                                            */\
768*1208bc7eSAndroid Build Coastguard Worker 		    /* (b)                                            */\
769*1208bc7eSAndroid Build Coastguard Worker 		    assert(leftright != NULL);				\
770*1208bc7eSAndroid Build Coastguard Worker 		    rbtn_red_set(a_type, a_field, leftright);		\
771*1208bc7eSAndroid Build Coastguard Worker 		    rbtn_rotate_right(a_type, a_field, pathp->node,	\
772*1208bc7eSAndroid Build Coastguard Worker 		      tnode);						\
773*1208bc7eSAndroid Build Coastguard Worker 		    rbtn_black_set(a_type, a_field, tnode);		\
774*1208bc7eSAndroid Build Coastguard Worker 		}							\
775*1208bc7eSAndroid Build Coastguard Worker 		/* Balance restored, but rotation modified subtree    */\
776*1208bc7eSAndroid Build Coastguard Worker 		/* root, which may actually be the tree root.         */\
777*1208bc7eSAndroid Build Coastguard Worker 		if (pathp == path) {					\
778*1208bc7eSAndroid Build Coastguard Worker 		    /* Set root. */					\
779*1208bc7eSAndroid Build Coastguard Worker 		    rbtree->rbt_root = tnode;				\
780*1208bc7eSAndroid Build Coastguard Worker 		} else {						\
781*1208bc7eSAndroid Build Coastguard Worker 		    if (pathp[-1].cmp < 0) {				\
782*1208bc7eSAndroid Build Coastguard Worker 			rbtn_left_set(a_type, a_field, pathp[-1].node,	\
783*1208bc7eSAndroid Build Coastguard Worker 			  tnode);					\
784*1208bc7eSAndroid Build Coastguard Worker 		    } else {						\
785*1208bc7eSAndroid Build Coastguard Worker 			rbtn_right_set(a_type, a_field, pathp[-1].node,	\
786*1208bc7eSAndroid Build Coastguard Worker 			  tnode);					\
787*1208bc7eSAndroid Build Coastguard Worker 		    }							\
788*1208bc7eSAndroid Build Coastguard Worker 		}							\
789*1208bc7eSAndroid Build Coastguard Worker 		return;							\
790*1208bc7eSAndroid Build Coastguard Worker 	    } else if (rbtn_red_get(a_type, a_field, pathp->node)) {	\
791*1208bc7eSAndroid Build Coastguard Worker 		a_type *leftleft = rbtn_left_get(a_type, a_field, left);\
792*1208bc7eSAndroid Build Coastguard Worker 		if (leftleft != NULL && rbtn_red_get(a_type, a_field,	\
793*1208bc7eSAndroid Build Coastguard Worker 		  leftleft)) {						\
794*1208bc7eSAndroid Build Coastguard Worker 		    /*        ||                                      */\
795*1208bc7eSAndroid Build Coastguard Worker 		    /*      pathp(r)                                  */\
796*1208bc7eSAndroid Build Coastguard Worker 		    /*     /        \\                                */\
797*1208bc7eSAndroid Build Coastguard Worker 		    /*   (b)        (b)                               */\
798*1208bc7eSAndroid Build Coastguard Worker 		    /*   /                                            */\
799*1208bc7eSAndroid Build Coastguard Worker 		    /* (r)                                            */\
800*1208bc7eSAndroid Build Coastguard Worker 		    a_type *tnode;					\
801*1208bc7eSAndroid Build Coastguard Worker 		    rbtn_black_set(a_type, a_field, pathp->node);	\
802*1208bc7eSAndroid Build Coastguard Worker 		    rbtn_red_set(a_type, a_field, left);		\
803*1208bc7eSAndroid Build Coastguard Worker 		    rbtn_black_set(a_type, a_field, leftleft);		\
804*1208bc7eSAndroid Build Coastguard Worker 		    rbtn_rotate_right(a_type, a_field, pathp->node,	\
805*1208bc7eSAndroid Build Coastguard Worker 		      tnode);						\
806*1208bc7eSAndroid Build Coastguard Worker 		    /* Balance restored, but rotation modified        */\
807*1208bc7eSAndroid Build Coastguard Worker 		    /* subtree root.                                  */\
808*1208bc7eSAndroid Build Coastguard Worker 		    assert((uintptr_t)pathp > (uintptr_t)path);		\
809*1208bc7eSAndroid Build Coastguard Worker 		    if (pathp[-1].cmp < 0) {				\
810*1208bc7eSAndroid Build Coastguard Worker 			rbtn_left_set(a_type, a_field, pathp[-1].node,	\
811*1208bc7eSAndroid Build Coastguard Worker 			  tnode);					\
812*1208bc7eSAndroid Build Coastguard Worker 		    } else {						\
813*1208bc7eSAndroid Build Coastguard Worker 			rbtn_right_set(a_type, a_field, pathp[-1].node,	\
814*1208bc7eSAndroid Build Coastguard Worker 			  tnode);					\
815*1208bc7eSAndroid Build Coastguard Worker 		    }							\
816*1208bc7eSAndroid Build Coastguard Worker 		    return;						\
817*1208bc7eSAndroid Build Coastguard Worker 		} else {						\
818*1208bc7eSAndroid Build Coastguard Worker 		    /*        ||                                      */\
819*1208bc7eSAndroid Build Coastguard Worker 		    /*      pathp(r)                                  */\
820*1208bc7eSAndroid Build Coastguard Worker 		    /*     /        \\                                */\
821*1208bc7eSAndroid Build Coastguard Worker 		    /*   (b)        (b)                               */\
822*1208bc7eSAndroid Build Coastguard Worker 		    /*   /                                            */\
823*1208bc7eSAndroid Build Coastguard Worker 		    /* (b)                                            */\
824*1208bc7eSAndroid Build Coastguard Worker 		    rbtn_red_set(a_type, a_field, left);		\
825*1208bc7eSAndroid Build Coastguard Worker 		    rbtn_black_set(a_type, a_field, pathp->node);	\
826*1208bc7eSAndroid Build Coastguard Worker 		    /* Balance restored. */				\
827*1208bc7eSAndroid Build Coastguard Worker 		    return;						\
828*1208bc7eSAndroid Build Coastguard Worker 		}							\
829*1208bc7eSAndroid Build Coastguard Worker 	    } else {							\
830*1208bc7eSAndroid Build Coastguard Worker 		a_type *leftleft = rbtn_left_get(a_type, a_field, left);\
831*1208bc7eSAndroid Build Coastguard Worker 		if (leftleft != NULL && rbtn_red_get(a_type, a_field,	\
832*1208bc7eSAndroid Build Coastguard Worker 		  leftleft)) {						\
833*1208bc7eSAndroid Build Coastguard Worker 		    /*               ||                               */\
834*1208bc7eSAndroid Build Coastguard Worker 		    /*             pathp(b)                           */\
835*1208bc7eSAndroid Build Coastguard Worker 		    /*            /        \\                         */\
836*1208bc7eSAndroid Build Coastguard Worker 		    /*          (b)        (b)                        */\
837*1208bc7eSAndroid Build Coastguard Worker 		    /*          /                                     */\
838*1208bc7eSAndroid Build Coastguard Worker 		    /*        (r)                                     */\
839*1208bc7eSAndroid Build Coastguard Worker 		    a_type *tnode;					\
840*1208bc7eSAndroid Build Coastguard Worker 		    rbtn_black_set(a_type, a_field, leftleft);		\
841*1208bc7eSAndroid Build Coastguard Worker 		    rbtn_rotate_right(a_type, a_field, pathp->node,	\
842*1208bc7eSAndroid Build Coastguard Worker 		      tnode);						\
843*1208bc7eSAndroid Build Coastguard Worker 		    /* Balance restored, but rotation modified        */\
844*1208bc7eSAndroid Build Coastguard Worker 		    /* subtree root, which may actually be the tree   */\
845*1208bc7eSAndroid Build Coastguard Worker 		    /* root.                                          */\
846*1208bc7eSAndroid Build Coastguard Worker 		    if (pathp == path) {				\
847*1208bc7eSAndroid Build Coastguard Worker 			/* Set root. */					\
848*1208bc7eSAndroid Build Coastguard Worker 			rbtree->rbt_root = tnode;			\
849*1208bc7eSAndroid Build Coastguard Worker 		    } else {						\
850*1208bc7eSAndroid Build Coastguard Worker 			if (pathp[-1].cmp < 0) {			\
851*1208bc7eSAndroid Build Coastguard Worker 			    rbtn_left_set(a_type, a_field,		\
852*1208bc7eSAndroid Build Coastguard Worker 			      pathp[-1].node, tnode);			\
853*1208bc7eSAndroid Build Coastguard Worker 			} else {					\
854*1208bc7eSAndroid Build Coastguard Worker 			    rbtn_right_set(a_type, a_field,		\
855*1208bc7eSAndroid Build Coastguard Worker 			      pathp[-1].node, tnode);			\
856*1208bc7eSAndroid Build Coastguard Worker 			}						\
857*1208bc7eSAndroid Build Coastguard Worker 		    }							\
858*1208bc7eSAndroid Build Coastguard Worker 		    return;						\
859*1208bc7eSAndroid Build Coastguard Worker 		} else {						\
860*1208bc7eSAndroid Build Coastguard Worker 		    /*               ||                               */\
861*1208bc7eSAndroid Build Coastguard Worker 		    /*             pathp(b)                           */\
862*1208bc7eSAndroid Build Coastguard Worker 		    /*            /        \\                         */\
863*1208bc7eSAndroid Build Coastguard Worker 		    /*          (b)        (b)                        */\
864*1208bc7eSAndroid Build Coastguard Worker 		    /*          /                                     */\
865*1208bc7eSAndroid Build Coastguard Worker 		    /*        (b)                                     */\
866*1208bc7eSAndroid Build Coastguard Worker 		    rbtn_red_set(a_type, a_field, left);		\
867*1208bc7eSAndroid Build Coastguard Worker 		}							\
868*1208bc7eSAndroid Build Coastguard Worker 	    }								\
869*1208bc7eSAndroid Build Coastguard Worker 	}								\
870*1208bc7eSAndroid Build Coastguard Worker     }									\
871*1208bc7eSAndroid Build Coastguard Worker     /* Set root. */							\
872*1208bc7eSAndroid Build Coastguard Worker     rbtree->rbt_root = path->node;					\
873*1208bc7eSAndroid Build Coastguard Worker     assert(!rbtn_red_get(a_type, a_field, rbtree->rbt_root));		\
874*1208bc7eSAndroid Build Coastguard Worker }									\
875*1208bc7eSAndroid Build Coastguard Worker a_attr a_type *								\
876*1208bc7eSAndroid Build Coastguard Worker a_prefix##iter_recurse(a_rbt_type *rbtree, a_type *node,		\
877*1208bc7eSAndroid Build Coastguard Worker   a_type *(*cb)(a_rbt_type *, a_type *, void *), void *arg) {		\
878*1208bc7eSAndroid Build Coastguard Worker     if (node == NULL) {							\
879*1208bc7eSAndroid Build Coastguard Worker 	return NULL;							\
880*1208bc7eSAndroid Build Coastguard Worker     } else {								\
881*1208bc7eSAndroid Build Coastguard Worker 	a_type *ret;							\
882*1208bc7eSAndroid Build Coastguard Worker 	if ((ret = a_prefix##iter_recurse(rbtree, rbtn_left_get(a_type,	\
883*1208bc7eSAndroid Build Coastguard Worker 	  a_field, node), cb, arg)) != NULL || (ret = cb(rbtree, node,	\
884*1208bc7eSAndroid Build Coastguard Worker 	  arg)) != NULL) {						\
885*1208bc7eSAndroid Build Coastguard Worker 	    return ret;							\
886*1208bc7eSAndroid Build Coastguard Worker 	}								\
887*1208bc7eSAndroid Build Coastguard Worker 	return a_prefix##iter_recurse(rbtree, rbtn_right_get(a_type,	\
888*1208bc7eSAndroid Build Coastguard Worker 	  a_field, node), cb, arg);					\
889*1208bc7eSAndroid Build Coastguard Worker     }									\
890*1208bc7eSAndroid Build Coastguard Worker }									\
891*1208bc7eSAndroid Build Coastguard Worker a_attr a_type *								\
892*1208bc7eSAndroid Build Coastguard Worker a_prefix##iter_start(a_rbt_type *rbtree, a_type *start, a_type *node,	\
893*1208bc7eSAndroid Build Coastguard Worker   a_type *(*cb)(a_rbt_type *, a_type *, void *), void *arg) {		\
894*1208bc7eSAndroid Build Coastguard Worker     int cmp = a_cmp(start, node);					\
895*1208bc7eSAndroid Build Coastguard Worker     if (cmp < 0) {							\
896*1208bc7eSAndroid Build Coastguard Worker 	a_type *ret;							\
897*1208bc7eSAndroid Build Coastguard Worker 	if ((ret = a_prefix##iter_start(rbtree, start,			\
898*1208bc7eSAndroid Build Coastguard Worker 	  rbtn_left_get(a_type, a_field, node), cb, arg)) != NULL ||	\
899*1208bc7eSAndroid Build Coastguard Worker 	  (ret = cb(rbtree, node, arg)) != NULL) {			\
900*1208bc7eSAndroid Build Coastguard Worker 	    return ret;							\
901*1208bc7eSAndroid Build Coastguard Worker 	}								\
902*1208bc7eSAndroid Build Coastguard Worker 	return a_prefix##iter_recurse(rbtree, rbtn_right_get(a_type,	\
903*1208bc7eSAndroid Build Coastguard Worker 	  a_field, node), cb, arg);					\
904*1208bc7eSAndroid Build Coastguard Worker     } else if (cmp > 0) {						\
905*1208bc7eSAndroid Build Coastguard Worker 	return a_prefix##iter_start(rbtree, start,			\
906*1208bc7eSAndroid Build Coastguard Worker 	  rbtn_right_get(a_type, a_field, node), cb, arg);		\
907*1208bc7eSAndroid Build Coastguard Worker     } else {								\
908*1208bc7eSAndroid Build Coastguard Worker 	a_type *ret;							\
909*1208bc7eSAndroid Build Coastguard Worker 	if ((ret = cb(rbtree, node, arg)) != NULL) {			\
910*1208bc7eSAndroid Build Coastguard Worker 	    return ret;							\
911*1208bc7eSAndroid Build Coastguard Worker 	}								\
912*1208bc7eSAndroid Build Coastguard Worker 	return a_prefix##iter_recurse(rbtree, rbtn_right_get(a_type,	\
913*1208bc7eSAndroid Build Coastguard Worker 	  a_field, node), cb, arg);					\
914*1208bc7eSAndroid Build Coastguard Worker     }									\
915*1208bc7eSAndroid Build Coastguard Worker }									\
916*1208bc7eSAndroid Build Coastguard Worker a_attr a_type *								\
917*1208bc7eSAndroid Build Coastguard Worker a_prefix##iter(a_rbt_type *rbtree, a_type *start, a_type *(*cb)(	\
918*1208bc7eSAndroid Build Coastguard Worker   a_rbt_type *, a_type *, void *), void *arg) {				\
919*1208bc7eSAndroid Build Coastguard Worker     a_type *ret;							\
920*1208bc7eSAndroid Build Coastguard Worker     if (start != NULL) {						\
921*1208bc7eSAndroid Build Coastguard Worker 	ret = a_prefix##iter_start(rbtree, start, rbtree->rbt_root,	\
922*1208bc7eSAndroid Build Coastguard Worker 	  cb, arg);							\
923*1208bc7eSAndroid Build Coastguard Worker     } else {								\
924*1208bc7eSAndroid Build Coastguard Worker 	ret = a_prefix##iter_recurse(rbtree, rbtree->rbt_root, cb, arg);\
925*1208bc7eSAndroid Build Coastguard Worker     }									\
926*1208bc7eSAndroid Build Coastguard Worker     return ret;								\
927*1208bc7eSAndroid Build Coastguard Worker }									\
928*1208bc7eSAndroid Build Coastguard Worker a_attr a_type *								\
929*1208bc7eSAndroid Build Coastguard Worker a_prefix##reverse_iter_recurse(a_rbt_type *rbtree, a_type *node,	\
930*1208bc7eSAndroid Build Coastguard Worker   a_type *(*cb)(a_rbt_type *, a_type *, void *), void *arg) {		\
931*1208bc7eSAndroid Build Coastguard Worker     if (node == NULL) {							\
932*1208bc7eSAndroid Build Coastguard Worker 	return NULL;							\
933*1208bc7eSAndroid Build Coastguard Worker     } else {								\
934*1208bc7eSAndroid Build Coastguard Worker 	a_type *ret;							\
935*1208bc7eSAndroid Build Coastguard Worker 	if ((ret = a_prefix##reverse_iter_recurse(rbtree,		\
936*1208bc7eSAndroid Build Coastguard Worker 	  rbtn_right_get(a_type, a_field, node), cb, arg)) != NULL ||	\
937*1208bc7eSAndroid Build Coastguard Worker 	  (ret = cb(rbtree, node, arg)) != NULL) {			\
938*1208bc7eSAndroid Build Coastguard Worker 	    return ret;							\
939*1208bc7eSAndroid Build Coastguard Worker 	}								\
940*1208bc7eSAndroid Build Coastguard Worker 	return a_prefix##reverse_iter_recurse(rbtree,			\
941*1208bc7eSAndroid Build Coastguard Worker 	  rbtn_left_get(a_type, a_field, node), cb, arg);		\
942*1208bc7eSAndroid Build Coastguard Worker     }									\
943*1208bc7eSAndroid Build Coastguard Worker }									\
944*1208bc7eSAndroid Build Coastguard Worker a_attr a_type *								\
945*1208bc7eSAndroid Build Coastguard Worker a_prefix##reverse_iter_start(a_rbt_type *rbtree, a_type *start,		\
946*1208bc7eSAndroid Build Coastguard Worker   a_type *node, a_type *(*cb)(a_rbt_type *, a_type *, void *),		\
947*1208bc7eSAndroid Build Coastguard Worker   void *arg) {								\
948*1208bc7eSAndroid Build Coastguard Worker     int cmp = a_cmp(start, node);					\
949*1208bc7eSAndroid Build Coastguard Worker     if (cmp > 0) {							\
950*1208bc7eSAndroid Build Coastguard Worker 	a_type *ret;							\
951*1208bc7eSAndroid Build Coastguard Worker 	if ((ret = a_prefix##reverse_iter_start(rbtree, start,		\
952*1208bc7eSAndroid Build Coastguard Worker 	  rbtn_right_get(a_type, a_field, node), cb, arg)) != NULL ||	\
953*1208bc7eSAndroid Build Coastguard Worker 	  (ret = cb(rbtree, node, arg)) != NULL) {			\
954*1208bc7eSAndroid Build Coastguard Worker 	    return ret;							\
955*1208bc7eSAndroid Build Coastguard Worker 	}								\
956*1208bc7eSAndroid Build Coastguard Worker 	return a_prefix##reverse_iter_recurse(rbtree,			\
957*1208bc7eSAndroid Build Coastguard Worker 	  rbtn_left_get(a_type, a_field, node), cb, arg);		\
958*1208bc7eSAndroid Build Coastguard Worker     } else if (cmp < 0) {						\
959*1208bc7eSAndroid Build Coastguard Worker 	return a_prefix##reverse_iter_start(rbtree, start,		\
960*1208bc7eSAndroid Build Coastguard Worker 	  rbtn_left_get(a_type, a_field, node), cb, arg);		\
961*1208bc7eSAndroid Build Coastguard Worker     } else {								\
962*1208bc7eSAndroid Build Coastguard Worker 	a_type *ret;							\
963*1208bc7eSAndroid Build Coastguard Worker 	if ((ret = cb(rbtree, node, arg)) != NULL) {			\
964*1208bc7eSAndroid Build Coastguard Worker 	    return ret;							\
965*1208bc7eSAndroid Build Coastguard Worker 	}								\
966*1208bc7eSAndroid Build Coastguard Worker 	return a_prefix##reverse_iter_recurse(rbtree,			\
967*1208bc7eSAndroid Build Coastguard Worker 	  rbtn_left_get(a_type, a_field, node), cb, arg);		\
968*1208bc7eSAndroid Build Coastguard Worker     }									\
969*1208bc7eSAndroid Build Coastguard Worker }									\
970*1208bc7eSAndroid Build Coastguard Worker a_attr a_type *								\
971*1208bc7eSAndroid Build Coastguard Worker a_prefix##reverse_iter(a_rbt_type *rbtree, a_type *start,		\
972*1208bc7eSAndroid Build Coastguard Worker   a_type *(*cb)(a_rbt_type *, a_type *, void *), void *arg) {		\
973*1208bc7eSAndroid Build Coastguard Worker     a_type *ret;							\
974*1208bc7eSAndroid Build Coastguard Worker     if (start != NULL) {						\
975*1208bc7eSAndroid Build Coastguard Worker 	ret = a_prefix##reverse_iter_start(rbtree, start,		\
976*1208bc7eSAndroid Build Coastguard Worker 	  rbtree->rbt_root, cb, arg);					\
977*1208bc7eSAndroid Build Coastguard Worker     } else {								\
978*1208bc7eSAndroid Build Coastguard Worker 	ret = a_prefix##reverse_iter_recurse(rbtree, rbtree->rbt_root,	\
979*1208bc7eSAndroid Build Coastguard Worker 	  cb, arg);							\
980*1208bc7eSAndroid Build Coastguard Worker     }									\
981*1208bc7eSAndroid Build Coastguard Worker     return ret;								\
982*1208bc7eSAndroid Build Coastguard Worker }									\
983*1208bc7eSAndroid Build Coastguard Worker a_attr void								\
984*1208bc7eSAndroid Build Coastguard Worker a_prefix##destroy_recurse(a_rbt_type *rbtree, a_type *node, void (*cb)(	\
985*1208bc7eSAndroid Build Coastguard Worker   a_type *, void *), void *arg) {					\
986*1208bc7eSAndroid Build Coastguard Worker     if (node == NULL) {							\
987*1208bc7eSAndroid Build Coastguard Worker 	return;								\
988*1208bc7eSAndroid Build Coastguard Worker     }									\
989*1208bc7eSAndroid Build Coastguard Worker     a_prefix##destroy_recurse(rbtree, rbtn_left_get(a_type, a_field,	\
990*1208bc7eSAndroid Build Coastguard Worker       node), cb, arg);							\
991*1208bc7eSAndroid Build Coastguard Worker     rbtn_left_set(a_type, a_field, (node), NULL);			\
992*1208bc7eSAndroid Build Coastguard Worker     a_prefix##destroy_recurse(rbtree, rbtn_right_get(a_type, a_field,	\
993*1208bc7eSAndroid Build Coastguard Worker       node), cb, arg);							\
994*1208bc7eSAndroid Build Coastguard Worker     rbtn_right_set(a_type, a_field, (node), NULL);			\
995*1208bc7eSAndroid Build Coastguard Worker     if (cb) {								\
996*1208bc7eSAndroid Build Coastguard Worker 	cb(node, arg);							\
997*1208bc7eSAndroid Build Coastguard Worker     }									\
998*1208bc7eSAndroid Build Coastguard Worker }									\
999*1208bc7eSAndroid Build Coastguard Worker a_attr void								\
1000*1208bc7eSAndroid Build Coastguard Worker a_prefix##destroy(a_rbt_type *rbtree, void (*cb)(a_type *, void *),	\
1001*1208bc7eSAndroid Build Coastguard Worker   void *arg) {								\
1002*1208bc7eSAndroid Build Coastguard Worker     a_prefix##destroy_recurse(rbtree, rbtree->rbt_root, cb, arg);	\
1003*1208bc7eSAndroid Build Coastguard Worker     rbtree->rbt_root = NULL;						\
1004*1208bc7eSAndroid Build Coastguard Worker }
1005*1208bc7eSAndroid Build Coastguard Worker 
1006*1208bc7eSAndroid Build Coastguard Worker #endif /* RB_H_ */
1007