1 ------------------------------------------------------------------------------
3 -- GNAT LIBRARY COMPONENTS --
5 -- ADA.CONTAINERS.RED_BLACK_TREES.GENERIC_OPERATIONS --
9 -- Copyright (C) 2004 Free Software Foundation, Inc. --
11 -- This specification is derived from the Ada Reference Manual for use with --
12 -- GNAT. The copyright notice above, and the license provisions that follow --
13 -- apply solely to the contents of the part following the private keyword. --
15 -- GNAT is free software; you can redistribute it and/or modify it under --
16 -- terms of the GNU General Public License as published by the Free Soft- --
17 -- ware Foundation; either version 2, or (at your option) any later ver- --
18 -- sion. GNAT is distributed in the hope that it will be useful, but WITH- --
19 -- OUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY --
20 -- or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License --
21 -- for more details. You should have received a copy of the GNU General --
22 -- Public License distributed with GNAT; see file COPYING. If not, write --
23 -- to the Free Software Foundation, 59 Temple Place - Suite 330, Boston, --
24 -- MA 02111-1307, USA. --
26 -- As a special exception, if other files instantiate generics from this --
27 -- unit, or you link this unit with other files to produce an executable, --
28 -- this unit does not by itself cause the resulting executable to be --
29 -- covered by the GNU General Public License. This exception does not --
30 -- however invalidate any other reasons why the executable file might be --
31 -- covered by the GNU Public License. --
33 -- This unit was originally developed by Matthew J Heaney. --
34 ------------------------------------------------------------------------------
36 package body Ada
.Containers
.Red_Black_Trees
.Generic_Operations
is
38 -----------------------
39 -- Local Subprograms --
40 -----------------------
42 procedure Delete_Fixup
(Tree
: in out Tree_Type
; Node
: Node_Access
);
44 procedure Delete_Swap
(Tree
: in out Tree_Type
; Z
, Y
: Node_Access
);
46 procedure Left_Rotate
(Tree
: in out Tree_Type
; X
: Node_Access
);
47 procedure Right_Rotate
(Tree
: in out Tree_Type
; Y
: Node_Access
);
53 procedure Check_Invariant
(Tree
: Tree_Type
) is
54 Root
: constant Node_Access
:= Tree
.Root
;
56 function Check
(Node
: Node_Access
) return Natural;
62 function Check
(Node
: Node_Access
) return Natural is
64 if Node
= Null_Node
then
68 if Color
(Node
) = Red
then
70 L
: constant Node_Access
:= Left
(Node
);
72 pragma Assert
(L
= Null_Node
or else Color
(L
) = Black
);
77 R
: constant Node_Access
:= Right
(Node
);
79 pragma Assert
(R
= Null_Node
or else Color
(R
) = Black
);
84 NL
: constant Natural := Check
(Left
(Node
));
85 NR
: constant Natural := Check
(Right
(Node
));
87 pragma Assert
(NL
= NR
);
93 NL
: constant Natural := Check
(Left
(Node
));
94 NR
: constant Natural := Check
(Right
(Node
));
96 pragma Assert
(NL
= NR
);
101 -- Start of processing for Check_Invariant
104 if Root
= Null_Node
then
105 pragma Assert
(Tree
.First
= Null_Node
);
106 pragma Assert
(Tree
.Last
= Null_Node
);
107 pragma Assert
(Tree
.Length
= 0);
111 pragma Assert
(Color
(Root
) = Black
);
112 pragma Assert
(Tree
.Length
> 0);
113 pragma Assert
(Tree
.Root
/= Null_Node
);
114 pragma Assert
(Tree
.First
/= Null_Node
);
115 pragma Assert
(Tree
.Last
/= Null_Node
);
116 pragma Assert
(Parent
(Tree
.Root
) = Null_Node
);
117 pragma Assert
((Tree
.Length
> 1)
118 or else (Tree
.First
= Tree
.Last
119 and Tree
.First
= Tree
.Root
));
120 pragma Assert
(Left
(Tree
.First
) = Null_Node
);
121 pragma Assert
(Right
(Tree
.Last
) = Null_Node
);
124 L
: constant Node_Access
:= Left
(Root
);
125 R
: constant Node_Access
:= Right
(Root
);
126 NL
: constant Natural := Check
(L
);
127 NR
: constant Natural := Check
(R
);
129 pragma Assert
(NL
= NR
);
139 procedure Delete_Fixup
(Tree
: in out Tree_Type
; Node
: Node_Access
) is
143 X
: Node_Access
:= Node
;
148 and then Color
(X
) = Black
150 if X
= Left
(Parent
(X
)) then
151 W
:= Right
(Parent
(X
));
153 if Color
(W
) = Red
then
154 Set_Color
(W
, Black
);
155 Set_Color
(Parent
(X
), Red
);
156 Left_Rotate
(Tree
, Parent
(X
));
157 W
:= Right
(Parent
(X
));
160 if (Left
(W
) = Null_Node
or else Color
(Left
(W
)) = Black
)
162 (Right
(W
) = Null_Node
or else Color
(Right
(W
)) = Black
)
168 if Right
(W
) = Null_Node
169 or else Color
(Right
(W
)) = Black
171 if Left
(W
) /= Null_Node
then
172 Set_Color
(Left
(W
), Black
);
176 Right_Rotate
(Tree
, W
);
177 W
:= Right
(Parent
(X
));
180 Set_Color
(W
, Color
(Parent
(X
)));
181 Set_Color
(Parent
(X
), Black
);
182 Set_Color
(Right
(W
), Black
);
183 Left_Rotate
(Tree
, Parent
(X
));
188 pragma Assert
(X
= Right
(Parent
(X
)));
190 W
:= Left
(Parent
(X
));
192 if Color
(W
) = Red
then
193 Set_Color
(W
, Black
);
194 Set_Color
(Parent
(X
), Red
);
195 Right_Rotate
(Tree
, Parent
(X
));
196 W
:= Left
(Parent
(X
));
199 if (Left
(W
) = Null_Node
or else Color
(Left
(W
)) = Black
)
201 (Right
(W
) = Null_Node
or else Color
(Right
(W
)) = Black
)
207 if Left
(W
) = Null_Node
or else Color
(Left
(W
)) = Black
then
208 if Right
(W
) /= Null_Node
then
209 Set_Color
(Right
(W
), Black
);
213 Left_Rotate
(Tree
, W
);
214 W
:= Left
(Parent
(X
));
217 Set_Color
(W
, Color
(Parent
(X
)));
218 Set_Color
(Parent
(X
), Black
);
219 Set_Color
(Left
(W
), Black
);
220 Right_Rotate
(Tree
, Parent
(X
));
226 Set_Color
(X
, Black
);
229 ---------------------------
230 -- Delete_Node_Sans_Free --
231 ---------------------------
233 procedure Delete_Node_Sans_Free
234 (Tree
: in out Tree_Type
;
241 Z
: constant Node_Access
:= Node
;
242 pragma Assert
(Z
/= Null_Node
);
245 pragma Assert
(Tree
.Length
> 0);
246 pragma Assert
(Tree
.Root
/= Null_Node
);
247 pragma Assert
(Tree
.First
/= Null_Node
);
248 pragma Assert
(Tree
.Last
/= Null_Node
);
249 pragma Assert
(Parent
(Tree
.Root
) = Null_Node
);
250 pragma Assert
((Tree
.Length
> 1)
251 or else (Tree
.First
= Tree
.Last
252 and then Tree
.First
= Tree
.Root
));
253 pragma Assert
((Left
(Node
) = Null_Node
)
254 or else (Parent
(Left
(Node
)) = Node
));
255 pragma Assert
((Right
(Node
) = Null_Node
)
256 or else (Parent
(Right
(Node
)) = Node
));
257 pragma Assert
(((Parent
(Node
) = Null_Node
) and then (Tree
.Root
= Node
))
258 or else ((Parent
(Node
) /= Null_Node
) and then
259 ((Left
(Parent
(Node
)) = Node
)
260 or else (Right
(Parent
(Node
)) = Node
))));
262 if Left
(Z
) = Null_Node
then
263 if Right
(Z
) = Null_Node
then
264 if Z
= Tree
.First
then
265 Tree
.First
:= Parent
(Z
);
268 if Z
= Tree
.Last
then
269 Tree
.Last
:= Parent
(Z
);
272 if Color
(Z
) = Black
then
273 Delete_Fixup
(Tree
, Z
);
276 pragma Assert
(Left
(Z
) = Null_Node
);
277 pragma Assert
(Right
(Z
) = Null_Node
);
279 if Z
= Tree
.Root
then
280 pragma Assert
(Tree
.Length
= 1);
281 pragma Assert
(Parent
(Z
) = Null_Node
);
282 Tree
.Root
:= Null_Node
;
283 elsif Z
= Left
(Parent
(Z
)) then
284 Set_Left
(Parent
(Z
), Null_Node
);
286 pragma Assert
(Z
= Right
(Parent
(Z
)));
287 Set_Right
(Parent
(Z
), Null_Node
);
291 pragma Assert
(Z
/= Tree
.Last
);
295 if Z
= Tree
.First
then
296 Tree
.First
:= Min
(X
);
299 if Z
= Tree
.Root
then
301 elsif Z
= Left
(Parent
(Z
)) then
302 Set_Left
(Parent
(Z
), X
);
304 pragma Assert
(Z
= Right
(Parent
(Z
)));
305 Set_Right
(Parent
(Z
), X
);
308 Set_Parent
(X
, Parent
(Z
));
310 if Color
(Z
) = Black
then
311 Delete_Fixup
(Tree
, X
);
315 elsif Right
(Z
) = Null_Node
then
316 pragma Assert
(Z
/= Tree
.First
);
320 if Z
= Tree
.Last
then
321 Tree
.Last
:= Max
(X
);
324 if Z
= Tree
.Root
then
326 elsif Z
= Left
(Parent
(Z
)) then
327 Set_Left
(Parent
(Z
), X
);
329 pragma Assert
(Z
= Right
(Parent
(Z
)));
330 Set_Right
(Parent
(Z
), X
);
333 Set_Parent
(X
, Parent
(Z
));
335 if Color
(Z
) = Black
then
336 Delete_Fixup
(Tree
, X
);
340 pragma Assert
(Z
/= Tree
.First
);
341 pragma Assert
(Z
/= Tree
.Last
);
344 pragma Assert
(Left
(Y
) = Null_Node
);
348 if X
= Null_Node
then
349 if Y
= Left
(Parent
(Y
)) then
350 pragma Assert
(Parent
(Y
) /= Z
);
351 Delete_Swap
(Tree
, Z
, Y
);
352 Set_Left
(Parent
(Z
), Z
);
355 pragma Assert
(Y
= Right
(Parent
(Y
)));
356 pragma Assert
(Parent
(Y
) = Z
);
357 Set_Parent
(Y
, Parent
(Z
));
359 if Z
= Tree
.Root
then
361 elsif Z
= Left
(Parent
(Z
)) then
362 Set_Left
(Parent
(Z
), Y
);
364 pragma Assert
(Z
= Right
(Parent
(Z
)));
365 Set_Right
(Parent
(Z
), Y
);
368 Set_Left
(Y
, Left
(Z
));
369 Set_Parent
(Left
(Y
), Y
);
372 Set_Left
(Z
, Null_Node
);
373 Set_Right
(Z
, Null_Node
);
376 Y_Color
: constant Color_Type
:= Color
(Y
);
378 Set_Color
(Y
, Color
(Z
));
379 Set_Color
(Z
, Y_Color
);
383 if Color
(Z
) = Black
then
384 Delete_Fixup
(Tree
, Z
);
387 pragma Assert
(Left
(Z
) = Null_Node
);
388 pragma Assert
(Right
(Z
) = Null_Node
);
390 if Z
= Right
(Parent
(Z
)) then
391 Set_Right
(Parent
(Z
), Null_Node
);
393 pragma Assert
(Z
= Left
(Parent
(Z
)));
394 Set_Left
(Parent
(Z
), Null_Node
);
398 if Y
= Left
(Parent
(Y
)) then
399 pragma Assert
(Parent
(Y
) /= Z
);
401 Delete_Swap
(Tree
, Z
, Y
);
403 Set_Left
(Parent
(Z
), X
);
404 Set_Parent
(X
, Parent
(Z
));
407 pragma Assert
(Y
= Right
(Parent
(Y
)));
408 pragma Assert
(Parent
(Y
) = Z
);
410 Set_Parent
(Y
, Parent
(Z
));
412 if Z
= Tree
.Root
then
414 elsif Z
= Left
(Parent
(Z
)) then
415 Set_Left
(Parent
(Z
), Y
);
417 pragma Assert
(Z
= Right
(Parent
(Z
)));
418 Set_Right
(Parent
(Z
), Y
);
421 Set_Left
(Y
, Left
(Z
));
422 Set_Parent
(Left
(Y
), Y
);
425 Y_Color
: constant Color_Type
:= Color
(Y
);
427 Set_Color
(Y
, Color
(Z
));
428 Set_Color
(Z
, Y_Color
);
432 if Color
(Z
) = Black
then
433 Delete_Fixup
(Tree
, X
);
438 Tree
.Length
:= Tree
.Length
- 1;
439 end Delete_Node_Sans_Free
;
445 procedure Delete_Swap
446 (Tree
: in out Tree_Type
;
449 pragma Assert
(Z
/= Y
);
450 pragma Assert
(Parent
(Y
) /= Z
);
452 Y_Parent
: constant Node_Access
:= Parent
(Y
);
453 Y_Color
: constant Color_Type
:= Color
(Y
);
456 Set_Parent
(Y
, Parent
(Z
));
457 Set_Left
(Y
, Left
(Z
));
458 Set_Right
(Y
, Right
(Z
));
459 Set_Color
(Y
, Color
(Z
));
461 if Tree
.Root
= Z
then
463 elsif Right
(Parent
(Y
)) = Z
then
464 Set_Right
(Parent
(Y
), Y
);
466 pragma Assert
(Left
(Parent
(Y
)) = Z
);
467 Set_Left
(Parent
(Y
), Y
);
470 if Right
(Y
) /= Null_Node
then
471 Set_Parent
(Right
(Y
), Y
);
474 if Left
(Y
) /= Null_Node
then
475 Set_Parent
(Left
(Y
), Y
);
478 Set_Parent
(Z
, Y_Parent
);
479 Set_Color
(Z
, Y_Color
);
480 Set_Left
(Z
, Null_Node
);
481 Set_Right
(Z
, Null_Node
);
488 function Generic_Equal
(Left
, Right
: Tree_Type
) return Boolean is
489 L_Node
: Node_Access
;
490 R_Node
: Node_Access
;
493 if Left
.Length
/= Right
.Length
then
497 L_Node
:= Left
.First
;
498 R_Node
:= Right
.First
;
499 while L_Node
/= Null_Node
loop
500 if not Is_Equal
(L_Node
, R_Node
) then
504 L_Node
:= Next
(L_Node
);
505 R_Node
:= Next
(R_Node
);
511 -----------------------
512 -- Generic_Iteration --
513 -----------------------
515 procedure Generic_Iteration
(Tree
: Tree_Type
) is
516 procedure Iterate
(P
: Node_Access
);
522 procedure Iterate
(P
: Node_Access
) is
523 X
: Node_Access
:= P
;
525 while X
/= Null_Node
loop
532 -- Start of processing for Generic_Iteration
536 end Generic_Iteration
;
542 procedure Generic_Read
(Tree
: in out Tree_Type
; N
: Count_Type
) is
544 pragma Assert
(Tree
.Length
= 0);
545 -- Clear and back node reinit was done by caller
547 Node
, Last_Node
: Node_Access
;
555 pragma Assert
(Node
/= Null_Node
);
556 pragma Assert
(Color
(Node
) = Red
);
558 Set_Color
(Node
, Black
);
566 for J
in Count_Type
range 2 .. N
loop
568 pragma Assert
(Last_Node
= Tree
.Last
);
571 pragma Assert
(Node
/= Null_Node
);
572 pragma Assert
(Color
(Node
) = Red
);
574 Set_Right
(Node
=> Last_Node
, Right
=> Node
);
576 Set_Parent
(Node
=> Node
, Parent
=> Last_Node
);
577 Rebalance_For_Insert
(Tree
, Node
);
578 Tree
.Length
:= Tree
.Length
+ 1;
582 -------------------------------
583 -- Generic_Reverse_Iteration --
584 -------------------------------
586 procedure Generic_Reverse_Iteration
(Tree
: Tree_Type
)
588 procedure Iterate
(P
: Node_Access
);
594 procedure Iterate
(P
: Node_Access
) is
595 X
: Node_Access
:= P
;
597 while X
/= Null_Node
loop
604 -- Start of processing for Generic_Reverse_Iteration
608 end Generic_Reverse_Iteration
;
614 procedure Left_Rotate
(Tree
: in out Tree_Type
; X
: Node_Access
) is
618 Y
: constant Node_Access
:= Right
(X
);
619 pragma Assert
(Y
/= Null_Node
);
622 Set_Right
(X
, Left
(Y
));
624 if Left
(Y
) /= Null_Node
then
625 Set_Parent
(Left
(Y
), X
);
628 Set_Parent
(Y
, Parent
(X
));
630 if X
= Tree
.Root
then
632 elsif X
= Left
(Parent
(X
)) then
633 Set_Left
(Parent
(X
), Y
);
635 pragma Assert
(X
= Right
(Parent
(X
)));
636 Set_Right
(Parent
(X
), Y
);
647 function Max
(Node
: Node_Access
) return Node_Access
is
651 X
: Node_Access
:= Node
;
658 if Y
= Null_Node
then
670 function Min
(Node
: Node_Access
) return Node_Access
is
674 X
: Node_Access
:= Node
;
681 if Y
= Null_Node
then
693 procedure Move
(Target
, Source
: in out Tree_Type
) is
695 if Target
.Length
> 0 then
696 raise Constraint_Error
;
700 Source
:= (First
=> Null_Node
,
710 function Next
(Node
: Node_Access
) return Node_Access
is
714 if Node
= Null_Node
then
718 if Right
(Node
) /= Null_Node
then
719 return Min
(Right
(Node
));
723 X
: Node_Access
:= Node
;
724 Y
: Node_Access
:= Parent
(Node
);
728 and then X
= Right
(Y
)
734 -- Why is this code commented out ???
736 -- if Right (X) /= Y then
750 function Previous
(Node
: Node_Access
) return Node_Access
is
752 if Node
= Null_Node
then
756 if Left
(Node
) /= Null_Node
then
757 return Max
(Left
(Node
));
761 X
: Node_Access
:= Node
;
762 Y
: Node_Access
:= Parent
(Node
);
766 and then X
= Left
(Y
)
772 -- Why is this code commented out ???
774 -- if Left (X) /= Y then
784 --------------------------
785 -- Rebalance_For_Insert --
786 --------------------------
788 procedure Rebalance_For_Insert
789 (Tree
: in out Tree_Type
;
794 X
: Node_Access
:= Node
;
795 pragma Assert
(X
/= Null_Node
);
796 pragma Assert
(Color
(X
) = Red
);
801 while X
/= Tree
.Root
and then Color
(Parent
(X
)) = Red
loop
802 if Parent
(X
) = Left
(Parent
(Parent
(X
))) then
803 Y
:= Right
(Parent
(Parent
(X
)));
805 if Y
/= Null_Node
and then Color
(Y
) = Red
then
806 Set_Color
(Parent
(X
), Black
);
807 Set_Color
(Y
, Black
);
808 Set_Color
(Parent
(Parent
(X
)), Red
);
809 X
:= Parent
(Parent
(X
));
812 if X
= Right
(Parent
(X
)) then
814 Left_Rotate
(Tree
, X
);
817 Set_Color
(Parent
(X
), Black
);
818 Set_Color
(Parent
(Parent
(X
)), Red
);
819 Right_Rotate
(Tree
, Parent
(Parent
(X
)));
823 pragma Assert
(Parent
(X
) = Right
(Parent
(Parent
(X
))));
825 Y
:= Left
(Parent
(Parent
(X
)));
827 if Y
/= Null_Node
and then Color
(Y
) = Red
then
828 Set_Color
(Parent
(X
), Black
);
829 Set_Color
(Y
, Black
);
830 Set_Color
(Parent
(Parent
(X
)), Red
);
831 X
:= Parent
(Parent
(X
));
834 if X
= Left
(Parent
(X
)) then
836 Right_Rotate
(Tree
, X
);
839 Set_Color
(Parent
(X
), Black
);
840 Set_Color
(Parent
(Parent
(X
)), Red
);
841 Left_Rotate
(Tree
, Parent
(Parent
(X
)));
846 Set_Color
(Tree
.Root
, Black
);
847 end Rebalance_For_Insert
;
853 procedure Right_Rotate
(Tree
: in out Tree_Type
; Y
: Node_Access
) is
854 X
: constant Node_Access
:= Left
(Y
);
855 pragma Assert
(X
/= Null_Node
);
858 Set_Left
(Y
, Right
(X
));
860 if Right
(X
) /= Null_Node
then
861 Set_Parent
(Right
(X
), Y
);
864 Set_Parent
(X
, Parent
(Y
));
866 if Y
= Tree
.Root
then
868 elsif Y
= Left
(Parent
(Y
)) then
869 Set_Left
(Parent
(Y
), X
);
871 pragma Assert
(Y
= Right
(Parent
(Y
)));
872 Set_Right
(Parent
(Y
), X
);
879 end Ada
.Containers
.Red_Black_Trees
.Generic_Operations
;