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."
78#define FUNCTION_DEFINITIONS
79#define TYPE_DEFINITIONS
81#define RBTREE_NAME NAME
93#error "Must define KEY_TYPE."
108#ifdef ALLOW_DUPLICATES
115#ifdef KEY_MEMBER_IS_FIRST
122#ifndef FUNCTION_LINKAGE
123#define FUNCTION_LINKAGE
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))
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))
142#define RBTREE_CHILD_DIR(node_ptr) ((node_ptr) == RBTREE_NODE_GET_PARENT_PTR(node_ptr)->left_ptr ? 0 : 1)
149struct JOIN(RBTREE_NAME, node);
155#ifdef TYPE_DEFINITIONS
160struct JOIN(RBTREE_NAME, node) {
161#ifdef KEY_MEMBER_IS_FIRST
173#ifndef KEY_MEMBER_IS_FIRST
197FUNCTION_LINKAGE RBTREE_NODE_TYPE *
JOIN(RBTREE_NAME, node_get_parent_ptr)(RBTREE_NODE_TYPE *node_ptr);
249FUNCTION_LINKAGE void JOIN(RBTREE_NAME, insert_node)(RBTREE_NODE_TYPE **rootptr_ptr, RBTREE_NODE_TYPE *node_ptr);
259FUNCTION_LINKAGE RBTREE_NODE_TYPE *
JOIN(RBTREE_NAME, delete_node)(RBTREE_NODE_TYPE **rootptr_ptr,
260 RBTREE_NODE_TYPE *node_ptr);
270#ifdef FUNCTION_DEFINITIONS
287#ifndef KEY_IS_STRICTLY_LESS
288#error "Must define KEY_IS_STRICTLY_LESS."
289#define KEY_IS_STRICTLY_LESS(a, b) ((a) < (b))
294static inline void JOIN(internal,
JOIN(RBTREE_NAME, node_set_color_to_red))(RBTREE_NODE_TYPE *node_ptr)
296 node_ptr->__parent_ptr_with_color_bit &= ~(uintptr_t)1;
299static inline void JOIN(internal,
JOIN(RBTREE_NAME, node_set_color_to_black))(RBTREE_NODE_TYPE *node_ptr)
301 node_ptr->__parent_ptr_with_color_bit |= 1;
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)
308 const bool is_black = other_ptr->__parent_ptr_with_color_bit & 1;
310 node_ptr->__parent_ptr_with_color_bit &= ~(uintptr_t)1;
311 node_ptr->__parent_ptr_with_color_bit += is_black;
314static inline void JOIN(internal,
JOIN(RBTREE_NAME, node_set_parent_ptr))(RBTREE_NODE_TYPE *node_ptr,
315 RBTREE_NODE_TYPE *parent_ptr)
317 const bool is_black = node_ptr->__parent_ptr_with_color_bit & 1;
319 node_ptr->__parent_ptr_with_color_bit = (uintptr_t)parent_ptr;
320 node_ptr->__parent_ptr_with_color_bit += is_black;
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);
329static inline void JOIN(internal,
JOIN(RBTREE_NAME, insert_fixup))(RBTREE_NODE_TYPE **rootptr_ptr, RBTREE_NODE_TYPE *N);
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);
338static inline void JOIN(internal,
JOIN(RBTREE_NAME, delete_fixup))(RBTREE_NODE_TYPE **rootptr_ptr, RBTREE_NODE_TYPE *P,
345 assert(node_ptr != NULL);
348 node_ptr->left_ptr = node_ptr->right_ptr = NULL;
349 RBTREE_NODE_SET_PARENT_PTR(node_ptr, NULL);
354 assert(node_ptr != NULL);
356 return (RBTREE_NODE_TYPE *)(node_ptr->__parent_ptr_with_color_bit & ~(uintptr_t)1);
361 assert(node_ptr != NULL);
363 return (node_ptr->__parent_ptr_with_color_bit & 1);
368 assert(node_ptr != NULL);
370 return !RBTREE_NODE_IS_BLACK(node_ptr);
375 assert(rootptr_ptr != NULL);
377 return *rootptr_ptr == NULL;
382 assert(rootptr_ptr != NULL);
384 RBTREE_NODE_TYPE *node_ptr = *rootptr_ptr;
386 while (node_ptr != NULL) {
389 const bool is_equal = !is_strictly_less && !is_strictly_greater;
394 else if (is_strictly_less) {
395 node_ptr = node_ptr->left_ptr;
398 node_ptr = node_ptr->right_ptr;
406 assert(rootptr_ptr != NULL);
408 RBTREE_NODE_TYPE *node_ptr = *rootptr_ptr;
409 while (node_ptr != NULL) {
412 const bool is_equal = !is_strictly_less && !is_strictly_greater;
417 else if (is_strictly_less) {
418 node_ptr = node_ptr->left_ptr;
421 node_ptr = node_ptr->right_ptr;
427FUNCTION_LINKAGE void JOIN(RBTREE_NAME, insert_node)(RBTREE_NODE_TYPE **rootptr_ptr, RBTREE_NODE_TYPE *node_ptr)
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);
435 RBTREE_NODE_TYPE *parent_ptr = NULL;
436 RBTREE_NODE_TYPE *current_ptr = *rootptr_ptr;
438 while (current_ptr != NULL) {
441 parent_ptr = current_ptr;
443 if (is_strictly_greater) {
444 current_ptr = current_ptr->right_ptr;
447 current_ptr = current_ptr->left_ptr;
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);
455 if (parent_ptr == NULL) {
456 *rootptr_ptr = node_ptr;
461 parent_ptr->child_ptrs[dir] = node_ptr;
463 RBTREE_INSERT_FIXUP(rootptr_ptr, node_ptr);
468 RBTREE_NODE_TYPE *node_ptr)
470 assert(rootptr_ptr != NULL);
471 assert(node_ptr != NULL);
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);
478 RBTREE_NODE_TYPE *
const parent_ptr = RBTREE_NODE_GET_PARENT_PTR(node_ptr);
480 const int dir = RBTREE_CHILD_DIR(node_ptr) ? 1 : 0;
482 RBTREE_NODE_TRANSPLANT(rootptr_ptr, node_ptr, NULL);
484 RBTREE_DELETE_FIXUP(rootptr_ptr, parent_ptr, dir);
487 else if (node_ptr->left_ptr == NULL || node_ptr->right_ptr == NULL) {
488 const int dir = node_ptr->left_ptr == NULL;
490 assert(RBTREE_NODE_IS_BLACK(node_ptr));
491 assert(RBTREE_NODE_IS_RED(node_ptr->child_ptrs[dir]));
493 RBTREE_NODE_SET_COLOR_TO_BLACK(node_ptr->child_ptrs[dir]);
495 RBTREE_NODE_TRANSPLANT(rootptr_ptr, node_ptr, node_ptr->child_ptrs[dir]);
498 RBTREE_NODE_TYPE *successor_ptr = node_ptr->right_ptr;
500 while (successor_ptr->left_ptr != NULL) {
501 successor_ptr = successor_ptr->left_ptr;
504 const bool prev_successor_black = RBTREE_NODE_IS_BLACK(successor_ptr);
506 const int prev_successor_dir = RBTREE_CHILD_DIR(successor_ptr);
508 RBTREE_NODE_TYPE *
const prev_successor_parent_ptr = RBTREE_NODE_GET_PARENT_PTR(successor_ptr);
510 RBTREE_NODE_TYPE *
const prev_successor_child_ptr = successor_ptr->right_ptr;
513 if (RBTREE_NODE_GET_PARENT_PTR(successor_ptr) != node_ptr) {
514 RBTREE_NODE_TRANSPLANT(rootptr_ptr, successor_ptr, successor_ptr->right_ptr);
516 successor_ptr->right_ptr = node_ptr->right_ptr;
517 RBTREE_NODE_SET_PARENT_PTR(node_ptr->right_ptr, successor_ptr);
519 RBTREE_NODE_TRANSPLANT(rootptr_ptr, node_ptr, successor_ptr);
521 successor_ptr->left_ptr = node_ptr->left_ptr;
522 RBTREE_NODE_SET_PARENT_PTR(node_ptr->left_ptr, successor_ptr);
524 RBTREE_NODE_SET_COLOR_TO_COLOR_OF_OTHER(successor_ptr, node_ptr);
527 if (prev_successor_child_ptr != NULL) {
528 assert(prev_successor_black);
529 assert(RBTREE_NODE_IS_RED(prev_successor_child_ptr));
531 RBTREE_NODE_SET_COLOR_TO_BLACK(prev_successor_child_ptr);
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;
537 RBTREE_DELETE_FIXUP(rootptr_ptr, actual_successor_ptr, prev_successor_dir);
541 node_ptr->left_ptr = node_ptr->right_ptr = NULL;
542 RBTREE_NODE_SET_PARENT_PTR(node_ptr, NULL);
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)
571 RBTREE_NODE_TYPE *G = RBTREE_NODE_GET_PARENT_PTR(P);
572 RBTREE_NODE_TYPE *S = P->child_ptrs[1 - dir];
574 RBTREE_NODE_TYPE *C = S->child_ptrs[dir];
576 P->child_ptrs[1 - dir] = C;
578 RBTREE_NODE_SET_PARENT_PTR(C, P);
581 S->child_ptrs[dir] = P;
582 RBTREE_NODE_SET_PARENT_PTR(P, S);
584 RBTREE_NODE_SET_PARENT_PTR(S, G);
586 G->child_ptrs[P == G->left_ptr ? 0 : 1] = S;
594static inline void JOIN(internal,
JOIN(RBTREE_NAME, insert_fixup))(RBTREE_NODE_TYPE **rootptr_ptr, RBTREE_NODE_TYPE *N)
596 assert(RBTREE_NODE_IS_RED(N));
597 assert(N != *rootptr_ptr);
599 RBTREE_NODE_TYPE *P = RBTREE_NODE_GET_PARENT_PTR(N);
600 RBTREE_NODE_TYPE *G = NULL;
601 RBTREE_NODE_TYPE *U = NULL;
604 if (RBTREE_NODE_IS_BLACK(P)) {
607 if ((G = RBTREE_NODE_GET_PARENT_PTR(P)) == NULL) {
608 RBTREE_NODE_SET_COLOR_TO_BLACK(P);
611 const int dir = RBTREE_CHILD_DIR(P);
612 U = G->child_ptrs[1 - dir];
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);
618 P = G->child_ptrs[dir];
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);
626 RBTREE_NODE_SET_COLOR_TO_BLACK(P);
627 RBTREE_NODE_SET_COLOR_TO_BLACK(U);
628 RBTREE_NODE_SET_COLOR_TO_RED(G);
631 P = RBTREE_NODE_GET_PARENT_PTR(N);
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)
639 RBTREE_NODE_TYPE *src_node_parent_ptr = RBTREE_NODE_GET_PARENT_PTR(src_node);
641 if (src_node_parent_ptr == NULL) {
642 *rootptr_ptr = dest_node;
645 src_node_parent_ptr->child_ptrs[RBTREE_CHILD_DIR(src_node)] = dest_node;
648 if (dest_node != NULL) {
649 RBTREE_NODE_SET_PARENT_PTR(dest_node, src_node_parent_ptr);
653static inline void JOIN(internal,
JOIN(RBTREE_NAME, delete_fixup))(RBTREE_NODE_TYPE **rootptr_ptr, RBTREE_NODE_TYPE *P,
656 RBTREE_NODE_TYPE *N = NULL;
657 RBTREE_NODE_TYPE *S = NULL;
658 RBTREE_NODE_TYPE *C = NULL;
659 RBTREE_NODE_TYPE *D = NULL;
662 S = P->child_ptrs[1 - dir];
663 D = S->child_ptrs[1 - dir];
664 C = S->child_ptrs[dir];
666 if (RBTREE_NODE_IS_RED(S)) {
669 if (D != NULL && RBTREE_NODE_IS_RED(D)) {
672 if (C != NULL && RBTREE_NODE_IS_RED(C)) {
675 if (RBTREE_NODE_IS_RED(P)) {
678 RBTREE_NODE_SET_COLOR_TO_RED(S);
681 P = RBTREE_NODE_GET_PARENT_PTR(N);
682 }
while (P != NULL && (dir = RBTREE_CHILD_DIR(N),
true));
686 RBTREE_ROTATE_DIR(rootptr_ptr, P, dir);
687 RBTREE_NODE_SET_COLOR_TO_RED(P);
688 RBTREE_NODE_SET_COLOR_TO_BLACK(S);
690 D = S->child_ptrs[1 - dir];
691 if (D != NULL && RBTREE_NODE_IS_RED(D)) {
694 C = S->child_ptrs[dir];
695 if (C != NULL && RBTREE_NODE_IS_RED(C)) {
699 RBTREE_NODE_SET_COLOR_TO_RED(S);
700 RBTREE_NODE_SET_COLOR_TO_BLACK(P);
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);
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);
726#undef KEY_IS_STRICTLY_LESS
727#undef ALLOW_DUPLICATES
728#undef KEY_MEMBER_IS_FIRST
729#undef FUNCTION_DEFINITIONS
730#undef TYPE_DEFINITIONS
734#undef RBTREE_NODE_TYPE
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
745#undef RBTREE_CONTAINS_KEY
746#undef RBTREE_INSERT_FIXUP
747#undef RBTREE_DELETE_FIXUP
748#undef RBTREE_CHILD_DIR
#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