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#else
79#define RBTREE_NAME NAME
80#endif
81
89#ifndef KEY_TYPE
90#define FUNCTION_DEFINITIONS
91#define TYPE_DEFINITIONS
92#define KEY_TYPE int
93#error "Must define KEY_TYPE."
94#endif
95
109#ifndef KEY_IS_STRICTLY_LESS
110#error "Must define KEY_IS_STRICTLY_LESS."
111#define KEY_IS_STRICTLY_LESS(a, b) ((a) < (b))
112#endif
113
126#ifdef ALLOW_DUPLICATES
127#endif
128
133#ifdef KEY_MEMBER_IS_FIRST
134#endif
135
140#ifndef FUNCTION_LINKAGE
141#define FUNCTION_LINKAGE
142#endif
143
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))
152
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))
159
160#define RBTREE_CHILD_DIR(node_ptr) ((node_ptr) == RBTREE_NODE_GET_PARENT_PTR(node_ptr)->left_ptr ? 0 : 1)
162
163// }}}
164
165// type definitions: {{{
166
171
172struct JOIN(RBTREE_NAME, node);
173
174#ifdef TYPE_DEFINITIONS
175
179struct JOIN(RBTREE_NAME, node) {
180#ifdef KEY_MEMBER_IS_FIRST
181 KEY_TYPE key;
182#endif
185 union {
186 struct {
187 RBTREE_NODE_TYPE *left_ptr;
188 RBTREE_NODE_TYPE *right_ptr;
189 };
190 RBTREE_NODE_TYPE *child_ptrs[2];
191 };
192#ifndef KEY_MEMBER_IS_FIRST
194#endif
195};
196
197#endif
198
199// }}}
200
201// function declarations: {{{
202
209FUNCTION_LINKAGE void JOIN(RBTREE_NAME, node_init)(RBTREE_NODE_TYPE *node_ptr, KEY_TYPE key);
210
216FUNCTION_LINKAGE RBTREE_NODE_TYPE *JOIN(RBTREE_NAME, node_get_parent_ptr)(RBTREE_NODE_TYPE *node_ptr);
217
223FUNCTION_LINKAGE bool JOIN(RBTREE_NAME, node_is_black)(const RBTREE_NODE_TYPE *node_ptr);
224
230FUNCTION_LINKAGE bool JOIN(RBTREE_NAME, node_is_red)(const RBTREE_NODE_TYPE *node_ptr);
231
239FUNCTION_LINKAGE bool JOIN(RBTREE_NAME, is_empty)(RBTREE_NODE_TYPE **rootptr_ptr);
240
249FUNCTION_LINKAGE bool JOIN(RBTREE_NAME, contains_key)(RBTREE_NODE_TYPE **rootptr_ptr, const KEY_TYPE key);
250
260FUNCTION_LINKAGE RBTREE_NODE_TYPE *JOIN(RBTREE_NAME, search_node)(RBTREE_NODE_TYPE **rootptr_ptr, const KEY_TYPE key);
261
268FUNCTION_LINKAGE void JOIN(RBTREE_NAME, insert_node)(RBTREE_NODE_TYPE **rootptr_ptr, RBTREE_NODE_TYPE *node_ptr);
269
278FUNCTION_LINKAGE RBTREE_NODE_TYPE *JOIN(RBTREE_NAME, delete_node)(RBTREE_NODE_TYPE **rootptr_ptr,
279 RBTREE_NODE_TYPE *node_ptr);
280
281// @}}}
282
283// function definitions: {{{
284
289#ifdef FUNCTION_DEFINITIONS
290
291#include <assert.h>
292
294
295static inline void JOIN(internal, JOIN(RBTREE_NAME, node_set_color_to_red))(RBTREE_NODE_TYPE *node_ptr)
296{
297 node_ptr->__parent_ptr_with_color_bit &= ~(uintptr_t)1;
298}
299
300static inline void JOIN(internal, JOIN(RBTREE_NAME, node_set_color_to_black))(RBTREE_NODE_TYPE *node_ptr)
301{
302 node_ptr->__parent_ptr_with_color_bit |= 1;
303}
304
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)
308{
309 const bool is_black = other_ptr->__parent_ptr_with_color_bit & 1;
310
311 node_ptr->__parent_ptr_with_color_bit &= ~(uintptr_t)1;
312 node_ptr->__parent_ptr_with_color_bit += is_black;
313}
314
315static inline void JOIN(internal, JOIN(RBTREE_NAME, node_set_parent_ptr))(RBTREE_NODE_TYPE *node_ptr,
316 RBTREE_NODE_TYPE *parent_ptr)
317{
318 const bool is_black = node_ptr->__parent_ptr_with_color_bit & 1;
319
320 node_ptr->__parent_ptr_with_color_bit = (uintptr_t)parent_ptr;
321 node_ptr->__parent_ptr_with_color_bit += is_black;
322}
323
324// rotate a subtree around a given subtree root node and direction (0: left or
325// 1: right). returns the new subtree root
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);
328
329// rebalance tree after insert. see explanation in the sources linked above.
330static inline void JOIN(internal, JOIN(RBTREE_NAME, insert_fixup))(RBTREE_NODE_TYPE **rootptr_ptr, RBTREE_NODE_TYPE *N);
331
332// move the parent of a node (src) to another node (dest).
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);
336
337// rebalance tree after delete. see explanation in the sources linked above.
338// for the special case where: (P's child) was not root and was black and had no children.
339static inline void JOIN(internal, JOIN(RBTREE_NAME, delete_fixup))(RBTREE_NODE_TYPE **rootptr_ptr, RBTREE_NODE_TYPE *P,
340 int dir);
341
343
344
345FUNCTION_LINKAGE void JOIN(RBTREE_NAME, node_init)(RBTREE_NODE_TYPE *node_ptr, KEY_TYPE key)
346{
347 assert(node_ptr != NULL);
348
349 node_ptr->key = key;
350 node_ptr->left_ptr = node_ptr->right_ptr = NULL;
351 RBTREE_NODE_SET_PARENT_PTR(node_ptr, NULL);
352}
353
354FUNCTION_LINKAGE RBTREE_NODE_TYPE *JOIN(RBTREE_NAME, node_get_parent_ptr)(RBTREE_NODE_TYPE *node_ptr)
355{
356 assert(node_ptr != NULL);
357
358 return (RBTREE_NODE_TYPE *)(node_ptr->__parent_ptr_with_color_bit & ~(uintptr_t)1);
359}
360
361FUNCTION_LINKAGE bool JOIN(RBTREE_NAME, node_is_black)(const RBTREE_NODE_TYPE *node_ptr)
362{
363 assert(node_ptr != NULL);
364
365 return (node_ptr->__parent_ptr_with_color_bit & 1);
366}
367
368FUNCTION_LINKAGE bool JOIN(RBTREE_NAME, node_is_red)(const RBTREE_NODE_TYPE *node_ptr)
369{
370 assert(node_ptr != NULL);
371
372 return !RBTREE_NODE_IS_BLACK(node_ptr);
373}
374
375FUNCTION_LINKAGE bool JOIN(RBTREE_NAME, is_empty)(RBTREE_NODE_TYPE **rootptr_ptr)
376{
377 assert(rootptr_ptr != NULL);
378
379 return *rootptr_ptr == NULL;
380}
381
382FUNCTION_LINKAGE bool JOIN(RBTREE_NAME, contains_key)(RBTREE_NODE_TYPE **rootptr_ptr, const KEY_TYPE key)
383{
384 assert(rootptr_ptr != NULL);
385
386 RBTREE_NODE_TYPE *node_ptr = *rootptr_ptr;
387
388 while (node_ptr != NULL) {
389 const bool is_strictly_less = KEY_IS_STRICTLY_LESS(key, node_ptr->key);
390 const bool is_strictly_greater = KEY_IS_STRICTLY_LESS(node_ptr->key, key);
391 const bool is_equal = !is_strictly_less && !is_strictly_greater;
392
393 if (is_equal) {
394 return true;
395 }
396 else if (is_strictly_less) {
397 node_ptr = node_ptr->left_ptr;
398 }
399 else {
400 node_ptr = node_ptr->right_ptr;
401 }
402 }
403 return false;
404}
405
406FUNCTION_LINKAGE RBTREE_NODE_TYPE *JOIN(RBTREE_NAME, search_node)(RBTREE_NODE_TYPE **rootptr_ptr, const KEY_TYPE key)
407{
408 assert(rootptr_ptr != NULL);
409
410 RBTREE_NODE_TYPE *node_ptr = *rootptr_ptr;
411 while (node_ptr != NULL) {
412 const bool is_strictly_less = KEY_IS_STRICTLY_LESS(key, node_ptr->key);
413 const bool is_strictly_greater = KEY_IS_STRICTLY_LESS(node_ptr->key, key);
414 const bool is_equal = !is_strictly_less && !is_strictly_greater;
415
416 if (is_equal) {
417 return node_ptr;
418 }
419 else if (is_strictly_less) {
420 node_ptr = node_ptr->left_ptr;
421 }
422 else {
423 node_ptr = node_ptr->right_ptr;
424 }
425 }
426 return NULL;
427}
428
429FUNCTION_LINKAGE void JOIN(RBTREE_NAME, insert_node)(RBTREE_NODE_TYPE **rootptr_ptr, RBTREE_NODE_TYPE *node_ptr)
430{
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);
435#endif
436
437 RBTREE_NODE_TYPE *parent_ptr = NULL;
438 RBTREE_NODE_TYPE *current_ptr = *rootptr_ptr;
439
440 while (current_ptr != NULL) {
441 const bool is_strictly_greater = KEY_IS_STRICTLY_LESS(current_ptr->key, node_ptr->key);
442
443 parent_ptr = current_ptr;
444
445 if (is_strictly_greater) {
446 current_ptr = current_ptr->right_ptr;
447 }
448 else {
449 current_ptr = current_ptr->left_ptr;
450 }
451 }
452
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);
456
457 if (parent_ptr == NULL) {
458 *rootptr_ptr = node_ptr;
459 }
460 else {
461 const int dir = KEY_IS_STRICTLY_LESS(parent_ptr->key, node_ptr->key) ? 1 : 0;
462
463 parent_ptr->child_ptrs[dir] = node_ptr;
464
465 RBTREE_INSERT_FIXUP(rootptr_ptr, node_ptr);
466 }
467}
468
469FUNCTION_LINKAGE RBTREE_NODE_TYPE *JOIN(RBTREE_NAME, delete_node)(RBTREE_NODE_TYPE **rootptr_ptr,
470 RBTREE_NODE_TYPE *node_ptr)
471{
472 assert(rootptr_ptr != NULL);
473 assert(node_ptr != NULL);
474
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);
478 }
479 else {
480 RBTREE_NODE_TYPE *const parent_ptr = RBTREE_NODE_GET_PARENT_PTR(node_ptr);
481
482 const int dir = RBTREE_CHILD_DIR(node_ptr) ? 1 : 0;
483
484 RBTREE_NODE_TRANSPLANT(rootptr_ptr, node_ptr, NULL);
485
486 RBTREE_DELETE_FIXUP(rootptr_ptr, parent_ptr, dir);
487 }
488 }
489 else if (node_ptr->left_ptr == NULL || node_ptr->right_ptr == NULL) {
490 const int dir = node_ptr->left_ptr == NULL;
491
492 assert(RBTREE_NODE_IS_BLACK(node_ptr));
493 assert(RBTREE_NODE_IS_RED(node_ptr->child_ptrs[dir]));
494
495 RBTREE_NODE_SET_COLOR_TO_BLACK(node_ptr->child_ptrs[dir]);
496
497 RBTREE_NODE_TRANSPLANT(rootptr_ptr, node_ptr, node_ptr->child_ptrs[dir]);
498 }
499 else {
500 RBTREE_NODE_TYPE *successor_ptr = node_ptr->right_ptr;
501
502 while (successor_ptr->left_ptr != NULL) {
503 successor_ptr = successor_ptr->left_ptr;
504 }
505
506 const bool prev_successor_black = RBTREE_NODE_IS_BLACK(successor_ptr);
507
508 const int prev_successor_dir = RBTREE_CHILD_DIR(successor_ptr);
509
510 RBTREE_NODE_TYPE *const prev_successor_parent_ptr = RBTREE_NODE_GET_PARENT_PTR(successor_ptr);
511
512 RBTREE_NODE_TYPE *const prev_successor_child_ptr = successor_ptr->right_ptr;
513
514 {
515 if (RBTREE_NODE_GET_PARENT_PTR(successor_ptr) != node_ptr) {
516 RBTREE_NODE_TRANSPLANT(rootptr_ptr, successor_ptr, successor_ptr->right_ptr);
517
518 successor_ptr->right_ptr = node_ptr->right_ptr;
519 RBTREE_NODE_SET_PARENT_PTR(node_ptr->right_ptr, successor_ptr);
520 }
521 RBTREE_NODE_TRANSPLANT(rootptr_ptr, node_ptr, successor_ptr);
522
523 successor_ptr->left_ptr = node_ptr->left_ptr;
524 RBTREE_NODE_SET_PARENT_PTR(node_ptr->left_ptr, successor_ptr);
525
526 RBTREE_NODE_SET_COLOR_TO_COLOR_OF_OTHER(successor_ptr, node_ptr);
527 }
528
529 if (prev_successor_child_ptr != NULL) {
530 assert(prev_successor_black);
531 assert(RBTREE_NODE_IS_RED(prev_successor_child_ptr));
532
533 RBTREE_NODE_SET_COLOR_TO_BLACK(prev_successor_child_ptr);
534 }
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;
538
539 RBTREE_DELETE_FIXUP(rootptr_ptr, actual_successor_ptr, prev_successor_dir);
540 }
541 }
542
543 node_ptr->left_ptr = node_ptr->right_ptr = NULL;
544 RBTREE_NODE_SET_PARENT_PTR(node_ptr, NULL);
545
546 return node_ptr;
547}
548
550
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)
553{
554 /* Right rotate around P:
555 P S
556 / \ / \
557 S T --> .. P
558 / \ / \ ⟳ / \
559 .. C .. .. C T
560 / \ / \ / \
561 .. .. .. .. .. ..
562
563 Left rotate around P:
564 P S
565 / \ / \
566 T S P ..
567 / \ / \ --> / \
568 .. .. C .. ↺ T C
569 / \ / \ / \
570 .. .. .. .. .. ..
571 */
572
573 RBTREE_NODE_TYPE *G = RBTREE_NODE_GET_PARENT_PTR(P);
574 RBTREE_NODE_TYPE *S = P->child_ptrs[1 - dir];
575 assert(S != NULL);
576 RBTREE_NODE_TYPE *C = S->child_ptrs[dir];
577
578 P->child_ptrs[1 - dir] = C;
579 if (C != NULL) {
580 RBTREE_NODE_SET_PARENT_PTR(C, P);
581 }
582
583 S->child_ptrs[dir] = P;
584 RBTREE_NODE_SET_PARENT_PTR(P, S);
585
586 RBTREE_NODE_SET_PARENT_PTR(S, G);
587 if (G != NULL) {
588 G->child_ptrs[P == G->left_ptr ? 0 : 1] = S;
589 }
590 else {
591 *rootptr_ptr = S;
592 }
593 return S;
594}
595
596static inline void JOIN(internal, JOIN(RBTREE_NAME, insert_fixup))(RBTREE_NODE_TYPE **rootptr_ptr, RBTREE_NODE_TYPE *N)
597{
598 assert(RBTREE_NODE_IS_RED(N));
599 assert(N != *rootptr_ptr);
600
601 RBTREE_NODE_TYPE *P = RBTREE_NODE_GET_PARENT_PTR(N); // parent
602 RBTREE_NODE_TYPE *G = NULL; // grandparent
603 RBTREE_NODE_TYPE *U = NULL; // uncle
604
605 do {
606 if (RBTREE_NODE_IS_BLACK(P)) {
607 return;
608 }
609 if ((G = RBTREE_NODE_GET_PARENT_PTR(P)) == NULL) {
610 RBTREE_NODE_SET_COLOR_TO_BLACK(P);
611 return;
612 }
613 const int dir = RBTREE_CHILD_DIR(P);
614 U = G->child_ptrs[1 - dir];
615
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);
619 N = P;
620 P = G->child_ptrs[dir];
621 }
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);
625 return;
626 }
627
628 RBTREE_NODE_SET_COLOR_TO_BLACK(P);
629 RBTREE_NODE_SET_COLOR_TO_BLACK(U);
630 RBTREE_NODE_SET_COLOR_TO_RED(G);
631
632 N = G;
633 P = RBTREE_NODE_GET_PARENT_PTR(N);
634 } while (P != NULL);
635}
636
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)
640{
641 RBTREE_NODE_TYPE *src_node_parent_ptr = RBTREE_NODE_GET_PARENT_PTR(src_node);
642
643 if (src_node_parent_ptr == NULL) {
644 *rootptr_ptr = dest_node;
645 }
646 else {
647 src_node_parent_ptr->child_ptrs[RBTREE_CHILD_DIR(src_node)] = dest_node;
648 }
649
650 if (dest_node != NULL) {
651 RBTREE_NODE_SET_PARENT_PTR(dest_node, src_node_parent_ptr);
652 }
653}
654
655static inline void JOIN(internal, JOIN(RBTREE_NAME, delete_fixup))(RBTREE_NODE_TYPE **rootptr_ptr, RBTREE_NODE_TYPE *P,
656 int dir)
657{
658 RBTREE_NODE_TYPE *N = NULL; // node (temp)
659 RBTREE_NODE_TYPE *S = NULL; // sibling
660 RBTREE_NODE_TYPE *C = NULL; // close nephew
661 RBTREE_NODE_TYPE *D = NULL; // distant nephew
662
663 do {
664 S = P->child_ptrs[1 - dir];
665 D = S->child_ptrs[1 - dir];
666 C = S->child_ptrs[dir];
667
668 if (RBTREE_NODE_IS_RED(S)) {
669 goto Case_3;
670 }
671 if (D != NULL && RBTREE_NODE_IS_RED(D)) {
672 goto Case_6;
673 }
674 if (C != NULL && RBTREE_NODE_IS_RED(C)) {
675 goto Case_5;
676 }
677 if (RBTREE_NODE_IS_RED(P)) {
678 goto Case_4;
679 }
680 RBTREE_NODE_SET_COLOR_TO_RED(S);
681
682 N = P;
683 P = RBTREE_NODE_GET_PARENT_PTR(N);
684 } while (P != NULL && (dir = RBTREE_CHILD_DIR(N), true));
685
686 return;
687Case_3:
688 RBTREE_ROTATE_DIR(rootptr_ptr, P, dir);
689 RBTREE_NODE_SET_COLOR_TO_RED(P);
690 RBTREE_NODE_SET_COLOR_TO_BLACK(S);
691 S = C;
692 D = S->child_ptrs[1 - dir];
693 if (D != NULL && RBTREE_NODE_IS_RED(D)) {
694 goto Case_6;
695 }
696 C = S->child_ptrs[dir];
697 if (C != NULL && RBTREE_NODE_IS_RED(C)) {
698 goto Case_5;
699 }
700Case_4:
701 RBTREE_NODE_SET_COLOR_TO_RED(S);
702 RBTREE_NODE_SET_COLOR_TO_BLACK(P);
703 return;
704Case_5:
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);
708 D = S;
709 S = C;
710Case_6:
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);
715 return;
716}
718
719#endif
720
721// }}}
722
723// macro undefs: {{{
724
725#undef NAME
726#undef KEY_TYPE
727#undef VALUE_TYPE
728#undef KEY_IS_STRICTLY_LESS
729#undef ALLOW_DUPLICATES
730#undef KEY_MEMBER_IS_FIRST
731#undef FUNCTION_DEFINITIONS
732#undef TYPE_DEFINITIONS
733
734#undef RBTREE_NAME
735#undef RBTREE_TYPE
736#undef RBTREE_NODE_TYPE
737
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
746
747#undef RBTREE_CONTAINS_KEY
748#undef RBTREE_INSERT_FIXUP
749#undef RBTREE_DELETE_FIXUP
750#undef RBTREE_CHILD_DIR
751
752// }}}
753
754#ifdef __cplusplus
755}
756#endif
757
758// 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: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