48#define PASTE(a, b) a##b
56#define XPASTE(a, b) PASTE(a, b)
64#define JOIN(a, b) XPASTE(a, XPASTE(_, b))
75#error "Must define NAME."
77#define RBTREE_NAME NAME
88#define FUNCTION_DEFINITIONS
89#define TYPE_DEFINITIONS
91#error "Must define KEY_TYPE."
107#ifndef KEY_IS_STRICTLY_LESS
108#error "Must define KEY_IS_STRICTLY_LESS."
109#define KEY_IS_STRICTLY_LESS(a, b) ((a) < (b))
124#ifdef ALLOW_DUPLICATES
131#ifdef KEY_MEMBER_IS_FIRST
138#ifndef FUNCTION_LINKAGE
139#define FUNCTION_LINKAGE
143#define RBTREE_NODE_TYPE struct JOIN(RBTREE_NAME, node)
144#define RBTREE_CONTAINS_KEY JOIN(RBTREE_NAME, contains_key)
145#define RBTREE_NODE_IS_RED JOIN(RBTREE_NAME, node_is_red)
146#define RBTREE_NODE_IS_BLACK JOIN(RBTREE_NAME, node_is_black)
147#define RBTREE_NODE_GET_PARENT_PTR JOIN(RBTREE_NAME, node_get_parent_ptr)
148#define RBTREE_INSERT_FIXUP JOIN(internal, JOIN(RBTREE_NAME, insert_fixup))
149#define RBTREE_DELETE_FIXUP JOIN(internal, JOIN(RBTREE_NAME, delete_fixup))
151#define RBTREE_NODE_TRANSPLANT JOIN(internal, JOIN(RBTREE_NAME, node_transplant))
152#define RBTREE_NODE_SET_COLOR_TO_RED JOIN(internal, JOIN(RBTREE_NAME, node_set_color_to_red))
153#define RBTREE_NODE_SET_COLOR_TO_BLACK JOIN(internal, JOIN(RBTREE_NAME, node_set_color_to_black))
154#define RBTREE_NODE_SET_PARENT_PTR JOIN(internal, JOIN(RBTREE_NAME, node_set_parent_ptr))
155#define RBTREE_NODE_SET_COLOR_TO_COLOR_OF_OTHER JOIN(internal, JOIN(RBTREE_NAME, node_set_color_to_color_of_other))
156#define RBTREE_ROTATE_DIR JOIN(internal, JOIN(RBTREE_NAME, rotate_dir))
158#define RBTREE_CHILD_DIR(node_ptr) ((node_ptr) == RBTREE_NODE_GET_PARENT_PTR(node_ptr)->left_ptr ? 0 : 1)
170#ifdef TYPE_DEFINITIONS
175struct JOIN(RBTREE_NAME, node) {
176#ifdef KEY_MEMBER_IS_FIRST
188#ifndef KEY_MEMBER_IS_FIRST
221FUNCTION_LINKAGE RBTREE_NODE_TYPE *
JOIN(RBTREE_NAME, node_get_parent_ptr)(RBTREE_NODE_TYPE *node_ptr);
273FUNCTION_LINKAGE void JOIN(RBTREE_NAME, insert_node)(RBTREE_NODE_TYPE **rootptr_ptr, RBTREE_NODE_TYPE *node_ptr);
283FUNCTION_LINKAGE RBTREE_NODE_TYPE *
JOIN(RBTREE_NAME, delete_node)(RBTREE_NODE_TYPE **rootptr_ptr,
284 RBTREE_NODE_TYPE *node_ptr);
294#ifdef FUNCTION_DEFINITIONS
298static inline void JOIN(internal,
JOIN(RBTREE_NAME, node_set_color_to_red))(RBTREE_NODE_TYPE *node_ptr)
300 node_ptr->__parent_ptr_with_color_bit &= ~(uintptr_t)1;
303static inline void JOIN(internal,
JOIN(RBTREE_NAME, node_set_color_to_black))(RBTREE_NODE_TYPE *node_ptr)
305 node_ptr->__parent_ptr_with_color_bit |= 1;
308static inline void JOIN(internal,
309 JOIN(RBTREE_NAME, node_set_color_to_color_of_other))(RBTREE_NODE_TYPE *node_ptr,
310 const RBTREE_NODE_TYPE *other_ptr)
312 const bool is_black = other_ptr->__parent_ptr_with_color_bit & 1;
314 node_ptr->__parent_ptr_with_color_bit &= ~(uintptr_t)1;
315 node_ptr->__parent_ptr_with_color_bit += is_black;
318static inline void JOIN(internal,
JOIN(RBTREE_NAME, node_set_parent_ptr))(RBTREE_NODE_TYPE *node_ptr,
319 RBTREE_NODE_TYPE *parent_ptr)
321 const bool is_black = node_ptr->__parent_ptr_with_color_bit & 1;
323 node_ptr->__parent_ptr_with_color_bit = (uintptr_t)parent_ptr;
324 node_ptr->__parent_ptr_with_color_bit += is_black;
329static inline RBTREE_NODE_TYPE *
JOIN(internal,
JOIN(RBTREE_NAME, rotate_dir))(RBTREE_NODE_TYPE **rootptr_ptr,
330 RBTREE_NODE_TYPE *P,
const int dir);
333static inline void JOIN(internal,
JOIN(RBTREE_NAME, insert_fixup))(RBTREE_NODE_TYPE **rootptr_ptr, RBTREE_NODE_TYPE *N);
336static inline void JOIN(internal,
JOIN(RBTREE_NAME, node_transplant))(RBTREE_NODE_TYPE **rootptr_ptr,
337 RBTREE_NODE_TYPE *src_node,
338 RBTREE_NODE_TYPE *dest_node);
342static inline void JOIN(internal,
JOIN(RBTREE_NAME, delete_fixup))(RBTREE_NODE_TYPE **rootptr_ptr, RBTREE_NODE_TYPE *P,
349 assert(rootptr_ptr != NULL);
356 assert(node_ptr != NULL);
359 node_ptr->left_ptr = node_ptr->right_ptr = NULL;
360 RBTREE_NODE_SET_PARENT_PTR(node_ptr, NULL);
365 assert(node_ptr != NULL);
367 return (RBTREE_NODE_TYPE *)(node_ptr->__parent_ptr_with_color_bit & ~(uintptr_t)1);
372 assert(node_ptr != NULL);
374 return (node_ptr->__parent_ptr_with_color_bit & 1);
379 assert(node_ptr != NULL);
381 return !RBTREE_NODE_IS_BLACK(node_ptr);
386 assert(rootptr_ptr != NULL);
388 return *rootptr_ptr == NULL;
393 assert(rootptr_ptr != NULL);
395 RBTREE_NODE_TYPE *node_ptr = *rootptr_ptr;
397 while (node_ptr != NULL) {
400 const bool is_equal = !is_strictly_less && !is_strictly_greater;
405 else if (is_strictly_less) {
406 node_ptr = node_ptr->left_ptr;
409 node_ptr = node_ptr->right_ptr;
417 assert(rootptr_ptr != NULL);
419 RBTREE_NODE_TYPE *node_ptr = *rootptr_ptr;
420 while (node_ptr != NULL) {
423 const bool is_equal = !is_strictly_less && !is_strictly_greater;
428 else if (is_strictly_less) {
429 node_ptr = node_ptr->left_ptr;
432 node_ptr = node_ptr->right_ptr;
438FUNCTION_LINKAGE void JOIN(RBTREE_NAME, insert_node)(RBTREE_NODE_TYPE **rootptr_ptr, RBTREE_NODE_TYPE *node_ptr)
440 assert(rootptr_ptr != NULL);
441 assert(node_ptr != NULL);
442#ifndef ALLOW_DUPLICATES
443 assert(RBTREE_CONTAINS_KEY(rootptr_ptr, node_ptr->key) ==
false);
446 RBTREE_NODE_TYPE *parent_ptr = NULL;
447 RBTREE_NODE_TYPE *current_ptr = *rootptr_ptr;
449 while (current_ptr != NULL) {
452 parent_ptr = current_ptr;
454 if (is_strictly_greater) {
455 current_ptr = current_ptr->right_ptr;
458 current_ptr = current_ptr->left_ptr;
462 node_ptr->left_ptr = node_ptr->right_ptr = NULL;
463 RBTREE_NODE_SET_PARENT_PTR(node_ptr, parent_ptr);
464 RBTREE_NODE_SET_COLOR_TO_RED(node_ptr);
466 if (parent_ptr == NULL) {
467 *rootptr_ptr = node_ptr;
472 parent_ptr->child_ptrs[dir] = node_ptr;
474 RBTREE_INSERT_FIXUP(rootptr_ptr, node_ptr);
479 RBTREE_NODE_TYPE *node_ptr)
481 assert(rootptr_ptr != NULL);
482 assert(node_ptr != NULL);
484 if (node_ptr->left_ptr == NULL && node_ptr->right_ptr == NULL) {
485 if (node_ptr == *rootptr_ptr || RBTREE_NODE_IS_RED(node_ptr)) {
486 RBTREE_NODE_TRANSPLANT(rootptr_ptr, node_ptr, NULL);
489 RBTREE_NODE_TYPE *
const parent_ptr = RBTREE_NODE_GET_PARENT_PTR(node_ptr);
491 const int dir = RBTREE_CHILD_DIR(node_ptr) ? 1 : 0;
493 RBTREE_NODE_TRANSPLANT(rootptr_ptr, node_ptr, NULL);
495 RBTREE_DELETE_FIXUP(rootptr_ptr, parent_ptr, dir);
498 else if (node_ptr->left_ptr == NULL || node_ptr->right_ptr == NULL) {
499 const int dir = node_ptr->left_ptr == NULL;
501 assert(RBTREE_NODE_IS_BLACK(node_ptr));
502 assert(RBTREE_NODE_IS_RED(node_ptr->child_ptrs[dir]));
504 RBTREE_NODE_SET_COLOR_TO_BLACK(node_ptr->child_ptrs[dir]);
506 RBTREE_NODE_TRANSPLANT(rootptr_ptr, node_ptr, node_ptr->child_ptrs[dir]);
509 RBTREE_NODE_TYPE *successor_ptr = node_ptr->right_ptr;
511 while (successor_ptr->left_ptr != NULL) {
512 successor_ptr = successor_ptr->left_ptr;
515 const bool prev_successor_black = RBTREE_NODE_IS_BLACK(successor_ptr);
517 const int prev_successor_dir = RBTREE_CHILD_DIR(successor_ptr);
519 RBTREE_NODE_TYPE *
const prev_successor_parent_ptr = RBTREE_NODE_GET_PARENT_PTR(successor_ptr);
521 RBTREE_NODE_TYPE *
const prev_successor_child_ptr = successor_ptr->right_ptr;
524 if (RBTREE_NODE_GET_PARENT_PTR(successor_ptr) != node_ptr) {
525 RBTREE_NODE_TRANSPLANT(rootptr_ptr, successor_ptr, successor_ptr->right_ptr);
527 successor_ptr->right_ptr = node_ptr->right_ptr;
528 RBTREE_NODE_SET_PARENT_PTR(node_ptr->right_ptr, successor_ptr);
530 RBTREE_NODE_TRANSPLANT(rootptr_ptr, node_ptr, successor_ptr);
532 successor_ptr->left_ptr = node_ptr->left_ptr;
533 RBTREE_NODE_SET_PARENT_PTR(node_ptr->left_ptr, successor_ptr);
535 RBTREE_NODE_SET_COLOR_TO_COLOR_OF_OTHER(successor_ptr, node_ptr);
538 if (prev_successor_child_ptr != NULL) {
539 assert(prev_successor_black);
540 assert(RBTREE_NODE_IS_RED(prev_successor_child_ptr));
542 RBTREE_NODE_SET_COLOR_TO_BLACK(prev_successor_child_ptr);
544 else if (prev_successor_child_ptr == NULL && prev_successor_black) {
545 RBTREE_NODE_TYPE *actual_successor_ptr =
546 (prev_successor_parent_ptr == node_ptr) ? successor_ptr : prev_successor_parent_ptr;
548 RBTREE_DELETE_FIXUP(rootptr_ptr, actual_successor_ptr, prev_successor_dir);
552 node_ptr->left_ptr = node_ptr->right_ptr = NULL;
553 RBTREE_NODE_SET_PARENT_PTR(node_ptr, NULL);
560static inline RBTREE_NODE_TYPE *
JOIN(internal,
JOIN(RBTREE_NAME, rotate_dir))(RBTREE_NODE_TYPE **rootptr_ptr,
561 RBTREE_NODE_TYPE *P,
const int dir)
582 RBTREE_NODE_TYPE *G = RBTREE_NODE_GET_PARENT_PTR(P);
583 RBTREE_NODE_TYPE *S = P->child_ptrs[1 - dir];
585 RBTREE_NODE_TYPE *C = S->child_ptrs[dir];
587 P->child_ptrs[1 - dir] = C;
589 RBTREE_NODE_SET_PARENT_PTR(C, P);
592 S->child_ptrs[dir] = P;
593 RBTREE_NODE_SET_PARENT_PTR(P, S);
595 RBTREE_NODE_SET_PARENT_PTR(S, G);
597 G->child_ptrs[P == G->left_ptr ? 0 : 1] = S;
605static inline void JOIN(internal,
JOIN(RBTREE_NAME, insert_fixup))(RBTREE_NODE_TYPE **rootptr_ptr, RBTREE_NODE_TYPE *N)
607 assert(RBTREE_NODE_IS_RED(N));
608 assert(N != *rootptr_ptr);
610 RBTREE_NODE_TYPE *P = RBTREE_NODE_GET_PARENT_PTR(N);
611 RBTREE_NODE_TYPE *G = NULL;
612 RBTREE_NODE_TYPE *U = NULL;
615 if (RBTREE_NODE_IS_BLACK(P)) {
618 if ((G = RBTREE_NODE_GET_PARENT_PTR(P)) == NULL) {
619 RBTREE_NODE_SET_COLOR_TO_BLACK(P);
622 const int dir = RBTREE_CHILD_DIR(P);
623 U = G->child_ptrs[1 - dir];
625 if (U == NULL || RBTREE_NODE_IS_BLACK(U)) {
626 if (N == P->child_ptrs[1 - dir]) {
627 RBTREE_ROTATE_DIR(rootptr_ptr, P, dir);
629 P = G->child_ptrs[dir];
631 RBTREE_NODE_SET_COLOR_TO_BLACK(P);
632 RBTREE_NODE_SET_COLOR_TO_RED(G);
633 RBTREE_ROTATE_DIR(rootptr_ptr, G, 1 - dir);
637 RBTREE_NODE_SET_COLOR_TO_BLACK(P);
638 RBTREE_NODE_SET_COLOR_TO_BLACK(U);
639 RBTREE_NODE_SET_COLOR_TO_RED(G);
642 P = RBTREE_NODE_GET_PARENT_PTR(N);
646static inline void JOIN(internal,
JOIN(RBTREE_NAME, node_transplant))(RBTREE_NODE_TYPE **rootptr_ptr,
647 RBTREE_NODE_TYPE *src_node,
648 RBTREE_NODE_TYPE *dest_node)
650 RBTREE_NODE_TYPE *src_node_parent_ptr = RBTREE_NODE_GET_PARENT_PTR(src_node);
652 if (src_node_parent_ptr == NULL) {
653 *rootptr_ptr = dest_node;
656 src_node_parent_ptr->child_ptrs[RBTREE_CHILD_DIR(src_node)] = dest_node;
659 if (dest_node != NULL) {
660 RBTREE_NODE_SET_PARENT_PTR(dest_node, src_node_parent_ptr);
664static inline void JOIN(internal,
JOIN(RBTREE_NAME, delete_fixup))(RBTREE_NODE_TYPE **rootptr_ptr, RBTREE_NODE_TYPE *P,
667 RBTREE_NODE_TYPE *N = NULL;
668 RBTREE_NODE_TYPE *S = NULL;
669 RBTREE_NODE_TYPE *C = NULL;
670 RBTREE_NODE_TYPE *D = NULL;
673 S = P->child_ptrs[1 - dir];
674 D = S->child_ptrs[1 - dir];
675 C = S->child_ptrs[dir];
677 if (RBTREE_NODE_IS_RED(S)) {
680 if (D != NULL && RBTREE_NODE_IS_RED(D)) {
683 if (C != NULL && RBTREE_NODE_IS_RED(C)) {
686 if (RBTREE_NODE_IS_RED(P)) {
689 RBTREE_NODE_SET_COLOR_TO_RED(S);
692 P = RBTREE_NODE_GET_PARENT_PTR(N);
693 }
while (P != NULL && (dir = RBTREE_CHILD_DIR(N),
true));
697 RBTREE_ROTATE_DIR(rootptr_ptr, P, dir);
698 RBTREE_NODE_SET_COLOR_TO_RED(P);
699 RBTREE_NODE_SET_COLOR_TO_BLACK(S);
701 D = S->child_ptrs[1 - dir];
702 if (D != NULL && RBTREE_NODE_IS_RED(D)) {
705 C = S->child_ptrs[dir];
706 if (C != NULL && RBTREE_NODE_IS_RED(C)) {
710 RBTREE_NODE_SET_COLOR_TO_RED(S);
711 RBTREE_NODE_SET_COLOR_TO_BLACK(P);
714 RBTREE_ROTATE_DIR(rootptr_ptr, S, 1 - dir);
715 RBTREE_NODE_SET_COLOR_TO_RED(S);
716 RBTREE_NODE_SET_COLOR_TO_BLACK(C);
720 RBTREE_ROTATE_DIR(rootptr_ptr, P, dir);
721 RBTREE_NODE_SET_COLOR_TO_COLOR_OF_OTHER(S, P);
722 RBTREE_NODE_SET_COLOR_TO_BLACK(P);
723 RBTREE_NODE_SET_COLOR_TO_BLACK(D);
737#undef KEY_IS_STRICTLY_LESS
738#undef ALLOW_DUPLICATES
739#undef KEY_MEMBER_IS_FIRST
740#undef FUNCTION_DEFINITIONS
741#undef TYPE_DEFINITIONS
745#undef RBTREE_NODE_TYPE
747#undef RBTREE_NODE_IS_RED
748#undef RBTREE_NODE_IS_BLACK
749#undef RBTREE_NODE_GET_PARENT_PTR
750#undef RBTREE_NODE_TRANSPLANT
751#undef RBTREE_NODE_SET_COLOR_TO_COLOR_OF_OTHER
752#undef RBTREE_NODE_SET_COLOR_TO_RED
753#undef RBTREE_NODE_SET_COLOR_TO_BLACK
754#undef RBTREE_NODE_SET_PARENT_PTR
756#undef RBTREE_CONTAINS_KEY
757#undef RBTREE_INSERT_FIXUP
758#undef RBTREE_DELETE_FIXUP
759#undef RBTREE_CHILD_DIR
#define KEY_TYPE
The key type. This must be manually defined before including this header file.
Definition fhashtable_template.h:166
#define FUNCTION_LINKAGE
Specify function linkage e.g. static inline.
Definition fstack_template.h:146
#define JOIN(a, b)
First expand tokens, then paste them together with a _ in between.
Definition rbtree_template.h:64
#define KEY_TYPE
The key type. This must be manually defined before including this header file.
Definition rbtree_template.h:90
#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:109
rbtree_node_type * child_ptrs[2]
array of child pointers
Definition rbtree_template.h:186
uintptr_t __parent_ptr_with_color_bit
Definition rbtree_template.h:179
rbtree_node_type * left_ptr
pointer to left node
Definition rbtree_template.h:183
KEY_TYPE key
node key
Definition rbtree_template.h:189
rbtree_node_type * right_ptr
pointer to right node
Definition rbtree_template.h:184