Coverage Report

Created: 2026-03-19 06:31

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
20.3k
#define RB_INIT(root) do {           \
305
20.3k
  (root)->rbh_root = NULL;          \
306
20.3k
} while (/*CONSTCOND*/ 0)
307
308
626k
#define RB_BLACK  0
309
705k
#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.52M
#define RB_LEFT(elm, field)   (elm)->field.rbe_left
319
1.52M
#define RB_RIGHT(elm, field)    (elm)->field.rbe_right
320
1.56M
#define RB_PARENT(elm, field)   (elm)->field.rbe_parent
321
1.35M
#define RB_COLOR(elm, field)    (elm)->field.rbe_color
322
292k
#define RB_ROOT(head)     (head)->rbh_root
323
11.7k
#define RB_EMPTY(head)      (RB_ROOT(head) == NULL)
324
325
126k
#define RB_SET(elm, parent, field) do {         \
326
126k
  RB_PARENT(elm, field) = parent;          \
327
126k
  RB_LEFT(elm, field) = RB_RIGHT(elm, field) = NULL;    \
328
126k
  RB_COLOR(elm, field) = RB_RED;         \
329
126k
} while (/*CONSTCOND*/ 0)
330
331
152k
#define RB_SET_BLACKRED(black, red, field) do {       \
332
152k
  RB_COLOR(black, field) = RB_BLACK;       \
333
152k
  RB_COLOR(red, field) = RB_RED;         \
334
152k
} while (/*CONSTCOND*/ 0)
335
336
#ifndef RB_AUGMENT
337
469k
#define RB_AUGMENT(x) do {} while (0)
338
#endif
339
340
89.0k
#define RB_ROTATE_LEFT(head, elm, tmp, field) do {     \
341
89.0k
  (tmp) = RB_RIGHT(elm, field);         \
342
89.0k
  if ((RB_RIGHT(elm, field) = RB_LEFT(tmp, field)) != NULL) { \
343
42.2k
    RB_PARENT(RB_LEFT(tmp, field), field) = (elm);   \
344
42.2k
  }                \
345
89.0k
  RB_AUGMENT(elm);            \
346
89.0k
  if ((RB_PARENT(tmp, field) = RB_PARENT(elm, field)) != NULL) { \
347
63.2k
    if ((elm) == RB_LEFT(RB_PARENT(elm, field), field)) \
348
63.2k
      RB_LEFT(RB_PARENT(elm, field), field) = (tmp); \
349
63.2k
    else              \
350
63.2k
      RB_RIGHT(RB_PARENT(elm, field), field) = (tmp); \
351
63.2k
  } else               \
352
89.0k
    (head)->rbh_root = (tmp);       \
353
89.0k
  RB_LEFT(tmp, field) = (elm);         \
354
89.0k
  RB_PARENT(elm, field) = (tmp);         \
355
89.0k
  RB_AUGMENT(tmp);            \
356
89.0k
  if ((RB_PARENT(tmp, field)))          \
357
89.0k
    RB_AUGMENT(RB_PARENT(tmp, field));      \
358
89.0k
} while (/*CONSTCOND*/ 0)
359
360
16.0k
#define RB_ROTATE_RIGHT(head, elm, tmp, field) do {     \
361
16.0k
  (tmp) = RB_LEFT(elm, field);         \
362
16.0k
  if ((RB_LEFT(elm, field) = RB_RIGHT(tmp, field)) != NULL) { \
363
4.64k
    RB_PARENT(RB_RIGHT(tmp, field), field) = (elm);    \
364
4.64k
  }                \
365
16.0k
  RB_AUGMENT(elm);            \
366
16.0k
  if ((RB_PARENT(tmp, field) = RB_PARENT(elm, field)) != NULL) { \
367
15.6k
    if ((elm) == RB_LEFT(RB_PARENT(elm, field), field)) \
368
15.6k
      RB_LEFT(RB_PARENT(elm, field), field) = (tmp); \
369
15.6k
    else              \
370
15.6k
      RB_RIGHT(RB_PARENT(elm, field), field) = (tmp); \
371
15.6k
  } else               \
372
16.0k
    (head)->rbh_root = (tmp);       \
373
16.0k
  RB_RIGHT(tmp, field) = (elm);         \
374
16.0k
  RB_PARENT(elm, field) = (tmp);         \
375
16.0k
  RB_AUGMENT(tmp);            \
376
16.0k
  if ((RB_PARENT(tmp, field)))          \
377
16.0k
    RB_AUGMENT(RB_PARENT(tmp, field));      \
378
16.0k
} 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
126k
name##_RB_INSERT_COLOR(struct name *head, struct type *elm)   \
435
126k
{                 \
436
126k
  struct type *parent, *gparent, *tmp;        \
437
263k
  while ((parent = RB_PARENT(elm, field)) != NULL &&    \
438
263k
      RB_COLOR(parent, field) == RB_RED) {     \
439
137k
    gparent = RB_PARENT(parent, field);      \
440
137k
    if (parent == RB_LEFT(gparent, field)) {   \
441
23.0k
      tmp = RB_RIGHT(gparent, field);     \
442
23.0k
      if (tmp && RB_COLOR(tmp, field) == RB_RED) { \
443
12.1k
        RB_COLOR(tmp, field) = RB_BLACK; \
444
12.1k
        RB_SET_BLACKRED(parent, gparent, field);\
445
12.1k
        elm = gparent;        \
446
12.1k
        continue;       \
447
12.1k
      }            \
448
23.0k
      if (RB_RIGHT(parent, field) == elm) {   \
449
5.87k
        RB_ROTATE_LEFT(head, parent, tmp, field);\
450
5.87k
        tmp = parent;       \
451
5.87k
        parent = elm;       \
452
5.87k
        elm = tmp;        \
453
5.87k
      }            \
454
10.9k
      RB_SET_BLACKRED(parent, gparent, field); \
455
10.9k
      RB_ROTATE_RIGHT(head, gparent, tmp, field);  \
456
114k
    } else {           \
457
114k
      tmp = RB_LEFT(gparent, field);     \
458
114k
      if (tmp && RB_COLOR(tmp, field) == RB_RED) { \
459
55.6k
        RB_COLOR(tmp, field) = RB_BLACK; \
460
55.6k
        RB_SET_BLACKRED(parent, gparent, field);\
461
55.6k
        elm = gparent;        \
462
55.6k
        continue;       \
463
55.6k
      }            \
464
114k
      if (RB_LEFT(parent, field) == elm) {   \
465
5.18k
        RB_ROTATE_RIGHT(head, parent, tmp, field);\
466
5.18k
        tmp = parent;       \
467
5.18k
        parent = elm;       \
468
5.18k
        elm = tmp;        \
469
5.18k
      }            \
470
58.7k
      RB_SET_BLACKRED(parent, gparent, field); \
471
58.7k
      RB_ROTATE_LEFT(head, gparent, tmp, field);  \
472
58.7k
    }              \
473
137k
  }                \
474
126k
  RB_COLOR(head->rbh_root, field) = RB_BLACK;     \
475
126k
}
476
477
#define RB_GENERATE_REMOVE_COLOR(name, type, field, attr)   \
478
attr void               \
479
74.7k
name##_RB_REMOVE_COLOR(struct name *head, struct type *parent, struct type *elm) \
480
74.7k
{                 \
481
74.7k
  struct type *tmp;           \
482
116k
  while ((elm == NULL || RB_COLOR(elm, field) == RB_BLACK) &&  \
483
116k
      elm != RB_ROOT(head)) {         \
484
51.1k
    if (RB_LEFT(parent, field) == elm) {     \
485
51.1k
      tmp = RB_RIGHT(parent, field);      \
486
51.1k
      if (RB_COLOR(tmp, field) == RB_RED) {   \
487
15.4k
        RB_SET_BLACKRED(tmp, parent, field); \
488
15.4k
        RB_ROTATE_LEFT(head, parent, tmp, field);\
489
15.4k
        tmp = RB_RIGHT(parent, field);    \
490
15.4k
      }            \
491
51.1k
      if ((RB_LEFT(tmp, field) == NULL ||   \
492
51.1k
          RB_COLOR(RB_LEFT(tmp, field), field) == RB_BLACK) &&\
493
51.1k
          (RB_RIGHT(tmp, field) == NULL ||   \
494
46.8k
          RB_COLOR(RB_RIGHT(tmp, field), field) == RB_BLACK)) {\
495
42.0k
        RB_COLOR(tmp, field) = RB_RED;   \
496
42.0k
        elm = parent;       \
497
42.0k
        parent = RB_PARENT(elm, field);   \
498
42.0k
      } else {         \
499
9.05k
        if (RB_RIGHT(tmp, field) == NULL || \
500
9.05k
            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
9.05k
        RB_COLOR(tmp, field) = RB_COLOR(parent, field);\
510
9.05k
        RB_COLOR(parent, field) = RB_BLACK; \
511
9.05k
        if (RB_RIGHT(tmp, field))   \
512
9.05k
          RB_COLOR(RB_RIGHT(tmp, field), field) = RB_BLACK;\
513
9.05k
        RB_ROTATE_LEFT(head, parent, tmp, field);\
514
9.05k
        elm = RB_ROOT(head);     \
515
9.05k
        break;          \
516
9.05k
      }            \
517
51.1k
    } 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
51.1k
  }                \
552
74.7k
  if (elm)             \
553
74.7k
    RB_COLOR(elm, field) = RB_BLACK;     \
554
74.7k
}
555
556
#define RB_GENERATE_REMOVE(name, type, field, attr)     \
557
attr struct type *              \
558
74.9k
name##_RB_REMOVE(struct name *head, struct type *elm)     \
559
74.9k
{                 \
560
74.9k
  struct type *child, *parent, *old = elm;      \
561
74.9k
  int color;              \
562
74.9k
  if (RB_LEFT(elm, field) == NULL)       \
563
74.9k
    child = RB_RIGHT(elm, field);       \
564
74.9k
  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
74.9k
  parent = RB_PARENT(elm, field);         \
607
74.9k
  color = RB_COLOR(elm, field);         \
608
74.9k
  if (child)             \
609
74.9k
    RB_PARENT(child, field) = parent;     \
610
74.9k
  if (parent) {             \
611
62.7k
    if (RB_LEFT(parent, field) == elm)     \
612
62.7k
      RB_LEFT(parent, field) = child;     \
613
62.7k
    else              \
614
62.7k
      RB_RIGHT(parent, field) = child;   \
615
62.7k
    RB_AUGMENT(parent);         \
616
62.7k
  } else               \
617
74.9k
    RB_ROOT(head) = child;         \
618
74.9k
color:                  \
619
74.9k
  if (color == RB_BLACK)           \
620
74.9k
    name##_RB_REMOVE_COLOR(head, parent, child);   \
621
74.9k
  return (old);             \
622
74.9k
}                  \
623
624
#define RB_GENERATE_INSERT(name, type, field, cmp, attr)    \
625
/* Inserts a node into the RB tree */         \
626
attr struct type *              \
627
143k
name##_RB_INSERT(struct name *head, struct type *elm)     \
628
143k
{                 \
629
143k
  struct type *tmp;           \
630
143k
  struct type *parent = NULL;         \
631
143k
  int comp = 0;             \
632
143k
  tmp = RB_ROOT(head);           \
633
846k
  while (tmp) {             \
634
720k
    parent = tmp;           \
635
720k
    comp = (cmp)(elm, parent);        \
636
720k
    if (comp < 0)           \
637
720k
      tmp = RB_LEFT(tmp, field);     \
638
720k
    else if (comp > 0)         \
639
516k
      tmp = RB_RIGHT(tmp, field);     \
640
516k
    else              \
641
516k
      return (tmp);         \
642
720k
  }                \
643
143k
  RB_SET(elm, parent, field);         \
644
126k
  if (parent != NULL) {           \
645
117k
    if (comp < 0)           \
646
117k
      RB_LEFT(parent, field) = elm;     \
647
117k
    else              \
648
117k
      RB_RIGHT(parent, field) = elm;     \
649
117k
    RB_AUGMENT(parent);         \
650
117k
  } else               \
651
126k
    RB_ROOT(head) = elm;         \
652
126k
  name##_RB_INSERT_COLOR(head, elm);        \
653
126k
  return (NULL);             \
654
143k
}
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.30k
name##_RB_FIND(struct name *head, struct type *elm)     \
660
2.30k
{                 \
661
2.30k
  struct type *tmp = RB_ROOT(head);       \
662
2.30k
  int comp;             \
663
2.30k
  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.30k
  return (NULL);             \
673
2.30k
}
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
154k
name##_RB_NEXT(struct type *elm)          \
701
154k
{                 \
702
154k
  if (RB_RIGHT(elm, field)) {         \
703
70.1k
    elm = RB_RIGHT(elm, field);       \
704
93.9k
    while (RB_LEFT(elm, field))       \
705
70.1k
      elm = RB_LEFT(elm, field);     \
706
84.0k
  } else {             \
707
84.0k
    if (RB_PARENT(elm, field) &&       \
708
84.0k
        (elm == RB_LEFT(RB_PARENT(elm, field), field))) \
709
84.0k
      elm = RB_PARENT(elm, field);     \
710
84.0k
    else {             \
711
65.3k
      while (RB_PARENT(elm, field) &&     \
712
65.3k
          (elm == RB_RIGHT(RB_PARENT(elm, field), field)))\
713
37.1k
        elm = RB_PARENT(elm, field);   \
714
28.1k
      elm = RB_PARENT(elm, field);     \
715
28.1k
    }              \
716
84.0k
  }                \
717
154k
  return (elm);             \
718
154k
}
workbook.c:lxw_worksheet_names_RB_NEXT
Line
Count
Source
700
1.15k
name##_RB_NEXT(struct type *elm)          \
701
1.15k
{                 \
702
1.15k
  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.15k
  } else {             \
707
1.15k
    if (RB_PARENT(elm, field) &&       \
708
1.15k
        (elm == RB_LEFT(RB_PARENT(elm, field), field))) \
709
1.15k
      elm = RB_PARENT(elm, field);     \
710
1.15k
    else {             \
711
1.15k
      while (RB_PARENT(elm, field) &&     \
712
1.15k
          (elm == RB_RIGHT(RB_PARENT(elm, field), field)))\
713
1.15k
        elm = RB_PARENT(elm, field);   \
714
1.15k
      elm = RB_PARENT(elm, field);     \
715
1.15k
    }             \
716
1.15k
  }               \
717
1.15k
  return (elm);             \
718
1.15k
}
Unexecuted instantiation: workbook.c:lxw_chartsheet_names_RB_NEXT
Unexecuted instantiation: workbook.c:lxw_image_md5s_RB_NEXT
worksheet.c:lxw_table_cells_RB_NEXT
Line
Count
Source
700
137k
name##_RB_NEXT(struct type *elm)          \
701
137k
{                 \
702
137k
  if (RB_RIGHT(elm, field)) {         \
703
63.5k
    elm = RB_RIGHT(elm, field);       \
704
84.7k
    while (RB_LEFT(elm, field))       \
705
63.5k
      elm = RB_LEFT(elm, field);     \
706
73.4k
  } else {             \
707
73.4k
    if (RB_PARENT(elm, field) &&       \
708
73.4k
        (elm == RB_LEFT(RB_PARENT(elm, field), field))) \
709
73.4k
      elm = RB_PARENT(elm, field);     \
710
73.4k
    else {             \
711
55.0k
      while (RB_PARENT(elm, field) &&     \
712
55.0k
          (elm == RB_RIGHT(RB_PARENT(elm, field), field)))\
713
32.6k
        elm = RB_PARENT(elm, field);   \
714
22.4k
      elm = RB_PARENT(elm, field);     \
715
22.4k
    }              \
716
73.4k
  }                \
717
137k
  return (elm);             \
718
137k
}
worksheet.c:lxw_table_rows_RB_NEXT
Line
Count
Source
700
16.0k
name##_RB_NEXT(struct type *elm)          \
701
16.0k
{                 \
702
16.0k
  if (RB_RIGHT(elm, field)) {         \
703
6.59k
    elm = RB_RIGHT(elm, field);       \
704
9.20k
    while (RB_LEFT(elm, field))       \
705
6.59k
      elm = RB_LEFT(elm, field);     \
706
9.41k
  } else {             \
707
9.41k
    if (RB_PARENT(elm, field) &&       \
708
9.41k
        (elm == RB_LEFT(RB_PARENT(elm, field), field))) \
709
9.41k
      elm = RB_PARENT(elm, field);     \
710
9.41k
    else {             \
711
9.13k
      while (RB_PARENT(elm, field) &&     \
712
9.13k
          (elm == RB_RIGHT(RB_PARENT(elm, field), field)))\
713
4.62k
        elm = RB_PARENT(elm, field);   \
714
4.62k
      elm = RB_PARENT(elm, field);     \
715
4.62k
    }              \
716
9.41k
  }                \
717
16.0k
  return (elm);             \
718
16.0k
}
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
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
37.4k
name##_RB_MINMAX(struct name *head, int val)        \
746
37.4k
{                 \
747
37.4k
  struct type *tmp = RB_ROOT(head);       \
748
37.4k
  struct type *parent = NULL;         \
749
109k
  while (tmp) {             \
750
72.5k
    parent = tmp;           \
751
72.5k
    if (val < 0)           \
752
72.5k
      tmp = RB_LEFT(tmp, field);     \
753
72.5k
    else              \
754
72.5k
      tmp = RB_RIGHT(tmp, field);     \
755
72.5k
  }                \
756
37.4k
  return (parent);            \
757
37.4k
}
758
759
32.0k
#define RB_NEGINF -1
760
5.33k
#define RB_INF  1
761
762
143k
#define RB_INSERT(name, x, y) name##_RB_INSERT(x, y)
763
74.9k
#define RB_REMOVE(name, x, y) name##_RB_REMOVE(x, y)
764
2.30k
#define RB_FIND(name, x, y) name##_RB_FIND(x, y)
765
#define RB_NFIND(name, x, y)  name##_RB_NFIND(x, y)
766
80.3k
#define RB_NEXT(name, x, y) name##_RB_NEXT(y)
767
#define RB_PREV(name, x, y) name##_RB_PREV(y)
768
32.0k
#define RB_MIN(name, x)   name##_RB_MINMAX(x, RB_NEGINF)
769
5.33k
#define RB_MAX(name, x)   name##_RB_MINMAX(x, RB_INF)
770
771
#define RB_FOREACH(x, name, head)         \
772
6.41k
  for ((x) = RB_MIN(name, head);         \
773
80.2k
       (x) != NULL;           \
774
73.8k
       (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_ */