data-structures-c
Loading...
Searching...
No Matches
rbtree_template.h
Go to the documentation of this file.
1// Copyright (c) 2026 abxh
2// SPDX-License-Identifier: MIT
3
29
34
35#ifdef __cplusplus
36extern "C" {
37#endif
38
39#include <stdbool.h>
40#include <stddef.h>
41#include <stdint.h>
42
43// macro definitions: {{{
44
49#ifndef PASTE
50#define PASTE(a, b) a##b
51#endif
52
57#ifndef XPASTE
58#define XPASTE(a, b) PASTE(a, b)
59#endif
60
65#ifndef JOIN
66#define JOIN(a, b) XPASTE(a, XPASTE(_, b))
67#endif
68
76#ifndef NAME
77#error "Must define NAME."
78#define FUNCTION_DEFINITIONS
79#define TYPE_DEFINITIONS
80#else
81#define RBTREE_NAME NAME
82#endif
83
91#ifndef KEY_TYPE
92#define KEY_TYPE int
93#error "Must define KEY_TYPE."
94#endif
95
108#ifdef ALLOW_DUPLICATES
109#endif
110
115#ifdef KEY_MEMBER_IS_FIRST
116#endif
117
122#ifndef FUNCTION_LINKAGE
123#define FUNCTION_LINKAGE
124#endif
125
127#define RBTREE_NODE_TYPE struct JOIN(RBTREE_NAME, node)
128#define RBTREE_CONTAINS_KEY JOIN(RBTREE_NAME, contains_key)
129#define RBTREE_NODE_IS_RED JOIN(RBTREE_NAME, node_is_red)
130#define RBTREE_NODE_IS_BLACK JOIN(RBTREE_NAME, node_is_black)
131#define RBTREE_NODE_GET_PARENT_PTR JOIN(RBTREE_NAME, node_get_parent_ptr)
132#define RBTREE_INSERT_FIXUP JOIN(internal, JOIN(RBTREE_NAME, insert_fixup))
133#define RBTREE_DELETE_FIXUP JOIN(internal, JOIN(RBTREE_NAME, delete_fixup))
134
135#define RBTREE_NODE_TRANSPLANT JOIN(internal, JOIN(RBTREE_NAME, node_transplant))
136#define RBTREE_NODE_SET_COLOR_TO_RED JOIN(internal, JOIN(RBTREE_NAME, node_set_color_to_red))
137#define RBTREE_NODE_SET_COLOR_TO_BLACK JOIN(internal, JOIN(RBTREE_NAME, node_set_color_to_black))
138#define RBTREE_NODE_SET_PARENT_PTR JOIN(internal, JOIN(RBTREE_NAME, node_set_parent_ptr))
139#define RBTREE_NODE_SET_COLOR_TO_COLOR_OF_OTHER JOIN(internal, JOIN(RBTREE_NAME, node_set_color_to_color_of_other))
140#define RBTREE_ROTATE_DIR JOIN(internal, JOIN(RBTREE_NAME, rotate_dir))
141
142#define RBTREE_CHILD_DIR(node_ptr) ((node_ptr) == RBTREE_NODE_GET_PARENT_PTR(node_ptr)->left_ptr ? 0 : 1)
144
145// }}}
146
147// type definitions: {{{
148
149struct JOIN(RBTREE_NAME, node);
150
155#ifdef TYPE_DEFINITIONS
156
160struct JOIN(RBTREE_NAME, node) {
161#ifdef KEY_MEMBER_IS_FIRST
162 KEY_TYPE key;
163#endif
166 union {
167 struct {
168 RBTREE_NODE_TYPE *left_ptr;
169 RBTREE_NODE_TYPE *right_ptr;
170 };
171 RBTREE_NODE_TYPE *child_ptrs[2];
172 };
173#ifndef KEY_MEMBER_IS_FIRST
175#endif
176};
177
178#endif
179
180// }}}
181
182// function declarations: {{{
183
190FUNCTION_LINKAGE void JOIN(RBTREE_NAME, node_init)(RBTREE_NODE_TYPE *node_ptr, KEY_TYPE key);
191
197FUNCTION_LINKAGE RBTREE_NODE_TYPE *JOIN(RBTREE_NAME, node_get_parent_ptr)(RBTREE_NODE_TYPE *node_ptr);
198
204FUNCTION_LINKAGE bool JOIN(RBTREE_NAME, node_is_black)(const RBTREE_NODE_TYPE *node_ptr);
205
211FUNCTION_LINKAGE bool JOIN(RBTREE_NAME, node_is_red)(const RBTREE_NODE_TYPE *node_ptr);
212
220FUNCTION_LINKAGE bool JOIN(RBTREE_NAME, is_empty)(RBTREE_NODE_TYPE **rootptr_ptr);
221
230FUNCTION_LINKAGE bool JOIN(RBTREE_NAME, contains_key)(RBTREE_NODE_TYPE **rootptr_ptr, const KEY_TYPE key);
231
241FUNCTION_LINKAGE RBTREE_NODE_TYPE *JOIN(RBTREE_NAME, search_node)(RBTREE_NODE_TYPE **rootptr_ptr, const KEY_TYPE key);
242
249FUNCTION_LINKAGE void JOIN(RBTREE_NAME, insert_node)(RBTREE_NODE_TYPE **rootptr_ptr, RBTREE_NODE_TYPE *node_ptr);
250
259FUNCTION_LINKAGE RBTREE_NODE_TYPE *JOIN(RBTREE_NAME, delete_node)(RBTREE_NODE_TYPE **rootptr_ptr,
260 RBTREE_NODE_TYPE *node_ptr);
261
262// @}}}
263
264// function definitions: {{{
265
270#ifdef FUNCTION_DEFINITIONS
271
272#include <assert.h>
273
287#ifndef KEY_IS_STRICTLY_LESS
288#error "Must define KEY_IS_STRICTLY_LESS."
289#define KEY_IS_STRICTLY_LESS(a, b) ((a) < (b))
290#endif
291
293
294static inline void JOIN(internal, JOIN(RBTREE_NAME, node_set_color_to_red))(RBTREE_NODE_TYPE *node_ptr)
295{
296 node_ptr->__parent_ptr_with_color_bit &= ~(uintptr_t)1;
297}
298
299static inline void JOIN(internal, JOIN(RBTREE_NAME, node_set_color_to_black))(RBTREE_NODE_TYPE *node_ptr)
300{
301 node_ptr->__parent_ptr_with_color_bit |= 1;
302}
303
304static inline void JOIN(internal,
305 JOIN(RBTREE_NAME, node_set_color_to_color_of_other))(RBTREE_NODE_TYPE *node_ptr,
306 const RBTREE_NODE_TYPE *other_ptr)
307{
308 const bool is_black = other_ptr->__parent_ptr_with_color_bit & 1;
309
310 node_ptr->__parent_ptr_with_color_bit &= ~(uintptr_t)1;
311 node_ptr->__parent_ptr_with_color_bit += is_black;
312}
313
314static inline void JOIN(internal, JOIN(RBTREE_NAME, node_set_parent_ptr))(RBTREE_NODE_TYPE *node_ptr,
315 RBTREE_NODE_TYPE *parent_ptr)
316{
317 const bool is_black = node_ptr->__parent_ptr_with_color_bit & 1;
318
319 node_ptr->__parent_ptr_with_color_bit = (uintptr_t)parent_ptr;
320 node_ptr->__parent_ptr_with_color_bit += is_black;
321}
322
323// rotate a subtree around a given subtree root node and direction (0: left or
324// 1: right). returns the new subtree root
325static inline RBTREE_NODE_TYPE *JOIN(internal, JOIN(RBTREE_NAME, rotate_dir))(RBTREE_NODE_TYPE **rootptr_ptr,
326 RBTREE_NODE_TYPE *P, const int dir);
327
328// rebalance tree after insert. see explanation in the sources linked above.
329static inline void JOIN(internal, JOIN(RBTREE_NAME, insert_fixup))(RBTREE_NODE_TYPE **rootptr_ptr, RBTREE_NODE_TYPE *N);
330
331// move the parent of a node (src) to another node (dest).
332static inline void JOIN(internal, JOIN(RBTREE_NAME, node_transplant))(RBTREE_NODE_TYPE **rootptr_ptr,
333 RBTREE_NODE_TYPE *src_node,
334 RBTREE_NODE_TYPE *dest_node);
335
336// rebalance tree after delete. see explanation in the sources linked above.
337// for the special case where: (P's child) was not root and was black and had no children.
338static inline void JOIN(internal, JOIN(RBTREE_NAME, delete_fixup))(RBTREE_NODE_TYPE **rootptr_ptr, RBTREE_NODE_TYPE *P,
339 int dir);
340
342
343FUNCTION_LINKAGE void JOIN(RBTREE_NAME, node_init)(RBTREE_NODE_TYPE *node_ptr, KEY_TYPE key)
344{
345 assert(node_ptr != NULL);
346
347 node_ptr->key = key;
348 node_ptr->left_ptr = node_ptr->right_ptr = NULL;
349 RBTREE_NODE_SET_PARENT_PTR(node_ptr, NULL);
350}
351
352FUNCTION_LINKAGE RBTREE_NODE_TYPE *JOIN(RBTREE_NAME, node_get_parent_ptr)(RBTREE_NODE_TYPE *node_ptr)
353{
354 assert(node_ptr != NULL);
355
356 return (RBTREE_NODE_TYPE *)(node_ptr->__parent_ptr_with_color_bit & ~(uintptr_t)1);
357}
358
359FUNCTION_LINKAGE bool JOIN(RBTREE_NAME, node_is_black)(const RBTREE_NODE_TYPE *node_ptr)
360{
361 assert(node_ptr != NULL);
362
363 return (node_ptr->__parent_ptr_with_color_bit & 1);
364}
365
366FUNCTION_LINKAGE bool JOIN(RBTREE_NAME, node_is_red)(const RBTREE_NODE_TYPE *node_ptr)
367{
368 assert(node_ptr != NULL);
369
370 return !RBTREE_NODE_IS_BLACK(node_ptr);
371}
372
373FUNCTION_LINKAGE bool JOIN(RBTREE_NAME, is_empty)(RBTREE_NODE_TYPE **rootptr_ptr)
374{
375 assert(rootptr_ptr != NULL);
376
377 return *rootptr_ptr == NULL;
378}
379
380FUNCTION_LINKAGE bool JOIN(RBTREE_NAME, contains_key)(RBTREE_NODE_TYPE **rootptr_ptr, const KEY_TYPE key)
381{
382 assert(rootptr_ptr != NULL);
383
384 RBTREE_NODE_TYPE *node_ptr = *rootptr_ptr;
385
386 while (node_ptr != NULL) {
387 const bool is_strictly_less = KEY_IS_STRICTLY_LESS(key, node_ptr->key);
388 const bool is_strictly_greater = KEY_IS_STRICTLY_LESS(node_ptr->key, key);
389 const bool is_equal = !is_strictly_less && !is_strictly_greater;
390
391 if (is_equal) {
392 return true;
393 }
394 else if (is_strictly_less) {
395 node_ptr = node_ptr->left_ptr;
396 }
397 else {
398 node_ptr = node_ptr->right_ptr;
399 }
400 }
401 return false;
402}
403
404FUNCTION_LINKAGE RBTREE_NODE_TYPE *JOIN(RBTREE_NAME, search_node)(RBTREE_NODE_TYPE **rootptr_ptr, const KEY_TYPE key)
405{
406 assert(rootptr_ptr != NULL);
407
408 RBTREE_NODE_TYPE *node_ptr = *rootptr_ptr;
409 while (node_ptr != NULL) {
410 const bool is_strictly_less = KEY_IS_STRICTLY_LESS(key, node_ptr->key);
411 const bool is_strictly_greater = KEY_IS_STRICTLY_LESS(node_ptr->key, key);
412 const bool is_equal = !is_strictly_less && !is_strictly_greater;
413
414 if (is_equal) {
415 return node_ptr;
416 }
417 else if (is_strictly_less) {
418 node_ptr = node_ptr->left_ptr;
419 }
420 else {
421 node_ptr = node_ptr->right_ptr;
422 }
423 }
424 return NULL;
425}
426
427FUNCTION_LINKAGE void JOIN(RBTREE_NAME, insert_node)(RBTREE_NODE_TYPE **rootptr_ptr, RBTREE_NODE_TYPE *node_ptr)
428{
429 assert(rootptr_ptr != NULL);
430 assert(node_ptr != NULL);
431#ifndef ALLOW_DUPLICATES
432 assert(RBTREE_CONTAINS_KEY(rootptr_ptr, node_ptr->key) == false);
433#endif
434
435 RBTREE_NODE_TYPE *parent_ptr = NULL;
436 RBTREE_NODE_TYPE *current_ptr = *rootptr_ptr;
437
438 while (current_ptr != NULL) {
439 const bool is_strictly_greater = KEY_IS_STRICTLY_LESS(current_ptr->key, node_ptr->key);
440
441 parent_ptr = current_ptr;
442
443 if (is_strictly_greater) {
444 current_ptr = current_ptr->right_ptr;
445 }
446 else {
447 current_ptr = current_ptr->left_ptr;
448 }
449 }
450
451 node_ptr->left_ptr = node_ptr->right_ptr = NULL;
452 RBTREE_NODE_SET_PARENT_PTR(node_ptr, parent_ptr);
453 RBTREE_NODE_SET_COLOR_TO_RED(node_ptr);
454
455 if (parent_ptr == NULL) {
456 *rootptr_ptr = node_ptr;
457 }
458 else {
459 const int dir = KEY_IS_STRICTLY_LESS(parent_ptr->key, node_ptr->key) ? 1 : 0;
460
461 parent_ptr->child_ptrs[dir] = node_ptr;
462
463 RBTREE_INSERT_FIXUP(rootptr_ptr, node_ptr);
464 }
465}
466
467FUNCTION_LINKAGE RBTREE_NODE_TYPE *JOIN(RBTREE_NAME, delete_node)(RBTREE_NODE_TYPE **rootptr_ptr,
468 RBTREE_NODE_TYPE *node_ptr)
469{
470 assert(rootptr_ptr != NULL);
471 assert(node_ptr != NULL);
472
473 if (node_ptr->left_ptr == NULL && node_ptr->right_ptr == NULL) {
474 if (node_ptr == *rootptr_ptr || RBTREE_NODE_IS_RED(node_ptr)) {
475 RBTREE_NODE_TRANSPLANT(rootptr_ptr, node_ptr, NULL);
476 }
477 else {
478 RBTREE_NODE_TYPE *const parent_ptr = RBTREE_NODE_GET_PARENT_PTR(node_ptr);
479
480 const int dir = RBTREE_CHILD_DIR(node_ptr) ? 1 : 0;
481
482 RBTREE_NODE_TRANSPLANT(rootptr_ptr, node_ptr, NULL);
483
484 RBTREE_DELETE_FIXUP(rootptr_ptr, parent_ptr, dir);
485 }
486 }
487 else if (node_ptr->left_ptr == NULL || node_ptr->right_ptr == NULL) {
488 const int dir = node_ptr->left_ptr == NULL;
489
490 assert(RBTREE_NODE_IS_BLACK(node_ptr));
491 assert(RBTREE_NODE_IS_RED(node_ptr->child_ptrs[dir]));
492
493 RBTREE_NODE_SET_COLOR_TO_BLACK(node_ptr->child_ptrs[dir]);
494
495 RBTREE_NODE_TRANSPLANT(rootptr_ptr, node_ptr, node_ptr->child_ptrs[dir]);
496 }
497 else {
498 RBTREE_NODE_TYPE *successor_ptr = node_ptr->right_ptr;
499
500 while (successor_ptr->left_ptr != NULL) {
501 successor_ptr = successor_ptr->left_ptr;
502 }
503
504 const bool prev_successor_black = RBTREE_NODE_IS_BLACK(successor_ptr);
505
506 const int prev_successor_dir = RBTREE_CHILD_DIR(successor_ptr);
507
508 RBTREE_NODE_TYPE *const prev_successor_parent_ptr = RBTREE_NODE_GET_PARENT_PTR(successor_ptr);
509
510 RBTREE_NODE_TYPE *const prev_successor_child_ptr = successor_ptr->right_ptr;
511
512 {
513 if (RBTREE_NODE_GET_PARENT_PTR(successor_ptr) != node_ptr) {
514 RBTREE_NODE_TRANSPLANT(rootptr_ptr, successor_ptr, successor_ptr->right_ptr);
515
516 successor_ptr->right_ptr = node_ptr->right_ptr;
517 RBTREE_NODE_SET_PARENT_PTR(node_ptr->right_ptr, successor_ptr);
518 }
519 RBTREE_NODE_TRANSPLANT(rootptr_ptr, node_ptr, successor_ptr);
520
521 successor_ptr->left_ptr = node_ptr->left_ptr;
522 RBTREE_NODE_SET_PARENT_PTR(node_ptr->left_ptr, successor_ptr);
523
524 RBTREE_NODE_SET_COLOR_TO_COLOR_OF_OTHER(successor_ptr, node_ptr);
525 }
526
527 if (prev_successor_child_ptr != NULL) {
528 assert(prev_successor_black);
529 assert(RBTREE_NODE_IS_RED(prev_successor_child_ptr));
530
531 RBTREE_NODE_SET_COLOR_TO_BLACK(prev_successor_child_ptr);
532 }
533 else if (prev_successor_child_ptr == NULL && prev_successor_black) {
534 RBTREE_NODE_TYPE *actual_successor_ptr =
535 (prev_successor_parent_ptr == node_ptr) ? successor_ptr : prev_successor_parent_ptr;
536
537 RBTREE_DELETE_FIXUP(rootptr_ptr, actual_successor_ptr, prev_successor_dir);
538 }
539 }
540
541 node_ptr->left_ptr = node_ptr->right_ptr = NULL;
542 RBTREE_NODE_SET_PARENT_PTR(node_ptr, NULL);
543
544 return node_ptr;
545}
546
548
549static inline RBTREE_NODE_TYPE *JOIN(internal, JOIN(RBTREE_NAME, rotate_dir))(RBTREE_NODE_TYPE **rootptr_ptr,
550 RBTREE_NODE_TYPE *P, const int dir)
551{
552 /* Right rotate around P:
553 P S
554 / \ / \
555 S T --> .. P
556 / \ / \ ⟳ / \
557 .. C .. .. C T
558 / \ / \ / \
559 .. .. .. .. .. ..
560
561 Left rotate around P:
562 P S
563 / \ / \
564 T S P ..
565 / \ / \ --> / \
566 .. .. C .. ↺ T C
567 / \ / \ / \
568 .. .. .. .. .. ..
569 */
570
571 RBTREE_NODE_TYPE *G = RBTREE_NODE_GET_PARENT_PTR(P);
572 RBTREE_NODE_TYPE *S = P->child_ptrs[1 - dir];
573 assert(S != NULL);
574 RBTREE_NODE_TYPE *C = S->child_ptrs[dir];
575
576 P->child_ptrs[1 - dir] = C;
577 if (C != NULL) {
578 RBTREE_NODE_SET_PARENT_PTR(C, P);
579 }
580
581 S->child_ptrs[dir] = P;
582 RBTREE_NODE_SET_PARENT_PTR(P, S);
583
584 RBTREE_NODE_SET_PARENT_PTR(S, G);
585 if (G != NULL) {
586 G->child_ptrs[P == G->left_ptr ? 0 : 1] = S;
587 }
588 else {
589 *rootptr_ptr = S;
590 }
591 return S;
592}
593
594static inline void JOIN(internal, JOIN(RBTREE_NAME, insert_fixup))(RBTREE_NODE_TYPE **rootptr_ptr, RBTREE_NODE_TYPE *N)
595{
596 assert(RBTREE_NODE_IS_RED(N));
597 assert(N != *rootptr_ptr);
598
599 RBTREE_NODE_TYPE *P = RBTREE_NODE_GET_PARENT_PTR(N); // parent
600 RBTREE_NODE_TYPE *G = NULL; // grandparent
601 RBTREE_NODE_TYPE *U = NULL; // uncle
602
603 do {
604 if (RBTREE_NODE_IS_BLACK(P)) {
605 return;
606 }
607 if ((G = RBTREE_NODE_GET_PARENT_PTR(P)) == NULL) {
608 RBTREE_NODE_SET_COLOR_TO_BLACK(P);
609 return;
610 }
611 const int dir = RBTREE_CHILD_DIR(P);
612 U = G->child_ptrs[1 - dir];
613
614 if (U == NULL || RBTREE_NODE_IS_BLACK(U)) {
615 if (N == P->child_ptrs[1 - dir]) {
616 RBTREE_ROTATE_DIR(rootptr_ptr, P, dir);
617 N = P;
618 P = G->child_ptrs[dir];
619 }
620 RBTREE_NODE_SET_COLOR_TO_BLACK(P);
621 RBTREE_NODE_SET_COLOR_TO_RED(G);
622 RBTREE_ROTATE_DIR(rootptr_ptr, G, 1 - dir);
623 return;
624 }
625
626 RBTREE_NODE_SET_COLOR_TO_BLACK(P);
627 RBTREE_NODE_SET_COLOR_TO_BLACK(U);
628 RBTREE_NODE_SET_COLOR_TO_RED(G);
629
630 N = G;
631 P = RBTREE_NODE_GET_PARENT_PTR(N);
632 } while (P != NULL);
633}
634
635static inline void JOIN(internal, JOIN(RBTREE_NAME, node_transplant))(RBTREE_NODE_TYPE **rootptr_ptr,
636 RBTREE_NODE_TYPE *src_node,
637 RBTREE_NODE_TYPE *dest_node)
638{
639 RBTREE_NODE_TYPE *src_node_parent_ptr = RBTREE_NODE_GET_PARENT_PTR(src_node);
640
641 if (src_node_parent_ptr == NULL) {
642 *rootptr_ptr = dest_node;
643 }
644 else {
645 src_node_parent_ptr->child_ptrs[RBTREE_CHILD_DIR(src_node)] = dest_node;
646 }
647
648 if (dest_node != NULL) {
649 RBTREE_NODE_SET_PARENT_PTR(dest_node, src_node_parent_ptr);
650 }
651}
652
653static inline void JOIN(internal, JOIN(RBTREE_NAME, delete_fixup))(RBTREE_NODE_TYPE **rootptr_ptr, RBTREE_NODE_TYPE *P,
654 int dir)
655{
656 RBTREE_NODE_TYPE *N = NULL; // node (temp)
657 RBTREE_NODE_TYPE *S = NULL; // sibling
658 RBTREE_NODE_TYPE *C = NULL; // close nephew
659 RBTREE_NODE_TYPE *D = NULL; // distant nephew
660
661 do {
662 S = P->child_ptrs[1 - dir];
663 D = S->child_ptrs[1 - dir];
664 C = S->child_ptrs[dir];
665
666 if (RBTREE_NODE_IS_RED(S)) {
667 goto Case_3;
668 }
669 if (D != NULL && RBTREE_NODE_IS_RED(D)) {
670 goto Case_6;
671 }
672 if (C != NULL && RBTREE_NODE_IS_RED(C)) {
673 goto Case_5;
674 }
675 if (RBTREE_NODE_IS_RED(P)) {
676 goto Case_4;
677 }
678 RBTREE_NODE_SET_COLOR_TO_RED(S);
679
680 N = P;
681 P = RBTREE_NODE_GET_PARENT_PTR(N);
682 } while (P != NULL && (dir = RBTREE_CHILD_DIR(N), true));
683
684 return;
685Case_3:
686 RBTREE_ROTATE_DIR(rootptr_ptr, P, dir);
687 RBTREE_NODE_SET_COLOR_TO_RED(P);
688 RBTREE_NODE_SET_COLOR_TO_BLACK(S);
689 S = C;
690 D = S->child_ptrs[1 - dir];
691 if (D != NULL && RBTREE_NODE_IS_RED(D)) {
692 goto Case_6;
693 }
694 C = S->child_ptrs[dir];
695 if (C != NULL && RBTREE_NODE_IS_RED(C)) {
696 goto Case_5;
697 }
698Case_4:
699 RBTREE_NODE_SET_COLOR_TO_RED(S);
700 RBTREE_NODE_SET_COLOR_TO_BLACK(P);
701 return;
702Case_5:
703 RBTREE_ROTATE_DIR(rootptr_ptr, S, 1 - dir);
704 RBTREE_NODE_SET_COLOR_TO_RED(S);
705 RBTREE_NODE_SET_COLOR_TO_BLACK(C);
706 D = S;
707 S = C;
708Case_6:
709 RBTREE_ROTATE_DIR(rootptr_ptr, P, dir);
710 RBTREE_NODE_SET_COLOR_TO_COLOR_OF_OTHER(S, P);
711 RBTREE_NODE_SET_COLOR_TO_BLACK(P);
712 RBTREE_NODE_SET_COLOR_TO_BLACK(D);
713 return;
714}
716
717#endif
718
719// }}}
720
721// macro undefs: {{{
722
723#undef NAME
724#undef KEY_TYPE
725#undef VALUE_TYPE
726#undef KEY_IS_STRICTLY_LESS
727#undef ALLOW_DUPLICATES
728#undef KEY_MEMBER_IS_FIRST
729#undef FUNCTION_DEFINITIONS
730#undef TYPE_DEFINITIONS
731
732#undef RBTREE_NAME
733#undef RBTREE_TYPE
734#undef RBTREE_NODE_TYPE
735
736#undef RBTREE_NODE_IS_RED
737#undef RBTREE_NODE_IS_BLACK
738#undef RBTREE_NODE_GET_PARENT_PTR
739#undef RBTREE_NODE_TRANSPLANT
740#undef RBTREE_NODE_SET_COLOR_TO_COLOR_OF_OTHER
741#undef RBTREE_NODE_SET_COLOR_TO_RED
742#undef RBTREE_NODE_SET_COLOR_TO_BLACK
743#undef RBTREE_NODE_SET_PARENT_PTR
744
745#undef RBTREE_CONTAINS_KEY
746#undef RBTREE_INSERT_FIXUP
747#undef RBTREE_DELETE_FIXUP
748#undef RBTREE_CHILD_DIR
749
750// }}}
751
752#ifdef __cplusplus
753}
754#endif
755
756// vim: ft=c fdm=marker
#define KEY_TYPE
The key type. This must be manually defined before including this header file.
Definition fhashtable_template.h:171
#define FUNCTION_LINKAGE
Specify function linkage e.g. static inline.
Definition fstack_template.h:145
#define JOIN(a, b)
First expand tokens, then paste them together with a _ in between.
Definition fstack_template.h:50
#define JOIN(a, b)
First expand tokens, then paste them together with a _ in between.
Definition rbtree_template.h:66
#define KEY_TYPE
The key type. This must be manually defined before including this header file.
Definition rbtree_template.h:92
#define KEY_IS_STRICTLY_LESS(a, b)
Used to compare two keys. This must be manually defined before including this header file.
Definition rbtree_template.h:289
rbtree_node_type * child_ptrs[2]
array of child pointers
Definition rbtree_template.h:171
uintptr_t __parent_ptr_with_color_bit
Definition rbtree_template.h:164
rbtree_node_type * left_ptr
pointer to left node
Definition rbtree_template.h:168
KEY_TYPE key
node key
Definition rbtree_template.h:174
rbtree_node_type * right_ptr
pointer to right node
Definition rbtree_template.h:169