PR other/22202
[official-gcc.git] / gcc / ada / a-crbtgo.adb
blob8dd62a5ce44229f42878e500cbe1f329bc02045d
1 ------------------------------------------------------------------------------
2 -- --
3 -- GNAT LIBRARY COMPONENTS --
4 -- --
5 -- A D A . C O N T A I N E R S . R E D _ B L A C K _ T R E E S . --
6 -- G E N E R I C _ O P E R A T I O N S --
7 -- --
8 -- B o d y --
9 -- --
10 -- Copyright (C) 2004-2005 Free Software Foundation, Inc. --
11 -- --
12 -- This specification is derived from the Ada Reference Manual for use with --
13 -- GNAT. The copyright notice above, and the license provisions that follow --
14 -- apply solely to the contents of the part following the private keyword. --
15 -- --
16 -- GNAT is free software; you can redistribute it and/or modify it under --
17 -- terms of the GNU General Public License as published by the Free Soft- --
18 -- ware Foundation; either version 2, or (at your option) any later ver- --
19 -- sion. GNAT is distributed in the hope that it will be useful, but WITH- --
20 -- OUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY --
21 -- or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License --
22 -- for more details. You should have received a copy of the GNU General --
23 -- Public License distributed with GNAT; see file COPYING. If not, write --
24 -- to the Free Software Foundation, 51 Franklin Street, Fifth Floor, --
25 -- Boston, MA 02110-1301, USA. --
26 -- --
27 -- As a special exception, if other files instantiate generics from this --
28 -- unit, or you link this unit with other files to produce an executable, --
29 -- this unit does not by itself cause the resulting executable to be --
30 -- covered by the GNU General Public License. This exception does not --
31 -- however invalidate any other reasons why the executable file might be --
32 -- covered by the GNU Public License. --
33 -- --
34 -- This unit was originally developed by Matthew J Heaney. --
35 ------------------------------------------------------------------------------
37 with System; use type System.Address;
39 package body Ada.Containers.Red_Black_Trees.Generic_Operations is
41 -----------------------
42 -- Local Subprograms --
43 -----------------------
45 procedure Delete_Fixup (Tree : in out Tree_Type; Node : Node_Access);
47 procedure Delete_Swap (Tree : in out Tree_Type; Z, Y : Node_Access);
49 procedure Left_Rotate (Tree : in out Tree_Type; X : Node_Access);
50 procedure Right_Rotate (Tree : in out Tree_Type; Y : Node_Access);
52 ---------------------
53 -- Check_Invariant --
54 ---------------------
56 procedure Check_Invariant (Tree : Tree_Type) is
57 Root : constant Node_Access := Tree.Root;
59 function Check (Node : Node_Access) return Natural;
61 -----------
62 -- Check --
63 -----------
65 function Check (Node : Node_Access) return Natural is
66 begin
67 if Node = null then
68 return 0;
69 end if;
71 if Color (Node) = Red then
72 declare
73 L : constant Node_Access := Left (Node);
74 begin
75 pragma Assert (L = null or else Color (L) = Black);
76 null;
77 end;
79 declare
80 R : constant Node_Access := Right (Node);
81 begin
82 pragma Assert (R = null or else Color (R) = Black);
83 null;
84 end;
86 declare
87 NL : constant Natural := Check (Left (Node));
88 NR : constant Natural := Check (Right (Node));
89 begin
90 pragma Assert (NL = NR);
91 return NL;
92 end;
93 end if;
95 declare
96 NL : constant Natural := Check (Left (Node));
97 NR : constant Natural := Check (Right (Node));
98 begin
99 pragma Assert (NL = NR);
100 return NL + 1;
101 end;
102 end Check;
104 -- Start of processing for Check_Invariant
106 begin
107 if Root = null then
108 pragma Assert (Tree.First = null);
109 pragma Assert (Tree.Last = null);
110 pragma Assert (Tree.Length = 0);
111 null;
113 else
114 pragma Assert (Color (Root) = Black);
115 pragma Assert (Tree.Length > 0);
116 pragma Assert (Tree.Root /= null);
117 pragma Assert (Tree.First /= null);
118 pragma Assert (Tree.Last /= null);
119 pragma Assert (Parent (Tree.Root) = null);
120 pragma Assert ((Tree.Length > 1)
121 or else (Tree.First = Tree.Last
122 and Tree.First = Tree.Root));
123 pragma Assert (Left (Tree.First) = null);
124 pragma Assert (Right (Tree.Last) = null);
126 declare
127 L : constant Node_Access := Left (Root);
128 R : constant Node_Access := Right (Root);
129 NL : constant Natural := Check (L);
130 NR : constant Natural := Check (R);
131 begin
132 pragma Assert (NL = NR);
133 null;
134 end;
135 end if;
136 end Check_Invariant;
138 ------------------
139 -- Delete_Fixup --
140 ------------------
142 procedure Delete_Fixup (Tree : in out Tree_Type; Node : Node_Access) is
144 -- CLR p274 ???
146 X : Node_Access := Node;
147 W : Node_Access;
149 begin
150 while X /= Tree.Root
151 and then Color (X) = Black
152 loop
153 if X = Left (Parent (X)) then
154 W := Right (Parent (X));
156 if Color (W) = Red then
157 Set_Color (W, Black);
158 Set_Color (Parent (X), Red);
159 Left_Rotate (Tree, Parent (X));
160 W := Right (Parent (X));
161 end if;
163 if (Left (W) = null or else Color (Left (W)) = Black)
164 and then
165 (Right (W) = null or else Color (Right (W)) = Black)
166 then
167 Set_Color (W, Red);
168 X := Parent (X);
170 else
171 if Right (W) = null
172 or else Color (Right (W)) = Black
173 then
174 if Left (W) /= null then
175 Set_Color (Left (W), Black);
176 end if;
178 Set_Color (W, Red);
179 Right_Rotate (Tree, W);
180 W := Right (Parent (X));
181 end if;
183 Set_Color (W, Color (Parent (X)));
184 Set_Color (Parent (X), Black);
185 Set_Color (Right (W), Black);
186 Left_Rotate (Tree, Parent (X));
187 X := Tree.Root;
188 end if;
190 else
191 pragma Assert (X = Right (Parent (X)));
193 W := Left (Parent (X));
195 if Color (W) = Red then
196 Set_Color (W, Black);
197 Set_Color (Parent (X), Red);
198 Right_Rotate (Tree, Parent (X));
199 W := Left (Parent (X));
200 end if;
202 if (Left (W) = null or else Color (Left (W)) = Black)
203 and then
204 (Right (W) = null or else Color (Right (W)) = Black)
205 then
206 Set_Color (W, Red);
207 X := Parent (X);
209 else
210 if Left (W) = null or else Color (Left (W)) = Black then
211 if Right (W) /= null then
212 Set_Color (Right (W), Black);
213 end if;
215 Set_Color (W, Red);
216 Left_Rotate (Tree, W);
217 W := Left (Parent (X));
218 end if;
220 Set_Color (W, Color (Parent (X)));
221 Set_Color (Parent (X), Black);
222 Set_Color (Left (W), Black);
223 Right_Rotate (Tree, Parent (X));
224 X := Tree.Root;
225 end if;
226 end if;
227 end loop;
229 Set_Color (X, Black);
230 end Delete_Fixup;
232 ---------------------------
233 -- Delete_Node_Sans_Free --
234 ---------------------------
236 procedure Delete_Node_Sans_Free
237 (Tree : in out Tree_Type;
238 Node : Node_Access)
240 -- CLR p273 ???
242 X, Y : Node_Access;
244 Z : constant Node_Access := Node;
245 pragma Assert (Z /= null);
247 begin
248 if Tree.Busy > 0 then
249 raise Program_Error;
250 end if;
252 pragma Assert (Tree.Length > 0);
253 pragma Assert (Tree.Root /= null);
254 pragma Assert (Tree.First /= null);
255 pragma Assert (Tree.Last /= null);
256 pragma Assert (Parent (Tree.Root) = null);
257 pragma Assert ((Tree.Length > 1)
258 or else (Tree.First = Tree.Last
259 and then Tree.First = Tree.Root));
260 pragma Assert ((Left (Node) = null)
261 or else (Parent (Left (Node)) = Node));
262 pragma Assert ((Right (Node) = null)
263 or else (Parent (Right (Node)) = Node));
264 pragma Assert (((Parent (Node) = null) and then (Tree.Root = Node))
265 or else ((Parent (Node) /= null) and then
266 ((Left (Parent (Node)) = Node)
267 or else (Right (Parent (Node)) = Node))));
269 if Left (Z) = null then
270 if Right (Z) = null then
271 if Z = Tree.First then
272 Tree.First := Parent (Z);
273 end if;
275 if Z = Tree.Last then
276 Tree.Last := Parent (Z);
277 end if;
279 if Color (Z) = Black then
280 Delete_Fixup (Tree, Z);
281 end if;
283 pragma Assert (Left (Z) = null);
284 pragma Assert (Right (Z) = null);
286 if Z = Tree.Root then
287 pragma Assert (Tree.Length = 1);
288 pragma Assert (Parent (Z) = null);
289 Tree.Root := null;
290 elsif Z = Left (Parent (Z)) then
291 Set_Left (Parent (Z), null);
292 else
293 pragma Assert (Z = Right (Parent (Z)));
294 Set_Right (Parent (Z), null);
295 end if;
297 else
298 pragma Assert (Z /= Tree.Last);
300 X := Right (Z);
302 if Z = Tree.First then
303 Tree.First := Min (X);
304 end if;
306 if Z = Tree.Root then
307 Tree.Root := X;
308 elsif Z = Left (Parent (Z)) then
309 Set_Left (Parent (Z), X);
310 else
311 pragma Assert (Z = Right (Parent (Z)));
312 Set_Right (Parent (Z), X);
313 end if;
315 Set_Parent (X, Parent (Z));
317 if Color (Z) = Black then
318 Delete_Fixup (Tree, X);
319 end if;
320 end if;
322 elsif Right (Z) = null then
323 pragma Assert (Z /= Tree.First);
325 X := Left (Z);
327 if Z = Tree.Last then
328 Tree.Last := Max (X);
329 end if;
331 if Z = Tree.Root then
332 Tree.Root := X;
333 elsif Z = Left (Parent (Z)) then
334 Set_Left (Parent (Z), X);
335 else
336 pragma Assert (Z = Right (Parent (Z)));
337 Set_Right (Parent (Z), X);
338 end if;
340 Set_Parent (X, Parent (Z));
342 if Color (Z) = Black then
343 Delete_Fixup (Tree, X);
344 end if;
346 else
347 pragma Assert (Z /= Tree.First);
348 pragma Assert (Z /= Tree.Last);
350 Y := Next (Z);
351 pragma Assert (Left (Y) = null);
353 X := Right (Y);
355 if X = null then
356 if Y = Left (Parent (Y)) then
357 pragma Assert (Parent (Y) /= Z);
358 Delete_Swap (Tree, Z, Y);
359 Set_Left (Parent (Z), Z);
361 else
362 pragma Assert (Y = Right (Parent (Y)));
363 pragma Assert (Parent (Y) = Z);
364 Set_Parent (Y, Parent (Z));
366 if Z = Tree.Root then
367 Tree.Root := Y;
368 elsif Z = Left (Parent (Z)) then
369 Set_Left (Parent (Z), Y);
370 else
371 pragma Assert (Z = Right (Parent (Z)));
372 Set_Right (Parent (Z), Y);
373 end if;
375 Set_Left (Y, Left (Z));
376 Set_Parent (Left (Y), Y);
377 Set_Right (Y, Z);
378 Set_Parent (Z, Y);
379 Set_Left (Z, null);
380 Set_Right (Z, null);
382 declare
383 Y_Color : constant Color_Type := Color (Y);
384 begin
385 Set_Color (Y, Color (Z));
386 Set_Color (Z, Y_Color);
387 end;
388 end if;
390 if Color (Z) = Black then
391 Delete_Fixup (Tree, Z);
392 end if;
394 pragma Assert (Left (Z) = null);
395 pragma Assert (Right (Z) = null);
397 if Z = Right (Parent (Z)) then
398 Set_Right (Parent (Z), null);
399 else
400 pragma Assert (Z = Left (Parent (Z)));
401 Set_Left (Parent (Z), null);
402 end if;
404 else
405 if Y = Left (Parent (Y)) then
406 pragma Assert (Parent (Y) /= Z);
408 Delete_Swap (Tree, Z, Y);
410 Set_Left (Parent (Z), X);
411 Set_Parent (X, Parent (Z));
413 else
414 pragma Assert (Y = Right (Parent (Y)));
415 pragma Assert (Parent (Y) = Z);
417 Set_Parent (Y, Parent (Z));
419 if Z = Tree.Root then
420 Tree.Root := Y;
421 elsif Z = Left (Parent (Z)) then
422 Set_Left (Parent (Z), Y);
423 else
424 pragma Assert (Z = Right (Parent (Z)));
425 Set_Right (Parent (Z), Y);
426 end if;
428 Set_Left (Y, Left (Z));
429 Set_Parent (Left (Y), Y);
431 declare
432 Y_Color : constant Color_Type := Color (Y);
433 begin
434 Set_Color (Y, Color (Z));
435 Set_Color (Z, Y_Color);
436 end;
437 end if;
439 if Color (Z) = Black then
440 Delete_Fixup (Tree, X);
441 end if;
442 end if;
443 end if;
445 Tree.Length := Tree.Length - 1;
446 end Delete_Node_Sans_Free;
448 -----------------
449 -- Delete_Swap --
450 -----------------
452 procedure Delete_Swap
453 (Tree : in out Tree_Type;
454 Z, Y : Node_Access)
456 pragma Assert (Z /= Y);
457 pragma Assert (Parent (Y) /= Z);
459 Y_Parent : constant Node_Access := Parent (Y);
460 Y_Color : constant Color_Type := Color (Y);
462 begin
463 Set_Parent (Y, Parent (Z));
464 Set_Left (Y, Left (Z));
465 Set_Right (Y, Right (Z));
466 Set_Color (Y, Color (Z));
468 if Tree.Root = Z then
469 Tree.Root := Y;
470 elsif Right (Parent (Y)) = Z then
471 Set_Right (Parent (Y), Y);
472 else
473 pragma Assert (Left (Parent (Y)) = Z);
474 Set_Left (Parent (Y), Y);
475 end if;
477 if Right (Y) /= null then
478 Set_Parent (Right (Y), Y);
479 end if;
481 if Left (Y) /= null then
482 Set_Parent (Left (Y), Y);
483 end if;
485 Set_Parent (Z, Y_Parent);
486 Set_Color (Z, Y_Color);
487 Set_Left (Z, null);
488 Set_Right (Z, null);
489 end Delete_Swap;
491 --------------------
492 -- Generic_Adjust --
493 --------------------
495 procedure Generic_Adjust (Tree : in out Tree_Type) is
496 N : constant Count_Type := Tree.Length;
497 Root : constant Node_Access := Tree.Root;
499 begin
500 if N = 0 then
501 pragma Assert (Root = null);
502 pragma Assert (Tree.Busy = 0);
503 pragma Assert (Tree.Lock = 0);
504 return;
505 end if;
507 Tree.Root := null;
508 Tree.First := null;
509 Tree.Last := null;
510 Tree.Length := 0;
512 Tree.Root := Copy_Tree (Root);
513 Tree.First := Min (Tree.Root);
514 Tree.Last := Max (Tree.Root);
515 Tree.Length := N;
516 end Generic_Adjust;
518 -------------------
519 -- Generic_Clear --
520 -------------------
522 procedure Generic_Clear (Tree : in out Tree_Type) is
523 Root : Node_Access := Tree.Root;
524 begin
525 if Tree.Busy > 0 then
526 raise Program_Error;
527 end if;
529 Tree := (First => null,
530 Last => null,
531 Root => null,
532 Length => 0,
533 Busy => 0,
534 Lock => 0);
536 Delete_Tree (Root);
537 end Generic_Clear;
539 -----------------------
540 -- Generic_Copy_Tree --
541 -----------------------
543 function Generic_Copy_Tree (Source_Root : Node_Access) return Node_Access is
544 Target_Root : Node_Access := Copy_Node (Source_Root);
545 P, X : Node_Access;
547 begin
549 if Right (Source_Root) /= null then
550 Set_Right
551 (Node => Target_Root,
552 Right => Generic_Copy_Tree (Right (Source_Root)));
554 Set_Parent
555 (Node => Right (Target_Root),
556 Parent => Target_Root);
557 end if;
559 P := Target_Root;
561 X := Left (Source_Root);
562 while X /= null loop
563 declare
564 Y : constant Node_Access := Copy_Node (X);
565 begin
566 Set_Left (Node => P, Left => Y);
567 Set_Parent (Node => Y, Parent => P);
569 if Right (X) /= null then
570 Set_Right
571 (Node => Y,
572 Right => Generic_Copy_Tree (Right (X)));
574 Set_Parent
575 (Node => Right (Y),
576 Parent => Y);
577 end if;
579 P := Y;
580 X := Left (X);
581 end;
582 end loop;
584 return Target_Root;
585 exception
586 when others =>
587 Delete_Tree (Target_Root);
588 raise;
590 end Generic_Copy_Tree;
592 -------------------------
593 -- Generic_Delete_Tree --
594 -------------------------
596 procedure Generic_Delete_Tree (X : in out Node_Access) is
597 Y : Node_Access;
598 begin
599 while X /= null loop
600 Y := Right (X);
601 Generic_Delete_Tree (Y);
602 Y := Left (X);
603 Free (X);
604 X := Y;
605 end loop;
606 end Generic_Delete_Tree;
608 -------------------
609 -- Generic_Equal --
610 -------------------
612 function Generic_Equal (Left, Right : Tree_Type) return Boolean is
613 L_Node : Node_Access;
614 R_Node : Node_Access;
616 begin
617 if Left'Address = Right'Address then
618 return True;
619 end if;
621 if Left.Length /= Right.Length then
622 return False;
623 end if;
625 L_Node := Left.First;
626 R_Node := Right.First;
627 while L_Node /= null loop
628 if not Is_Equal (L_Node, R_Node) then
629 return False;
630 end if;
632 L_Node := Next (L_Node);
633 R_Node := Next (R_Node);
634 end loop;
636 return True;
637 end Generic_Equal;
639 -----------------------
640 -- Generic_Iteration --
641 -----------------------
643 procedure Generic_Iteration (Tree : Tree_Type) is
644 procedure Iterate (P : Node_Access);
646 -------------
647 -- Iterate --
648 -------------
650 procedure Iterate (P : Node_Access) is
651 X : Node_Access := P;
652 begin
653 while X /= null loop
654 Iterate (Left (X));
655 Process (X);
656 X := Right (X);
657 end loop;
658 end Iterate;
660 -- Start of processing for Generic_Iteration
662 begin
663 Iterate (Tree.Root);
664 end Generic_Iteration;
666 ------------------
667 -- Generic_Move --
668 ------------------
670 procedure Generic_Move (Target, Source : in out Tree_Type) is
671 begin
672 if Target'Address = Source'Address then
673 return;
674 end if;
676 if Source.Busy > 0 then
677 raise Program_Error;
678 end if;
680 Clear (Target);
682 Target := Source;
684 Source := (First => null,
685 Last => null,
686 Root => null,
687 Length => 0,
688 Busy => 0,
689 Lock => 0);
690 end Generic_Move;
692 ------------------
693 -- Generic_Read --
694 ------------------
696 procedure Generic_Read
697 (Stream : access Root_Stream_Type'Class;
698 Tree : in out Tree_Type)
700 N : Count_Type'Base;
702 Node, Last_Node : Node_Access;
704 begin
705 Clear (Tree);
707 Count_Type'Base'Read (Stream, N);
708 pragma Assert (N >= 0);
710 if N = 0 then
711 return;
712 end if;
714 Node := Read_Node (Stream);
715 pragma Assert (Node /= null);
716 pragma Assert (Color (Node) = Red);
718 Set_Color (Node, Black);
720 Tree.Root := Node;
721 Tree.First := Node;
722 Tree.Last := Node;
724 Tree.Length := 1;
726 for J in Count_Type range 2 .. N loop
727 Last_Node := Node;
728 pragma Assert (Last_Node = Tree.Last);
730 Node := Read_Node (Stream);
731 pragma Assert (Node /= null);
732 pragma Assert (Color (Node) = Red);
734 Set_Right (Node => Last_Node, Right => Node);
735 Tree.Last := Node;
736 Set_Parent (Node => Node, Parent => Last_Node);
737 Rebalance_For_Insert (Tree, Node);
738 Tree.Length := Tree.Length + 1;
739 end loop;
740 end Generic_Read;
742 -------------------------------
743 -- Generic_Reverse_Iteration --
744 -------------------------------
746 procedure Generic_Reverse_Iteration (Tree : Tree_Type)
748 procedure Iterate (P : Node_Access);
750 -------------
751 -- Iterate --
752 -------------
754 procedure Iterate (P : Node_Access) is
755 X : Node_Access := P;
756 begin
757 while X /= null loop
758 Iterate (Right (X));
759 Process (X);
760 X := Left (X);
761 end loop;
762 end Iterate;
764 -- Start of processing for Generic_Reverse_Iteration
766 begin
767 Iterate (Tree.Root);
768 end Generic_Reverse_Iteration;
770 -------------------
771 -- Generic_Write --
772 -------------------
774 procedure Generic_Write
775 (Stream : access Root_Stream_Type'Class;
776 Tree : in Tree_Type)
778 procedure Process (Node : Node_Access);
779 pragma Inline (Process);
781 procedure Iterate is
782 new Generic_Iteration (Process);
784 -------------
785 -- Process --
786 -------------
788 procedure Process (Node : Node_Access) is
789 begin
790 Write_Node (Stream, Node);
791 end Process;
793 -- Start of processing for Generic_Write
795 begin
796 Count_Type'Base'Write (Stream, Tree.Length);
797 Iterate (Tree);
798 end Generic_Write;
800 -----------------
801 -- Left_Rotate --
802 -----------------
804 procedure Left_Rotate (Tree : in out Tree_Type; X : Node_Access) is
806 -- CLR p266 ???
808 Y : constant Node_Access := Right (X);
809 pragma Assert (Y /= null);
811 begin
812 Set_Right (X, Left (Y));
814 if Left (Y) /= null then
815 Set_Parent (Left (Y), X);
816 end if;
818 Set_Parent (Y, Parent (X));
820 if X = Tree.Root then
821 Tree.Root := Y;
822 elsif X = Left (Parent (X)) then
823 Set_Left (Parent (X), Y);
824 else
825 pragma Assert (X = Right (Parent (X)));
826 Set_Right (Parent (X), Y);
827 end if;
829 Set_Left (Y, X);
830 Set_Parent (X, Y);
831 end Left_Rotate;
833 ---------
834 -- Max --
835 ---------
837 function Max (Node : Node_Access) return Node_Access is
839 -- CLR p248 ???
841 X : Node_Access := Node;
842 Y : Node_Access;
844 begin
845 loop
846 Y := Right (X);
848 if Y = null then
849 return X;
850 end if;
852 X := Y;
853 end loop;
854 end Max;
856 ---------
857 -- Min --
858 ---------
860 function Min (Node : Node_Access) return Node_Access is
862 -- CLR p248 ???
864 X : Node_Access := Node;
865 Y : Node_Access;
867 begin
868 loop
869 Y := Left (X);
871 if Y = null then
872 return X;
873 end if;
875 X := Y;
876 end loop;
877 end Min;
879 ----------
880 -- Next --
881 ----------
883 function Next (Node : Node_Access) return Node_Access is
884 begin
885 -- CLR p249 ???
887 if Node = null then
888 return null;
889 end if;
891 if Right (Node) /= null then
892 return Min (Right (Node));
893 end if;
895 declare
896 X : Node_Access := Node;
897 Y : Node_Access := Parent (Node);
899 begin
900 while Y /= null
901 and then X = Right (Y)
902 loop
903 X := Y;
904 Y := Parent (Y);
905 end loop;
907 -- Why is this code commented out ???
909 -- if Right (X) /= Y then
910 -- return Y;
911 -- else
912 -- return X;
913 -- end if;
915 return Y;
916 end;
917 end Next;
919 --------------
920 -- Previous --
921 --------------
923 function Previous (Node : Node_Access) return Node_Access is
924 begin
925 if Node = null then
926 return null;
927 end if;
929 if Left (Node) /= null then
930 return Max (Left (Node));
931 end if;
933 declare
934 X : Node_Access := Node;
935 Y : Node_Access := Parent (Node);
937 begin
938 while Y /= null
939 and then X = Left (Y)
940 loop
941 X := Y;
942 Y := Parent (Y);
943 end loop;
945 -- Why is this code commented out ???
947 -- if Left (X) /= Y then
948 -- return Y;
949 -- else
950 -- return X;
951 -- end if;
953 return Y;
954 end;
955 end Previous;
957 --------------------------
958 -- Rebalance_For_Insert --
959 --------------------------
961 procedure Rebalance_For_Insert
962 (Tree : in out Tree_Type;
963 Node : Node_Access)
965 -- CLR p.268 ???
967 X : Node_Access := Node;
968 pragma Assert (X /= null);
969 pragma Assert (Color (X) = Red);
971 Y : Node_Access;
973 begin
974 while X /= Tree.Root and then Color (Parent (X)) = Red loop
975 if Parent (X) = Left (Parent (Parent (X))) then
976 Y := Right (Parent (Parent (X)));
978 if Y /= null and then Color (Y) = Red then
979 Set_Color (Parent (X), Black);
980 Set_Color (Y, Black);
981 Set_Color (Parent (Parent (X)), Red);
982 X := Parent (Parent (X));
984 else
985 if X = Right (Parent (X)) then
986 X := Parent (X);
987 Left_Rotate (Tree, X);
988 end if;
990 Set_Color (Parent (X), Black);
991 Set_Color (Parent (Parent (X)), Red);
992 Right_Rotate (Tree, Parent (Parent (X)));
993 end if;
995 else
996 pragma Assert (Parent (X) = Right (Parent (Parent (X))));
998 Y := Left (Parent (Parent (X)));
1000 if Y /= null and then Color (Y) = Red then
1001 Set_Color (Parent (X), Black);
1002 Set_Color (Y, Black);
1003 Set_Color (Parent (Parent (X)), Red);
1004 X := Parent (Parent (X));
1006 else
1007 if X = Left (Parent (X)) then
1008 X := Parent (X);
1009 Right_Rotate (Tree, X);
1010 end if;
1012 Set_Color (Parent (X), Black);
1013 Set_Color (Parent (Parent (X)), Red);
1014 Left_Rotate (Tree, Parent (Parent (X)));
1015 end if;
1016 end if;
1017 end loop;
1019 Set_Color (Tree.Root, Black);
1020 end Rebalance_For_Insert;
1022 ------------------
1023 -- Right_Rotate --
1024 ------------------
1026 procedure Right_Rotate (Tree : in out Tree_Type; Y : Node_Access) is
1027 X : constant Node_Access := Left (Y);
1028 pragma Assert (X /= null);
1030 begin
1031 Set_Left (Y, Right (X));
1033 if Right (X) /= null then
1034 Set_Parent (Right (X), Y);
1035 end if;
1037 Set_Parent (X, Parent (Y));
1039 if Y = Tree.Root then
1040 Tree.Root := X;
1041 elsif Y = Left (Parent (Y)) then
1042 Set_Left (Parent (Y), X);
1043 else
1044 pragma Assert (Y = Right (Parent (Y)));
1045 Set_Right (Parent (Y), X);
1046 end if;
1048 Set_Right (X, Y);
1049 Set_Parent (Y, X);
1050 end Right_Rotate;
1052 end Ada.Containers.Red_Black_Trees.Generic_Operations;