Coverage Report

Created: 2026-03-12 06:35

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/CMake/Utilities/cmlibuv/include/uv/tree.h
Line
Count
Source
1
/*-
2
 * Copyright 2002 Niels Provos <provos@citi.umich.edu>
3
 * All rights reserved.
4
 *
5
 * Redistribution and use in source and binary forms, with or without
6
 * modification, are permitted provided that the following conditions
7
 * are met:
8
 * 1. Redistributions of source code must retain the above copyright
9
 *    notice, this list of conditions and the following disclaimer.
10
 * 2. Redistributions in binary form must reproduce the above copyright
11
 *    notice, this list of conditions and the following disclaimer in the
12
 *    documentation and/or other materials provided with the distribution.
13
 *
14
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
15
 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
16
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
17
 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
18
 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
19
 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
20
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
21
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
23
 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24
 */
25
26
#ifndef  UV_TREE_H_
27
#define  UV_TREE_H_
28
29
#ifndef UV__UNUSED
30
# if __GNUC__
31
#  define UV__UNUSED __attribute__((unused))
32
# else
33
#  define UV__UNUSED
34
# endif
35
#endif
36
37
/*
38
 * This file defines data structures for red-black trees.
39
 * A red-black tree is a binary search tree with the node color as an
40
 * extra attribute.  It fulfills a set of conditions:
41
 *  - every search path from the root to a leaf consists of the
42
 *    same number of black nodes,
43
 *  - each red node (except for the root) has a black parent,
44
 *  - each leaf node is black.
45
 *
46
 * Every operation on a red-black tree is bounded as O(lg n).
47
 * The maximum height of a red-black tree is 2lg (n+1).
48
 */
49
50
/* Macros that define a red-black tree */
51
#define RB_HEAD(name, type)                                                   \
52
struct name {                                                                 \
53
  struct type *rbh_root; /* root of the tree */                               \
54
}
55
56
#define RB_INITIALIZER(root)                                                  \
57
  { NULL }
58
59
#define RB_INIT(root) do {                                                    \
60
  (root)->rbh_root = NULL;                                                    \
61
} while (/*CONSTCOND*/ 0)
62
63
0
#define RB_BLACK  0
64
0
#define RB_RED    1
65
#define RB_ENTRY(type)                                                        \
66
struct {                                                                      \
67
  struct type *rbe_left;        /* left element */                            \
68
  struct type *rbe_right;       /* right element */                           \
69
  struct type *rbe_parent;      /* parent element */                          \
70
  int rbe_color;                /* node color */                              \
71
}
72
73
0
#define RB_LEFT(elm, field)     (elm)->field.rbe_left
74
0
#define RB_RIGHT(elm, field)    (elm)->field.rbe_right
75
0
#define RB_PARENT(elm, field)   (elm)->field.rbe_parent
76
0
#define RB_COLOR(elm, field)    (elm)->field.rbe_color
77
0
#define RB_ROOT(head)           (head)->rbh_root
78
#define RB_EMPTY(head)          (RB_ROOT(head) == NULL)
79
80
0
#define RB_SET(elm, parent, field) do {                                       \
81
0
  RB_PARENT(elm, field) = parent;                                             \
82
0
  RB_LEFT(elm, field) = RB_RIGHT(elm, field) = NULL;                          \
83
0
  RB_COLOR(elm, field) = RB_RED;                                              \
84
0
} while (/*CONSTCOND*/ 0)
85
86
0
#define RB_SET_BLACKRED(black, red, field) do {                               \
87
0
  RB_COLOR(black, field) = RB_BLACK;                                          \
88
0
  RB_COLOR(red, field) = RB_RED;                                              \
89
0
} while (/*CONSTCOND*/ 0)
90
91
#ifndef RB_AUGMENT
92
0
#define RB_AUGMENT(x)  do {} while (0)
93
#endif
94
95
0
#define RB_ROTATE_LEFT(head, elm, tmp, field) do {                            \
96
0
  (tmp) = RB_RIGHT(elm, field);                                               \
97
0
  if ((RB_RIGHT(elm, field) = RB_LEFT(tmp, field)) != NULL) {                 \
98
0
    RB_PARENT(RB_LEFT(tmp, field), field) = (elm);                            \
99
0
  }                                                                           \
100
0
  RB_AUGMENT(elm);                                                            \
101
0
  if ((RB_PARENT(tmp, field) = RB_PARENT(elm, field)) != NULL) {              \
102
0
    if ((elm) == RB_LEFT(RB_PARENT(elm, field), field))                       \
103
0
      RB_LEFT(RB_PARENT(elm, field), field) = (tmp);                          \
104
0
    else                                                                      \
105
0
      RB_RIGHT(RB_PARENT(elm, field), field) = (tmp);                         \
106
0
  } else                                                                      \
107
0
    (head)->rbh_root = (tmp);                                                 \
108
0
  RB_LEFT(tmp, field) = (elm);                                                \
109
0
  RB_PARENT(elm, field) = (tmp);                                              \
110
0
  RB_AUGMENT(tmp);                                                            \
111
0
  if ((RB_PARENT(tmp, field)))                                                \
112
0
    RB_AUGMENT(RB_PARENT(tmp, field));                                        \
113
0
} while (/*CONSTCOND*/ 0)
114
115
0
#define RB_ROTATE_RIGHT(head, elm, tmp, field) do {                           \
116
0
  (tmp) = RB_LEFT(elm, field);                                                \
117
0
  if ((RB_LEFT(elm, field) = RB_RIGHT(tmp, field)) != NULL) {                 \
118
0
    RB_PARENT(RB_RIGHT(tmp, field), field) = (elm);                           \
119
0
  }                                                                           \
120
0
  RB_AUGMENT(elm);                                                            \
121
0
  if ((RB_PARENT(tmp, field) = RB_PARENT(elm, field)) != NULL) {              \
122
0
    if ((elm) == RB_LEFT(RB_PARENT(elm, field), field))                       \
123
0
      RB_LEFT(RB_PARENT(elm, field), field) = (tmp);                          \
124
0
    else                                                                      \
125
0
      RB_RIGHT(RB_PARENT(elm, field), field) = (tmp);                         \
126
0
  } else                                                                      \
127
0
    (head)->rbh_root = (tmp);                                                 \
128
0
  RB_RIGHT(tmp, field) = (elm);                                               \
129
0
  RB_PARENT(elm, field) = (tmp);                                              \
130
0
  RB_AUGMENT(tmp);                                                            \
131
0
  if ((RB_PARENT(tmp, field)))                                                \
132
0
    RB_AUGMENT(RB_PARENT(tmp, field));                                        \
133
0
} while (/*CONSTCOND*/ 0)
134
135
/* Generates prototypes and inline functions */
136
#define  RB_PROTOTYPE(name, type, field, cmp)                                 \
137
  RB_PROTOTYPE_INTERNAL(name, type, field, cmp,)
138
#define  RB_PROTOTYPE_STATIC(name, type, field, cmp)                          \
139
  RB_PROTOTYPE_INTERNAL(name, type, field, cmp, UV__UNUSED static)
140
#define RB_PROTOTYPE_INTERNAL(name, type, field, cmp, attr)                   \
141
attr void name##_RB_INSERT_COLOR(struct name *, struct type *);               \
142
attr void name##_RB_REMOVE_COLOR(struct name *, struct type *, struct type *);\
143
attr struct type *name##_RB_REMOVE(struct name *, struct type *);             \
144
attr struct type *name##_RB_INSERT(struct name *, struct type *);             \
145
attr struct type *name##_RB_FIND(struct name *, struct type *);               \
146
attr struct type *name##_RB_NFIND(struct name *, struct type *);              \
147
attr struct type *name##_RB_NEXT(struct type *);                              \
148
attr struct type *name##_RB_PREV(struct type *);                              \
149
attr struct type *name##_RB_MINMAX(struct name *, int);                       \
150
                                                                              \
151
152
/* Main rb operation.
153
 * Moves node close to the key of elm to top
154
 */
155
#define  RB_GENERATE(name, type, field, cmp)                                  \
156
  RB_GENERATE_INTERNAL(name, type, field, cmp,)
157
#define  RB_GENERATE_STATIC(name, type, field, cmp)                           \
158
  RB_GENERATE_INTERNAL(name, type, field, cmp, UV__UNUSED static)
159
#define RB_GENERATE_INTERNAL(name, type, field, cmp, attr)                    \
160
attr void                                                                     \
161
0
name##_RB_INSERT_COLOR(struct name *head, struct type *elm)                   \
162
0
{                                                                             \
163
0
  struct type *parent, *gparent, *tmp;                                        \
164
0
  while ((parent = RB_PARENT(elm, field)) != NULL &&                          \
165
0
      RB_COLOR(parent, field) == RB_RED) {                                    \
166
0
    gparent = RB_PARENT(parent, field);                                       \
167
0
    if (parent == RB_LEFT(gparent, field)) {                                  \
168
0
      tmp = RB_RIGHT(gparent, field);                                         \
169
0
      if (tmp && RB_COLOR(tmp, field) == RB_RED) {                            \
170
0
        RB_COLOR(tmp, field) = RB_BLACK;                                      \
171
0
        RB_SET_BLACKRED(parent, gparent, field);                              \
172
0
        elm = gparent;                                                        \
173
0
        continue;                                                             \
174
0
      }                                                                       \
175
0
      if (RB_RIGHT(parent, field) == elm) {                                   \
176
0
        RB_ROTATE_LEFT(head, parent, tmp, field);                             \
177
0
        tmp = parent;                                                         \
178
0
        parent = elm;                                                         \
179
0
        elm = tmp;                                                            \
180
0
      }                                                                       \
181
0
      RB_SET_BLACKRED(parent, gparent, field);                                \
182
0
      RB_ROTATE_RIGHT(head, gparent, tmp, field);                             \
183
0
    } else {                                                                  \
184
0
      tmp = RB_LEFT(gparent, field);                                          \
185
0
      if (tmp && RB_COLOR(tmp, field) == RB_RED) {                            \
186
0
        RB_COLOR(tmp, field) = RB_BLACK;                                      \
187
0
        RB_SET_BLACKRED(parent, gparent, field);                              \
188
0
        elm = gparent;                                                        \
189
0
        continue;                                                             \
190
0
      }                                                                       \
191
0
      if (RB_LEFT(parent, field) == elm) {                                    \
192
0
        RB_ROTATE_RIGHT(head, parent, tmp, field);                            \
193
0
        tmp = parent;                                                         \
194
0
        parent = elm;                                                         \
195
0
        elm = tmp;                                                            \
196
0
      }                                                                       \
197
0
      RB_SET_BLACKRED(parent, gparent, field);                                \
198
0
      RB_ROTATE_LEFT(head, gparent, tmp, field);                              \
199
0
    }                                                                         \
200
0
  }                                                                           \
201
0
  RB_COLOR(head->rbh_root, field) = RB_BLACK;                                 \
202
0
}                                                                             \
203
                                                                              \
204
attr void                                                                     \
205
name##_RB_REMOVE_COLOR(struct name *head, struct type *parent,                \
206
0
    struct type *elm)                                                         \
207
0
{                                                                             \
208
0
  struct type *tmp;                                                           \
209
0
  while ((elm == NULL || RB_COLOR(elm, field) == RB_BLACK) &&                 \
210
0
      elm != RB_ROOT(head)) {                                                 \
211
0
    if (RB_LEFT(parent, field) == elm) {                                      \
212
0
      tmp = RB_RIGHT(parent, field);                                          \
213
0
      if (RB_COLOR(tmp, field) == RB_RED) {                                   \
214
0
        RB_SET_BLACKRED(tmp, parent, field);                                  \
215
0
        RB_ROTATE_LEFT(head, parent, tmp, field);                             \
216
0
        tmp = RB_RIGHT(parent, field);                                        \
217
0
      }                                                                       \
218
0
      if ((RB_LEFT(tmp, field) == NULL ||                                     \
219
0
          RB_COLOR(RB_LEFT(tmp, field), field) == RB_BLACK) &&                \
220
0
          (RB_RIGHT(tmp, field) == NULL ||                                    \
221
0
          RB_COLOR(RB_RIGHT(tmp, field), field) == RB_BLACK)) {               \
222
0
        RB_COLOR(tmp, field) = RB_RED;                                        \
223
0
        elm = parent;                                                         \
224
0
        parent = RB_PARENT(elm, field);                                       \
225
0
      } else {                                                                \
226
0
        if (RB_RIGHT(tmp, field) == NULL ||                                   \
227
0
            RB_COLOR(RB_RIGHT(tmp, field), field) == RB_BLACK) {              \
228
0
          struct type *oleft;                                                 \
229
0
          if ((oleft = RB_LEFT(tmp, field))                                   \
230
0
              != NULL)                                                        \
231
0
            RB_COLOR(oleft, field) = RB_BLACK;                                \
232
0
          RB_COLOR(tmp, field) = RB_RED;                                      \
233
0
          RB_ROTATE_RIGHT(head, tmp, oleft, field);                           \
234
0
          tmp = RB_RIGHT(parent, field);                                      \
235
0
        }                                                                     \
236
0
        RB_COLOR(tmp, field) = RB_COLOR(parent, field);                       \
237
0
        RB_COLOR(parent, field) = RB_BLACK;                                   \
238
0
        if (RB_RIGHT(tmp, field))                                             \
239
0
          RB_COLOR(RB_RIGHT(tmp, field), field) = RB_BLACK;                   \
240
0
        RB_ROTATE_LEFT(head, parent, tmp, field);                             \
241
0
        elm = RB_ROOT(head);                                                  \
242
0
        break;                                                                \
243
0
      }                                                                       \
244
0
    } else {                                                                  \
245
0
      tmp = RB_LEFT(parent, field);                                           \
246
0
      if (RB_COLOR(tmp, field) == RB_RED) {                                   \
247
0
        RB_SET_BLACKRED(tmp, parent, field);                                  \
248
0
        RB_ROTATE_RIGHT(head, parent, tmp, field);                            \
249
0
        tmp = RB_LEFT(parent, field);                                         \
250
0
      }                                                                       \
251
0
      if ((RB_LEFT(tmp, field) == NULL ||                                     \
252
0
          RB_COLOR(RB_LEFT(tmp, field), field) == RB_BLACK) &&                \
253
0
          (RB_RIGHT(tmp, field) == NULL ||                                    \
254
0
          RB_COLOR(RB_RIGHT(tmp, field), field) == RB_BLACK)) {               \
255
0
        RB_COLOR(tmp, field) = RB_RED;                                        \
256
0
        elm = parent;                                                         \
257
0
        parent = RB_PARENT(elm, field);                                       \
258
0
      } else {                                                                \
259
0
        if (RB_LEFT(tmp, field) == NULL ||                                    \
260
0
            RB_COLOR(RB_LEFT(tmp, field), field) == RB_BLACK) {               \
261
0
          struct type *oright;                                                \
262
0
          if ((oright = RB_RIGHT(tmp, field))                                 \
263
0
              != NULL)                                                        \
264
0
            RB_COLOR(oright, field) = RB_BLACK;                               \
265
0
          RB_COLOR(tmp, field) = RB_RED;                                      \
266
0
          RB_ROTATE_LEFT(head, tmp, oright, field);                           \
267
0
          tmp = RB_LEFT(parent, field);                                       \
268
0
        }                                                                     \
269
0
        RB_COLOR(tmp, field) = RB_COLOR(parent, field);                       \
270
0
        RB_COLOR(parent, field) = RB_BLACK;                                   \
271
0
        if (RB_LEFT(tmp, field))                                              \
272
0
          RB_COLOR(RB_LEFT(tmp, field), field) = RB_BLACK;                    \
273
0
        RB_ROTATE_RIGHT(head, parent, tmp, field);                            \
274
0
        elm = RB_ROOT(head);                                                  \
275
0
        break;                                                                \
276
0
      }                                                                       \
277
0
    }                                                                         \
278
0
  }                                                                           \
279
0
  if (elm)                                                                    \
280
0
    RB_COLOR(elm, field) = RB_BLACK;                                          \
281
0
}                                                                             \
282
                                                                              \
283
attr struct type *                                                            \
284
0
name##_RB_REMOVE(struct name *head, struct type *elm)                         \
285
0
{                                                                             \
286
0
  struct type *child, *parent, *old = elm;                                    \
287
0
  int color;                                                                  \
288
0
  if (RB_LEFT(elm, field) == NULL)                                            \
289
0
    child = RB_RIGHT(elm, field);                                             \
290
0
  else if (RB_RIGHT(elm, field) == NULL)                                      \
291
0
    child = RB_LEFT(elm, field);                                              \
292
0
  else {                                                                      \
293
0
    struct type *left;                                                        \
294
0
    elm = RB_RIGHT(elm, field);                                               \
295
0
    while ((left = RB_LEFT(elm, field)) != NULL)                              \
296
0
      elm = left;                                                             \
297
0
    child = RB_RIGHT(elm, field);                                             \
298
0
    parent = RB_PARENT(elm, field);                                           \
299
0
    color = RB_COLOR(elm, field);                                             \
300
0
    if (child)                                                                \
301
0
      RB_PARENT(child, field) = parent;                                       \
302
0
    if (parent) {                                                             \
303
0
      if (RB_LEFT(parent, field) == elm)                                      \
304
0
        RB_LEFT(parent, field) = child;                                       \
305
0
      else                                                                    \
306
0
        RB_RIGHT(parent, field) = child;                                      \
307
0
      RB_AUGMENT(parent);                                                     \
308
0
    } else                                                                    \
309
0
      RB_ROOT(head) = child;                                                  \
310
0
    if (RB_PARENT(elm, field) == old)                                         \
311
0
      parent = elm;                                                           \
312
0
    (elm)->field = (old)->field;                                              \
313
0
    if (RB_PARENT(old, field)) {                                              \
314
0
      if (RB_LEFT(RB_PARENT(old, field), field) == old)                       \
315
0
        RB_LEFT(RB_PARENT(old, field), field) = elm;                          \
316
0
      else                                                                    \
317
0
        RB_RIGHT(RB_PARENT(old, field), field) = elm;                         \
318
0
      RB_AUGMENT(RB_PARENT(old, field));                                      \
319
0
    } else                                                                    \
320
0
      RB_ROOT(head) = elm;                                                    \
321
0
    RB_PARENT(RB_LEFT(old, field), field) = elm;                              \
322
0
    if (RB_RIGHT(old, field))                                                 \
323
0
      RB_PARENT(RB_RIGHT(old, field), field) = elm;                           \
324
0
    if (parent) {                                                             \
325
0
      left = parent;                                                          \
326
0
      do {                                                                    \
327
0
        RB_AUGMENT(left);                                                     \
328
0
      } while ((left = RB_PARENT(left, field)) != NULL);                      \
329
0
    }                                                                         \
330
0
    goto color;                                                               \
331
0
  }                                                                           \
332
0
  parent = RB_PARENT(elm, field);                                             \
333
0
  color = RB_COLOR(elm, field);                                               \
334
0
  if (child)                                                                  \
335
0
    RB_PARENT(child, field) = parent;                                         \
336
0
  if (parent) {                                                               \
337
0
    if (RB_LEFT(parent, field) == elm)                                        \
338
0
      RB_LEFT(parent, field) = child;                                         \
339
0
    else                                                                      \
340
0
      RB_RIGHT(parent, field) = child;                                        \
341
0
    RB_AUGMENT(parent);                                                       \
342
0
  } else                                                                      \
343
0
    RB_ROOT(head) = child;                                                    \
344
0
color:                                                                        \
345
0
  if (color == RB_BLACK)                                                      \
346
0
    name##_RB_REMOVE_COLOR(head, parent, child);                              \
347
0
  return (old);                                                               \
348
0
}                                                                             \
349
                                                                              \
350
/* Inserts a node into the RB tree */                                         \
351
attr struct type *                                                            \
352
0
name##_RB_INSERT(struct name *head, struct type *elm)                         \
353
0
{                                                                             \
354
0
  struct type *tmp;                                                           \
355
0
  struct type *parent = NULL;                                                 \
356
0
  int comp = 0;                                                               \
357
0
  tmp = RB_ROOT(head);                                                        \
358
0
  while (tmp) {                                                               \
359
0
    parent = tmp;                                                             \
360
0
    comp = (cmp)(elm, parent);                                                \
361
0
    if (comp < 0)                                                             \
362
0
      tmp = RB_LEFT(tmp, field);                                              \
363
0
    else if (comp > 0)                                                        \
364
0
      tmp = RB_RIGHT(tmp, field);                                             \
365
0
    else                                                                      \
366
0
      return (tmp);                                                           \
367
0
  }                                                                           \
368
0
  RB_SET(elm, parent, field);                                                 \
369
0
  if (parent != NULL) {                                                       \
370
0
    if (comp < 0)                                                             \
371
0
      RB_LEFT(parent, field) = elm;                                           \
372
0
    else                                                                      \
373
0
      RB_RIGHT(parent, field) = elm;                                          \
374
0
    RB_AUGMENT(parent);                                                       \
375
0
  } else                                                                      \
376
0
    RB_ROOT(head) = elm;                                                      \
377
0
  name##_RB_INSERT_COLOR(head, elm);                                          \
378
0
  return (NULL);                                                              \
379
0
}                                                                             \
380
                                                                              \
381
/* Finds the node with the same key as elm */                                 \
382
attr struct type *                                                            \
383
0
name##_RB_FIND(struct name *head, struct type *elm)                           \
384
0
{                                                                             \
385
0
  struct type *tmp = RB_ROOT(head);                                           \
386
0
  int comp;                                                                   \
387
0
  while (tmp) {                                                               \
388
0
    comp = cmp(elm, tmp);                                                     \
389
0
    if (comp < 0)                                                             \
390
0
      tmp = RB_LEFT(tmp, field);                                              \
391
0
    else if (comp > 0)                                                        \
392
0
      tmp = RB_RIGHT(tmp, field);                                             \
393
0
    else                                                                      \
394
0
      return (tmp);                                                           \
395
0
  }                                                                           \
396
0
  return (NULL);                                                              \
397
0
}                                                                             \
398
                                                                              \
399
/* Finds the first node greater than or equal to the search key */            \
400
attr struct type *                                                            \
401
0
name##_RB_NFIND(struct name *head, struct type *elm)                          \
402
0
{                                                                             \
403
0
  struct type *tmp = RB_ROOT(head);                                           \
404
0
  struct type *res = NULL;                                                    \
405
0
  int comp;                                                                   \
406
0
  while (tmp) {                                                               \
407
0
    comp = cmp(elm, tmp);                                                     \
408
0
    if (comp < 0) {                                                           \
409
0
      res = tmp;                                                              \
410
0
      tmp = RB_LEFT(tmp, field);                                              \
411
0
    }                                                                         \
412
0
    else if (comp > 0)                                                        \
413
0
      tmp = RB_RIGHT(tmp, field);                                             \
414
0
    else                                                                      \
415
0
      return (tmp);                                                           \
416
0
  }                                                                           \
417
0
  return (res);                                                               \
418
0
}                                                                             \
419
                                                                              \
420
/* ARGSUSED */                                                                \
421
attr struct type *                                                            \
422
0
name##_RB_NEXT(struct type *elm)                                              \
423
0
{                                                                             \
424
0
  if (RB_RIGHT(elm, field)) {                                                 \
425
0
    elm = RB_RIGHT(elm, field);                                               \
426
0
    while (RB_LEFT(elm, field))                                               \
427
0
      elm = RB_LEFT(elm, field);                                              \
428
0
  } else {                                                                    \
429
0
    if (RB_PARENT(elm, field) &&                                              \
430
0
        (elm == RB_LEFT(RB_PARENT(elm, field), field)))                       \
431
0
      elm = RB_PARENT(elm, field);                                            \
432
0
    else {                                                                    \
433
0
      while (RB_PARENT(elm, field) &&                                         \
434
0
          (elm == RB_RIGHT(RB_PARENT(elm, field), field)))                    \
435
0
        elm = RB_PARENT(elm, field);                                          \
436
0
      elm = RB_PARENT(elm, field);                                            \
437
0
    }                                                                         \
438
0
  }                                                                           \
439
0
  return (elm);                                                               \
440
0
}                                                                             \
Unexecuted instantiation: signal.c:uv__signal_tree_s_RB_NEXT
Unexecuted instantiation: linux.c:watcher_root_RB_NEXT
441
                                                                              \
442
/* ARGSUSED */                                                                \
443
attr struct type *                                                            \
444
0
name##_RB_PREV(struct type *elm)                                              \
445
0
{                                                                             \
446
0
  if (RB_LEFT(elm, field)) {                                                  \
447
0
    elm = RB_LEFT(elm, field);                                                \
448
0
    while (RB_RIGHT(elm, field))                                              \
449
0
      elm = RB_RIGHT(elm, field);                                             \
450
0
  } else {                                                                    \
451
0
    if (RB_PARENT(elm, field) &&                                              \
452
0
        (elm == RB_RIGHT(RB_PARENT(elm, field), field)))                      \
453
0
      elm = RB_PARENT(elm, field);                                            \
454
0
    else {                                                                    \
455
0
      while (RB_PARENT(elm, field) &&                                         \
456
0
          (elm == RB_LEFT(RB_PARENT(elm, field), field)))                     \
457
0
        elm = RB_PARENT(elm, field);                                          \
458
0
      elm = RB_PARENT(elm, field);                                            \
459
0
    }                                                                         \
460
0
  }                                                                           \
461
0
  return (elm);                                                               \
462
0
}                                                                             \
Unexecuted instantiation: signal.c:uv__signal_tree_s_RB_PREV
Unexecuted instantiation: linux.c:watcher_root_RB_PREV
463
                                                                              \
464
attr struct type *                                                            \
465
0
name##_RB_MINMAX(struct name *head, int val)                                  \
466
0
{                                                                             \
467
0
  struct type *tmp = RB_ROOT(head);                                           \
468
0
  struct type *parent = NULL;                                                 \
469
0
  while (tmp) {                                                               \
470
0
    parent = tmp;                                                             \
471
0
    if (val < 0)                                                              \
472
0
      tmp = RB_LEFT(tmp, field);                                              \
473
0
    else                                                                      \
474
0
      tmp = RB_RIGHT(tmp, field);                                             \
475
0
  }                                                                           \
476
0
  return (parent);                                                            \
477
0
}
478
479
0
#define RB_NEGINF   -1
480
#define RB_INF      1
481
482
0
#define RB_INSERT(name, x, y)   name##_RB_INSERT(x, y)
483
0
#define RB_REMOVE(name, x, y)   name##_RB_REMOVE(x, y)
484
0
#define RB_FIND(name, x, y)     name##_RB_FIND(x, y)
485
0
#define RB_NFIND(name, x, y)    name##_RB_NFIND(x, y)
486
0
#define RB_NEXT(name, x)        name##_RB_NEXT(x)
487
#define RB_PREV(name, x)        name##_RB_PREV(x)
488
0
#define RB_MIN(name, x)         name##_RB_MINMAX(x, RB_NEGINF)
489
#define RB_MAX(name, x)         name##_RB_MINMAX(x, RB_INF)
490
491
#define RB_FOREACH(x, name, head)                                             \
492
  for ((x) = RB_MIN(name, head);                                              \
493
       (x) != NULL;                                                           \
494
       (x) = name##_RB_NEXT(x))
495
496
#define RB_FOREACH_FROM(x, name, y)                                           \
497
  for ((x) = (y);                                                             \
498
      ((x) != NULL) && ((y) = name##_RB_NEXT(x), (x) != NULL);                \
499
       (x) = (y))
500
501
#define RB_FOREACH_SAFE(x, name, head, y)                                     \
502
0
  for ((x) = RB_MIN(name, head);                                              \
503
0
      ((x) != NULL) && ((y) = name##_RB_NEXT(x), (x) != NULL);                \
504
0
       (x) = (y))
505
506
#define RB_FOREACH_REVERSE(x, name, head)                                     \
507
  for ((x) = RB_MAX(name, head);                                              \
508
       (x) != NULL;                                                           \
509
       (x) = name##_RB_PREV(x))
510
511
#define RB_FOREACH_REVERSE_FROM(x, name, y)                                   \
512
  for ((x) = (y);                                                             \
513
      ((x) != NULL) && ((y) = name##_RB_PREV(x), (x) != NULL);                \
514
       (x) = (y))
515
516
#define RB_FOREACH_REVERSE_SAFE(x, name, head, y)                             \
517
  for ((x) = RB_MAX(name, head);                                              \
518
      ((x) != NULL) && ((y) = name##_RB_PREV(x), (x) != NULL);                \
519
       (x) = (y))
520
521
#endif  /* UV_TREE_H_ */