Coverage Report

Created: 2025-12-10 06:14

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