Coverage Report

Created: 2025-11-24 06:55

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
14.3k
#define RB_INIT(root) do {           \
305
14.3k
  (root)->rbh_root = NULL;          \
306
14.3k
} while (/*CONSTCOND*/ 0)
307
308
481k
#define RB_BLACK  0
309
545k
#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.17M
#define RB_LEFT(elm, field)   (elm)->field.rbe_left
319
1.17M
#define RB_RIGHT(elm, field)    (elm)->field.rbe_right
320
1.20M
#define RB_PARENT(elm, field)   (elm)->field.rbe_parent
321
1.04M
#define RB_COLOR(elm, field)    (elm)->field.rbe_color
322
219k
#define RB_ROOT(head)     (head)->rbh_root
323
8.74k
#define RB_EMPTY(head)      (RB_ROOT(head) == NULL)
324
325
97.2k
#define RB_SET(elm, parent, field) do {         \
326
97.2k
  RB_PARENT(elm, field) = parent;          \
327
97.2k
  RB_LEFT(elm, field) = RB_RIGHT(elm, field) = NULL;    \
328
97.2k
  RB_COLOR(elm, field) = RB_RED;         \
329
97.2k
} while (/*CONSTCOND*/ 0)
330
331
118k
#define RB_SET_BLACKRED(black, red, field) do {       \
332
118k
  RB_COLOR(black, field) = RB_BLACK;       \
333
118k
  RB_COLOR(red, field) = RB_RED;         \
334
118k
} while (/*CONSTCOND*/ 0)
335
336
#ifndef RB_AUGMENT
337
363k
#define RB_AUGMENT(x) do {} while (0)
338
#endif
339
340
68.7k
#define RB_ROTATE_LEFT(head, elm, tmp, field) do {     \
341
68.7k
  (tmp) = RB_RIGHT(elm, field);         \
342
68.7k
  if ((RB_RIGHT(elm, field) = RB_LEFT(tmp, field)) != NULL) { \
343
32.4k
    RB_PARENT(RB_LEFT(tmp, field), field) = (elm);   \
344
32.4k
  }                \
345
68.7k
  RB_AUGMENT(elm);            \
346
68.7k
  if ((RB_PARENT(tmp, field) = RB_PARENT(elm, field)) != NULL) { \
347
49.0k
    if ((elm) == RB_LEFT(RB_PARENT(elm, field), field)) \
348
49.0k
      RB_LEFT(RB_PARENT(elm, field), field) = (tmp); \
349
49.0k
    else              \
350
49.0k
      RB_RIGHT(RB_PARENT(elm, field), field) = (tmp); \
351
49.0k
  } else               \
352
68.7k
    (head)->rbh_root = (tmp);       \
353
68.7k
  RB_LEFT(tmp, field) = (elm);         \
354
68.7k
  RB_PARENT(elm, field) = (tmp);         \
355
68.7k
  RB_AUGMENT(tmp);            \
356
68.7k
  if ((RB_PARENT(tmp, field)))          \
357
68.7k
    RB_AUGMENT(RB_PARENT(tmp, field));      \
358
68.7k
} while (/*CONSTCOND*/ 0)
359
360
12.9k
#define RB_ROTATE_RIGHT(head, elm, tmp, field) do {     \
361
12.9k
  (tmp) = RB_LEFT(elm, field);         \
362
12.9k
  if ((RB_LEFT(elm, field) = RB_RIGHT(tmp, field)) != NULL) { \
363
3.71k
    RB_PARENT(RB_RIGHT(tmp, field), field) = (elm);    \
364
3.71k
  }                \
365
12.9k
  RB_AUGMENT(elm);            \
366
12.9k
  if ((RB_PARENT(tmp, field) = RB_PARENT(elm, field)) != NULL) { \
367
12.7k
    if ((elm) == RB_LEFT(RB_PARENT(elm, field), field)) \
368
12.7k
      RB_LEFT(RB_PARENT(elm, field), field) = (tmp); \
369
12.7k
    else              \
370
12.7k
      RB_RIGHT(RB_PARENT(elm, field), field) = (tmp); \
371
12.7k
  } else               \
372
12.9k
    (head)->rbh_root = (tmp);       \
373
12.9k
  RB_RIGHT(tmp, field) = (elm);         \
374
12.9k
  RB_PARENT(elm, field) = (tmp);         \
375
12.9k
  RB_AUGMENT(tmp);            \
376
12.9k
  if ((RB_PARENT(tmp, field)))          \
377
12.9k
    RB_AUGMENT(RB_PARENT(tmp, field));      \
378
12.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
97.2k
name##_RB_INSERT_COLOR(struct name *head, struct type *elm)   \
435
97.2k
{                 \
436
97.2k
  struct type *parent, *gparent, *tmp;        \
437
203k
  while ((parent = RB_PARENT(elm, field)) != NULL &&    \
438
203k
      RB_COLOR(parent, field) == RB_RED) {     \
439
106k
    gparent = RB_PARENT(parent, field);      \
440
106k
    if (parent == RB_LEFT(gparent, field)) {   \
441
18.5k
      tmp = RB_RIGHT(gparent, field);     \
442
18.5k
      if (tmp && RB_COLOR(tmp, field) == RB_RED) { \
443
9.48k
        RB_COLOR(tmp, field) = RB_BLACK; \
444
9.48k
        RB_SET_BLACKRED(parent, gparent, field);\
445
9.48k
        elm = gparent;        \
446
9.48k
        continue;       \
447
9.48k
      }            \
448
18.5k
      if (RB_RIGHT(parent, field) == elm) {   \
449
5.03k
        RB_ROTATE_LEFT(head, parent, tmp, field);\
450
5.03k
        tmp = parent;       \
451
5.03k
        parent = elm;       \
452
5.03k
        elm = tmp;        \
453
5.03k
      }            \
454
9.02k
      RB_SET_BLACKRED(parent, gparent, field); \
455
9.02k
      RB_ROTATE_RIGHT(head, gparent, tmp, field);  \
456
88.0k
    } else {           \
457
88.0k
      tmp = RB_LEFT(gparent, field);     \
458
88.0k
      if (tmp && RB_COLOR(tmp, field) == RB_RED) { \
459
42.9k
        RB_COLOR(tmp, field) = RB_BLACK; \
460
42.9k
        RB_SET_BLACKRED(parent, gparent, field);\
461
42.9k
        elm = gparent;        \
462
42.9k
        continue;       \
463
42.9k
      }            \
464
88.0k
      if (RB_LEFT(parent, field) == elm) {   \
465
3.97k
        RB_ROTATE_RIGHT(head, parent, tmp, field);\
466
3.97k
        tmp = parent;       \
467
3.97k
        parent = elm;       \
468
3.97k
        elm = tmp;        \
469
3.97k
      }            \
470
45.0k
      RB_SET_BLACKRED(parent, gparent, field); \
471
45.0k
      RB_ROTATE_LEFT(head, gparent, tmp, field);  \
472
45.0k
    }              \
473
106k
  }                \
474
97.2k
  RB_COLOR(head->rbh_root, field) = RB_BLACK;     \
475
97.2k
}
476
477
#define RB_GENERATE_REMOVE_COLOR(name, type, field, attr)   \
478
attr void               \
479
56.5k
name##_RB_REMOVE_COLOR(struct name *head, struct type *parent, struct type *elm) \
480
56.5k
{                 \
481
56.5k
  struct type *tmp;           \
482
88.7k
  while ((elm == NULL || RB_COLOR(elm, field) == RB_BLACK) &&  \
483
88.7k
      elm != RB_ROOT(head)) {         \
484
38.9k
    if (RB_LEFT(parent, field) == elm) {     \
485
38.9k
      tmp = RB_RIGHT(parent, field);      \
486
38.9k
      if (RB_COLOR(tmp, field) == RB_RED) {   \
487
11.7k
        RB_SET_BLACKRED(tmp, parent, field); \
488
11.7k
        RB_ROTATE_LEFT(head, parent, tmp, field);\
489
11.7k
        tmp = RB_RIGHT(parent, field);    \
490
11.7k
      }            \
491
38.9k
      if ((RB_LEFT(tmp, field) == NULL ||   \
492
38.9k
          RB_COLOR(RB_LEFT(tmp, field), field) == RB_BLACK) &&\
493
38.9k
          (RB_RIGHT(tmp, field) == NULL ||   \
494
35.7k
          RB_COLOR(RB_RIGHT(tmp, field), field) == RB_BLACK)) {\
495
32.1k
        RB_COLOR(tmp, field) = RB_RED;   \
496
32.1k
        elm = parent;       \
497
32.1k
        parent = RB_PARENT(elm, field);   \
498
32.1k
      } else {         \
499
6.86k
        if (RB_RIGHT(tmp, field) == NULL || \
500
6.86k
            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
6.86k
        RB_COLOR(tmp, field) = RB_COLOR(parent, field);\
510
6.86k
        RB_COLOR(parent, field) = RB_BLACK; \
511
6.86k
        if (RB_RIGHT(tmp, field))   \
512
6.86k
          RB_COLOR(RB_RIGHT(tmp, field), field) = RB_BLACK;\
513
6.86k
        RB_ROTATE_LEFT(head, parent, tmp, field);\
514
6.86k
        elm = RB_ROOT(head);     \
515
6.86k
        break;          \
516
6.86k
      }            \
517
38.9k
    } 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
38.9k
  }                \
552
56.5k
  if (elm)             \
553
56.5k
    RB_COLOR(elm, field) = RB_BLACK;     \
554
56.5k
}
555
556
#define RB_GENERATE_REMOVE(name, type, field, attr)     \
557
attr struct type *              \
558
56.8k
name##_RB_REMOVE(struct name *head, struct type *elm)     \
559
56.8k
{                 \
560
56.8k
  struct type *child, *parent, *old = elm;      \
561
56.8k
  int color;              \
562
56.8k
  if (RB_LEFT(elm, field) == NULL)       \
563
56.8k
    child = RB_RIGHT(elm, field);       \
564
56.8k
  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
56.8k
  parent = RB_PARENT(elm, field);         \
607
56.8k
  color = RB_COLOR(elm, field);         \
608
56.8k
  if (child)             \
609
56.8k
    RB_PARENT(child, field) = parent;     \
610
56.8k
  if (parent) {             \
611
47.7k
    if (RB_LEFT(parent, field) == elm)     \
612
47.7k
      RB_LEFT(parent, field) = child;     \
613
47.7k
    else              \
614
47.7k
      RB_RIGHT(parent, field) = child;   \
615
47.7k
    RB_AUGMENT(parent);         \
616
47.7k
  } else               \
617
56.8k
    RB_ROOT(head) = child;         \
618
56.8k
color:                  \
619
56.8k
  if (color == RB_BLACK)           \
620
56.8k
    name##_RB_REMOVE_COLOR(head, parent, child);   \
621
56.8k
  return (old);             \
622
56.8k
}                  \
623
624
#define RB_GENERATE_INSERT(name, type, field, cmp, attr)    \
625
/* Inserts a node into the RB tree */         \
626
attr struct type *              \
627
108k
name##_RB_INSERT(struct name *head, struct type *elm)     \
628
108k
{                 \
629
108k
  struct type *tmp;           \
630
108k
  struct type *parent = NULL;         \
631
108k
  int comp = 0;             \
632
108k
  tmp = RB_ROOT(head);           \
633
662k
  while (tmp) {             \
634
565k
    parent = tmp;           \
635
565k
    comp = (cmp)(elm, parent);        \
636
565k
    if (comp < 0)           \
637
565k
      tmp = RB_LEFT(tmp, field);     \
638
565k
    else if (comp > 0)         \
639
400k
      tmp = RB_RIGHT(tmp, field);     \
640
400k
    else              \
641
400k
      return (tmp);         \
642
565k
  }                \
643
108k
  RB_SET(elm, parent, field);         \
644
97.2k
  if (parent != NULL) {           \
645
90.9k
    if (comp < 0)           \
646
90.9k
      RB_LEFT(parent, field) = elm;     \
647
90.9k
    else              \
648
90.9k
      RB_RIGHT(parent, field) = elm;     \
649
90.9k
    RB_AUGMENT(parent);         \
650
90.9k
  } else               \
651
97.2k
    RB_ROOT(head) = elm;         \
652
97.2k
  name##_RB_INSERT_COLOR(head, elm);        \
653
97.2k
  return (NULL);             \
654
108k
}
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
1.59k
name##_RB_FIND(struct name *head, struct type *elm)     \
660
1.59k
{                 \
661
1.59k
  struct type *tmp = RB_ROOT(head);       \
662
1.59k
  int comp;             \
663
1.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
1.59k
  return (NULL);             \
673
1.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
116k
name##_RB_NEXT(struct type *elm)          \
701
116k
{                 \
702
116k
  if (RB_RIGHT(elm, field)) {         \
703
53.2k
    elm = RB_RIGHT(elm, field);       \
704
71.5k
    while (RB_LEFT(elm, field))       \
705
53.2k
      elm = RB_LEFT(elm, field);     \
706
63.5k
  } else {             \
707
63.5k
    if (RB_PARENT(elm, field) &&       \
708
63.5k
        (elm == RB_LEFT(RB_PARENT(elm, field), field))) \
709
63.5k
      elm = RB_PARENT(elm, field);     \
710
63.5k
    else {             \
711
49.2k
      while (RB_PARENT(elm, field) &&     \
712
49.2k
          (elm == RB_RIGHT(RB_PARENT(elm, field), field)))\
713
28.2k
        elm = RB_PARENT(elm, field);   \
714
21.0k
      elm = RB_PARENT(elm, field);     \
715
21.0k
    }              \
716
63.5k
  }                \
717
116k
  return (elm);             \
718
116k
}
workbook.c:lxw_worksheet_names_RB_NEXT
Line
Count
Source
700
797
name##_RB_NEXT(struct type *elm)          \
701
797
{                 \
702
797
  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
797
  } else {             \
707
797
    if (RB_PARENT(elm, field) &&       \
708
797
        (elm == RB_LEFT(RB_PARENT(elm, field), field))) \
709
797
      elm = RB_PARENT(elm, field);     \
710
797
    else {             \
711
797
      while (RB_PARENT(elm, field) &&     \
712
797
          (elm == RB_RIGHT(RB_PARENT(elm, field), field)))\
713
797
        elm = RB_PARENT(elm, field);   \
714
797
      elm = RB_PARENT(elm, field);     \
715
797
    }             \
716
797
  }               \
717
797
  return (elm);             \
718
797
}
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
12.0k
name##_RB_NEXT(struct type *elm)          \
701
12.0k
{                 \
702
12.0k
  if (RB_RIGHT(elm, field)) {         \
703
5.02k
    elm = RB_RIGHT(elm, field);       \
704
7.07k
    while (RB_LEFT(elm, field))       \
705
5.02k
      elm = RB_LEFT(elm, field);     \
706
6.98k
  } else {             \
707
6.98k
    if (RB_PARENT(elm, field) &&       \
708
6.98k
        (elm == RB_LEFT(RB_PARENT(elm, field), field))) \
709
6.98k
      elm = RB_PARENT(elm, field);     \
710
6.98k
    else {             \
711
6.77k
      while (RB_PARENT(elm, field) &&     \
712
6.77k
          (elm == RB_RIGHT(RB_PARENT(elm, field), field)))\
713
3.43k
        elm = RB_PARENT(elm, field);   \
714
3.33k
      elm = RB_PARENT(elm, field);     \
715
3.33k
    }              \
716
6.98k
  }                \
717
12.0k
  return (elm);             \
718
12.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
worksheet.c:lxw_table_cells_RB_NEXT
Line
Count
Source
700
104k
name##_RB_NEXT(struct type *elm)          \
701
104k
{                 \
702
104k
  if (RB_RIGHT(elm, field)) {         \
703
48.2k
    elm = RB_RIGHT(elm, field);       \
704
64.4k
    while (RB_LEFT(elm, field))       \
705
48.2k
      elm = RB_LEFT(elm, field);     \
706
55.7k
  } else {             \
707
55.7k
    if (RB_PARENT(elm, field) &&       \
708
55.7k
        (elm == RB_LEFT(RB_PARENT(elm, field), field))) \
709
55.7k
      elm = RB_PARENT(elm, field);     \
710
55.7k
    else {             \
711
41.6k
      while (RB_PARENT(elm, field) &&     \
712
41.6k
          (elm == RB_RIGHT(RB_PARENT(elm, field), field)))\
713
24.7k
        elm = RB_PARENT(elm, field);   \
714
16.9k
      elm = RB_PARENT(elm, field);     \
715
16.9k
    }              \
716
55.7k
  }                \
717
104k
  return (elm);             \
718
104k
}
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
27.1k
name##_RB_MINMAX(struct name *head, int val)        \
746
27.1k
{                 \
747
27.1k
  struct type *tmp = RB_ROOT(head);       \
748
27.1k
  struct type *parent = NULL;         \
749
81.8k
  while (tmp) {             \
750
54.7k
    parent = tmp;           \
751
54.7k
    if (val < 0)           \
752
54.7k
      tmp = RB_LEFT(tmp, field);     \
753
54.7k
    else              \
754
54.7k
      tmp = RB_RIGHT(tmp, field);     \
755
54.7k
  }                \
756
27.1k
  return (parent);            \
757
27.1k
}
758
759
23.1k
#define RB_NEGINF -1
760
4.00k
#define RB_INF  1
761
762
108k
#define RB_INSERT(name, x, y) name##_RB_INSERT(x, y)
763
56.8k
#define RB_REMOVE(name, x, y) name##_RB_REMOVE(x, y)
764
1.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
60.8k
#define RB_NEXT(name, x, y) name##_RB_NEXT(y)
767
#define RB_PREV(name, x, y) name##_RB_PREV(y)
768
23.1k
#define RB_MIN(name, x)   name##_RB_MINMAX(x, RB_NEGINF)
769
4.00k
#define RB_MAX(name, x)   name##_RB_MINMAX(x, RB_INF)
770
771
#define RB_FOREACH(x, name, head)         \
772
4.73k
  for ((x) = RB_MIN(name, head);         \
773
60.7k
       (x) != NULL;           \
774
56.0k
       (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_ */