50#define PASTE(a, b) a##b
58#define XPASTE(a, b) PASTE(a, b)
66#define JOIN(a, b) XPASTE(a, XPASTE(_, b))
77#error "Must define NAME."
79#define RBTREE_NAME NAME
90#define FUNCTION_DEFINITIONS
91#define TYPE_DEFINITIONS
93#error "Must define KEY_TYPE."
109#ifndef KEY_IS_STRICTLY_LESS
110#error "Must define KEY_IS_STRICTLY_LESS."
111#define KEY_IS_STRICTLY_LESS(a, b) ((a) < (b))
126#ifdef ALLOW_DUPLICATES
133#ifdef KEY_MEMBER_IS_FIRST
140#ifndef FUNCTION_LINKAGE
141#define FUNCTION_LINKAGE
145#define RBTREE_NODE_TYPE struct JOIN(RBTREE_NAME, node)
146#define RBTREE_CONTAINS_KEY JOIN(RBTREE_NAME, contains_key)
147#define RBTREE_NODE_IS_RED JOIN(RBTREE_NAME, node_is_red)
148#define RBTREE_NODE_IS_BLACK JOIN(RBTREE_NAME, node_is_black)
149#define RBTREE_NODE_GET_PARENT_PTR JOIN(RBTREE_NAME, node_get_parent_ptr)
150#define RBTREE_INSERT_FIXUP JOIN(internal, JOIN(RBTREE_NAME, insert_fixup))
151#define RBTREE_DELETE_FIXUP JOIN(internal, JOIN(RBTREE_NAME, delete_fixup))
153#define RBTREE_NODE_TRANSPLANT JOIN(internal, JOIN(RBTREE_NAME, node_transplant))
154#define RBTREE_NODE_SET_COLOR_TO_RED JOIN(internal, JOIN(RBTREE_NAME, node_set_color_to_red))
155#define RBTREE_NODE_SET_COLOR_TO_BLACK JOIN(internal, JOIN(RBTREE_NAME, node_set_color_to_black))
156#define RBTREE_NODE_SET_PARENT_PTR JOIN(internal, JOIN(RBTREE_NAME, node_set_parent_ptr))
157#define RBTREE_NODE_SET_COLOR_TO_COLOR_OF_OTHER JOIN(internal, JOIN(RBTREE_NAME, node_set_color_to_color_of_other))
158#define RBTREE_ROTATE_DIR JOIN(internal, JOIN(RBTREE_NAME, rotate_dir))
160#define RBTREE_CHILD_DIR(node_ptr) ((node_ptr) == RBTREE_NODE_GET_PARENT_PTR(node_ptr)->left_ptr ? 0 : 1)
172struct JOIN(RBTREE_NAME, node);
174#ifdef TYPE_DEFINITIONS
179struct JOIN(RBTREE_NAME, node) {
180#ifdef KEY_MEMBER_IS_FIRST
192#ifndef KEY_MEMBER_IS_FIRST
216FUNCTION_LINKAGE RBTREE_NODE_TYPE *
JOIN(RBTREE_NAME, node_get_parent_ptr)(RBTREE_NODE_TYPE *node_ptr);
268FUNCTION_LINKAGE void JOIN(RBTREE_NAME, insert_node)(RBTREE_NODE_TYPE **rootptr_ptr, RBTREE_NODE_TYPE *node_ptr);
278FUNCTION_LINKAGE RBTREE_NODE_TYPE *
JOIN(RBTREE_NAME, delete_node)(RBTREE_NODE_TYPE **rootptr_ptr,
279 RBTREE_NODE_TYPE *node_ptr);
289#ifdef FUNCTION_DEFINITIONS
295static inline void JOIN(internal,
JOIN(RBTREE_NAME, node_set_color_to_red))(RBTREE_NODE_TYPE *node_ptr)
297 node_ptr->__parent_ptr_with_color_bit &= ~(uintptr_t)1;
300static inline void JOIN(internal,
JOIN(RBTREE_NAME, node_set_color_to_black))(RBTREE_NODE_TYPE *node_ptr)
302 node_ptr->__parent_ptr_with_color_bit |= 1;
305static inline void JOIN(internal,
306 JOIN(RBTREE_NAME, node_set_color_to_color_of_other))(RBTREE_NODE_TYPE *node_ptr,
307 const RBTREE_NODE_TYPE *other_ptr)
309 const bool is_black = other_ptr->__parent_ptr_with_color_bit & 1;
311 node_ptr->__parent_ptr_with_color_bit &= ~(uintptr_t)1;
312 node_ptr->__parent_ptr_with_color_bit += is_black;
315static inline void JOIN(internal,
JOIN(RBTREE_NAME, node_set_parent_ptr))(RBTREE_NODE_TYPE *node_ptr,
316 RBTREE_NODE_TYPE *parent_ptr)
318 const bool is_black = node_ptr->__parent_ptr_with_color_bit & 1;
320 node_ptr->__parent_ptr_with_color_bit = (uintptr_t)parent_ptr;
321 node_ptr->__parent_ptr_with_color_bit += is_black;
326static inline RBTREE_NODE_TYPE *
JOIN(internal,
JOIN(RBTREE_NAME, rotate_dir))(RBTREE_NODE_TYPE **rootptr_ptr,
327 RBTREE_NODE_TYPE *P,
const int dir);
330static inline void JOIN(internal,
JOIN(RBTREE_NAME, insert_fixup))(RBTREE_NODE_TYPE **rootptr_ptr, RBTREE_NODE_TYPE *N);
333static inline void JOIN(internal,
JOIN(RBTREE_NAME, node_transplant))(RBTREE_NODE_TYPE **rootptr_ptr,
334 RBTREE_NODE_TYPE *src_node,
335 RBTREE_NODE_TYPE *dest_node);
339static inline void JOIN(internal,
JOIN(RBTREE_NAME, delete_fixup))(RBTREE_NODE_TYPE **rootptr_ptr, RBTREE_NODE_TYPE *P,
347 assert(node_ptr != NULL);
350 node_ptr->left_ptr = node_ptr->right_ptr = NULL;
351 RBTREE_NODE_SET_PARENT_PTR(node_ptr, NULL);
356 assert(node_ptr != NULL);
358 return (RBTREE_NODE_TYPE *)(node_ptr->__parent_ptr_with_color_bit & ~(uintptr_t)1);
363 assert(node_ptr != NULL);
365 return (node_ptr->__parent_ptr_with_color_bit & 1);
370 assert(node_ptr != NULL);
372 return !RBTREE_NODE_IS_BLACK(node_ptr);
377 assert(rootptr_ptr != NULL);
379 return *rootptr_ptr == NULL;
384 assert(rootptr_ptr != NULL);
386 RBTREE_NODE_TYPE *node_ptr = *rootptr_ptr;
388 while (node_ptr != NULL) {
391 const bool is_equal = !is_strictly_less && !is_strictly_greater;
396 else if (is_strictly_less) {
397 node_ptr = node_ptr->left_ptr;
400 node_ptr = node_ptr->right_ptr;
408 assert(rootptr_ptr != NULL);
410 RBTREE_NODE_TYPE *node_ptr = *rootptr_ptr;
411 while (node_ptr != NULL) {
414 const bool is_equal = !is_strictly_less && !is_strictly_greater;
419 else if (is_strictly_less) {
420 node_ptr = node_ptr->left_ptr;
423 node_ptr = node_ptr->right_ptr;
429FUNCTION_LINKAGE void JOIN(RBTREE_NAME, insert_node)(RBTREE_NODE_TYPE **rootptr_ptr, RBTREE_NODE_TYPE *node_ptr)
431 assert(rootptr_ptr != NULL);
432 assert(node_ptr != NULL);
433#ifndef ALLOW_DUPLICATES
434 assert(RBTREE_CONTAINS_KEY(rootptr_ptr, node_ptr->key) ==
false);
437 RBTREE_NODE_TYPE *parent_ptr = NULL;
438 RBTREE_NODE_TYPE *current_ptr = *rootptr_ptr;
440 while (current_ptr != NULL) {
443 parent_ptr = current_ptr;
445 if (is_strictly_greater) {
446 current_ptr = current_ptr->right_ptr;
449 current_ptr = current_ptr->left_ptr;
453 node_ptr->left_ptr = node_ptr->right_ptr = NULL;
454 RBTREE_NODE_SET_PARENT_PTR(node_ptr, parent_ptr);
455 RBTREE_NODE_SET_COLOR_TO_RED(node_ptr);
457 if (parent_ptr == NULL) {
458 *rootptr_ptr = node_ptr;
463 parent_ptr->child_ptrs[dir] = node_ptr;
465 RBTREE_INSERT_FIXUP(rootptr_ptr, node_ptr);
470 RBTREE_NODE_TYPE *node_ptr)
472 assert(rootptr_ptr != NULL);
473 assert(node_ptr != NULL);
475 if (node_ptr->left_ptr == NULL && node_ptr->right_ptr == NULL) {
476 if (node_ptr == *rootptr_ptr || RBTREE_NODE_IS_RED(node_ptr)) {
477 RBTREE_NODE_TRANSPLANT(rootptr_ptr, node_ptr, NULL);
480 RBTREE_NODE_TYPE *
const parent_ptr = RBTREE_NODE_GET_PARENT_PTR(node_ptr);
482 const int dir = RBTREE_CHILD_DIR(node_ptr) ? 1 : 0;
484 RBTREE_NODE_TRANSPLANT(rootptr_ptr, node_ptr, NULL);
486 RBTREE_DELETE_FIXUP(rootptr_ptr, parent_ptr, dir);
489 else if (node_ptr->left_ptr == NULL || node_ptr->right_ptr == NULL) {
490 const int dir = node_ptr->left_ptr == NULL;
492 assert(RBTREE_NODE_IS_BLACK(node_ptr));
493 assert(RBTREE_NODE_IS_RED(node_ptr->child_ptrs[dir]));
495 RBTREE_NODE_SET_COLOR_TO_BLACK(node_ptr->child_ptrs[dir]);
497 RBTREE_NODE_TRANSPLANT(rootptr_ptr, node_ptr, node_ptr->child_ptrs[dir]);
500 RBTREE_NODE_TYPE *successor_ptr = node_ptr->right_ptr;
502 while (successor_ptr->left_ptr != NULL) {
503 successor_ptr = successor_ptr->left_ptr;
506 const bool prev_successor_black = RBTREE_NODE_IS_BLACK(successor_ptr);
508 const int prev_successor_dir = RBTREE_CHILD_DIR(successor_ptr);
510 RBTREE_NODE_TYPE *
const prev_successor_parent_ptr = RBTREE_NODE_GET_PARENT_PTR(successor_ptr);
512 RBTREE_NODE_TYPE *
const prev_successor_child_ptr = successor_ptr->right_ptr;
515 if (RBTREE_NODE_GET_PARENT_PTR(successor_ptr) != node_ptr) {
516 RBTREE_NODE_TRANSPLANT(rootptr_ptr, successor_ptr, successor_ptr->right_ptr);
518 successor_ptr->right_ptr = node_ptr->right_ptr;
519 RBTREE_NODE_SET_PARENT_PTR(node_ptr->right_ptr, successor_ptr);
521 RBTREE_NODE_TRANSPLANT(rootptr_ptr, node_ptr, successor_ptr);
523 successor_ptr->left_ptr = node_ptr->left_ptr;
524 RBTREE_NODE_SET_PARENT_PTR(node_ptr->left_ptr, successor_ptr);
526 RBTREE_NODE_SET_COLOR_TO_COLOR_OF_OTHER(successor_ptr, node_ptr);
529 if (prev_successor_child_ptr != NULL) {
530 assert(prev_successor_black);
531 assert(RBTREE_NODE_IS_RED(prev_successor_child_ptr));
533 RBTREE_NODE_SET_COLOR_TO_BLACK(prev_successor_child_ptr);
535 else if (prev_successor_child_ptr == NULL && prev_successor_black) {
536 RBTREE_NODE_TYPE *actual_successor_ptr =
537 (prev_successor_parent_ptr == node_ptr) ? successor_ptr : prev_successor_parent_ptr;
539 RBTREE_DELETE_FIXUP(rootptr_ptr, actual_successor_ptr, prev_successor_dir);
543 node_ptr->left_ptr = node_ptr->right_ptr = NULL;
544 RBTREE_NODE_SET_PARENT_PTR(node_ptr, NULL);
551static inline RBTREE_NODE_TYPE *
JOIN(internal,
JOIN(RBTREE_NAME, rotate_dir))(RBTREE_NODE_TYPE **rootptr_ptr,
552 RBTREE_NODE_TYPE *P,
const int dir)
573 RBTREE_NODE_TYPE *G = RBTREE_NODE_GET_PARENT_PTR(P);
574 RBTREE_NODE_TYPE *S = P->child_ptrs[1 - dir];
576 RBTREE_NODE_TYPE *C = S->child_ptrs[dir];
578 P->child_ptrs[1 - dir] = C;
580 RBTREE_NODE_SET_PARENT_PTR(C, P);
583 S->child_ptrs[dir] = P;
584 RBTREE_NODE_SET_PARENT_PTR(P, S);
586 RBTREE_NODE_SET_PARENT_PTR(S, G);
588 G->child_ptrs[P == G->left_ptr ? 0 : 1] = S;
596static inline void JOIN(internal,
JOIN(RBTREE_NAME, insert_fixup))(RBTREE_NODE_TYPE **rootptr_ptr, RBTREE_NODE_TYPE *N)
598 assert(RBTREE_NODE_IS_RED(N));
599 assert(N != *rootptr_ptr);
601 RBTREE_NODE_TYPE *P = RBTREE_NODE_GET_PARENT_PTR(N);
602 RBTREE_NODE_TYPE *G = NULL;
603 RBTREE_NODE_TYPE *U = NULL;
606 if (RBTREE_NODE_IS_BLACK(P)) {
609 if ((G = RBTREE_NODE_GET_PARENT_PTR(P)) == NULL) {
610 RBTREE_NODE_SET_COLOR_TO_BLACK(P);
613 const int dir = RBTREE_CHILD_DIR(P);
614 U = G->child_ptrs[1 - dir];
616 if (U == NULL || RBTREE_NODE_IS_BLACK(U)) {
617 if (N == P->child_ptrs[1 - dir]) {
618 RBTREE_ROTATE_DIR(rootptr_ptr, P, dir);
620 P = G->child_ptrs[dir];
622 RBTREE_NODE_SET_COLOR_TO_BLACK(P);
623 RBTREE_NODE_SET_COLOR_TO_RED(G);
624 RBTREE_ROTATE_DIR(rootptr_ptr, G, 1 - dir);
628 RBTREE_NODE_SET_COLOR_TO_BLACK(P);
629 RBTREE_NODE_SET_COLOR_TO_BLACK(U);
630 RBTREE_NODE_SET_COLOR_TO_RED(G);
633 P = RBTREE_NODE_GET_PARENT_PTR(N);
637static inline void JOIN(internal,
JOIN(RBTREE_NAME, node_transplant))(RBTREE_NODE_TYPE **rootptr_ptr,
638 RBTREE_NODE_TYPE *src_node,
639 RBTREE_NODE_TYPE *dest_node)
641 RBTREE_NODE_TYPE *src_node_parent_ptr = RBTREE_NODE_GET_PARENT_PTR(src_node);
643 if (src_node_parent_ptr == NULL) {
644 *rootptr_ptr = dest_node;
647 src_node_parent_ptr->child_ptrs[RBTREE_CHILD_DIR(src_node)] = dest_node;
650 if (dest_node != NULL) {
651 RBTREE_NODE_SET_PARENT_PTR(dest_node, src_node_parent_ptr);
655static inline void JOIN(internal,
JOIN(RBTREE_NAME, delete_fixup))(RBTREE_NODE_TYPE **rootptr_ptr, RBTREE_NODE_TYPE *P,
658 RBTREE_NODE_TYPE *N = NULL;
659 RBTREE_NODE_TYPE *S = NULL;
660 RBTREE_NODE_TYPE *C = NULL;
661 RBTREE_NODE_TYPE *D = NULL;
664 S = P->child_ptrs[1 - dir];
665 D = S->child_ptrs[1 - dir];
666 C = S->child_ptrs[dir];
668 if (RBTREE_NODE_IS_RED(S)) {
671 if (D != NULL && RBTREE_NODE_IS_RED(D)) {
674 if (C != NULL && RBTREE_NODE_IS_RED(C)) {
677 if (RBTREE_NODE_IS_RED(P)) {
680 RBTREE_NODE_SET_COLOR_TO_RED(S);
683 P = RBTREE_NODE_GET_PARENT_PTR(N);
684 }
while (P != NULL && (dir = RBTREE_CHILD_DIR(N),
true));
688 RBTREE_ROTATE_DIR(rootptr_ptr, P, dir);
689 RBTREE_NODE_SET_COLOR_TO_RED(P);
690 RBTREE_NODE_SET_COLOR_TO_BLACK(S);
692 D = S->child_ptrs[1 - dir];
693 if (D != NULL && RBTREE_NODE_IS_RED(D)) {
696 C = S->child_ptrs[dir];
697 if (C != NULL && RBTREE_NODE_IS_RED(C)) {
701 RBTREE_NODE_SET_COLOR_TO_RED(S);
702 RBTREE_NODE_SET_COLOR_TO_BLACK(P);
705 RBTREE_ROTATE_DIR(rootptr_ptr, S, 1 - dir);
706 RBTREE_NODE_SET_COLOR_TO_RED(S);
707 RBTREE_NODE_SET_COLOR_TO_BLACK(C);
711 RBTREE_ROTATE_DIR(rootptr_ptr, P, dir);
712 RBTREE_NODE_SET_COLOR_TO_COLOR_OF_OTHER(S, P);
713 RBTREE_NODE_SET_COLOR_TO_BLACK(P);
714 RBTREE_NODE_SET_COLOR_TO_BLACK(D);
728#undef KEY_IS_STRICTLY_LESS
729#undef ALLOW_DUPLICATES
730#undef KEY_MEMBER_IS_FIRST
731#undef FUNCTION_DEFINITIONS
732#undef TYPE_DEFINITIONS
736#undef RBTREE_NODE_TYPE
738#undef RBTREE_NODE_IS_RED
739#undef RBTREE_NODE_IS_BLACK
740#undef RBTREE_NODE_GET_PARENT_PTR
741#undef RBTREE_NODE_TRANSPLANT
742#undef RBTREE_NODE_SET_COLOR_TO_COLOR_OF_OTHER
743#undef RBTREE_NODE_SET_COLOR_TO_RED
744#undef RBTREE_NODE_SET_COLOR_TO_BLACK
745#undef RBTREE_NODE_SET_PARENT_PTR
747#undef RBTREE_CONTAINS_KEY
748#undef RBTREE_INSERT_FIXUP
749#undef RBTREE_DELETE_FIXUP
750#undef RBTREE_CHILD_DIR
#define KEY_TYPE
The key type. This must be manually defined before including this header file.
Definition fhashtable_template.h:169
#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 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:111
rbtree_node_type * child_ptrs[2]
array of child pointers
Definition rbtree_template.h:190
uintptr_t __parent_ptr_with_color_bit
Definition rbtree_template.h:183
rbtree_node_type * left_ptr
pointer to left node
Definition rbtree_template.h:187
KEY_TYPE key
node key
Definition rbtree_template.h:193
rbtree_node_type * right_ptr
pointer to right node
Definition rbtree_template.h:188