1 ------------------------------------------------------------------------------
3 -- GNAT LIBRARY COMPONENTS --
5 -- ADA.CONTAINERS.RED_BLACK_TREES.GENERIC_BOUNDED_OPERATIONS --
9 -- Copyright (C) 2004-2011, Free Software Foundation, Inc. --
11 -- GNAT is free software; you can redistribute it and/or modify it under --
12 -- terms of the GNU General Public License as published by the Free Soft- --
13 -- ware Foundation; either version 3, or (at your option) any later ver- --
14 -- sion. GNAT is distributed in the hope that it will be useful, but WITH- --
15 -- OUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY --
16 -- or FITNESS FOR A PARTICULAR PURPOSE. --
18 -- As a special exception under Section 7 of GPL version 3, you are granted --
19 -- additional permissions described in the GCC Runtime Library Exception, --
20 -- version 3.1, as published by the Free Software Foundation. --
22 -- You should have received a copy of the GNU General Public License and --
23 -- a copy of the GCC Runtime Library Exception along with this program; --
24 -- see the files COPYING3 and COPYING.RUNTIME respectively. If not, see --
25 -- <http://www.gnu.org/licenses/>. --
27 -- This unit was originally developed by Matthew J Heaney. --
28 ------------------------------------------------------------------------------
30 -- The references below to "CLR" refer to the following book, from which
31 -- several of the algorithms here were adapted:
32 -- Introduction to Algorithms
33 -- by Thomas H. Cormen, Charles E. Leiserson, Ronald L. Rivest
34 -- Publisher: The MIT Press (June 18, 1990)
37 with System; use type System.Address;
39 package body Ada.Containers.Red_Black_Trees.Generic_Bounded_Operations is
41 -----------------------
42 -- Local Subprograms --
43 -----------------------
45 procedure Delete_Fixup (Tree : in out Tree_Type'Class; Node : Count_Type);
46 procedure Delete_Swap (Tree : in out Tree_Type'Class; Z, Y : Count_Type);
48 procedure Left_Rotate (Tree : in out Tree_Type'Class; X : Count_Type);
49 procedure Right_Rotate (Tree : in out Tree_Type'Class; Y : Count_Type);
55 procedure Clear_Tree (Tree : in out Tree_Type'Class) is
58 raise Program_Error with
59 "attempt to tamper with cursors (container is busy)";
75 procedure Delete_Fixup
76 (Tree : in out Tree_Type'Class;
84 N : Nodes_Type renames Tree.Nodes;
89 and then Color (N (X)) = Black
91 if X = Left (N (Parent (N (X)))) then
92 W := Right (N (Parent (N (X))));
94 if Color (N (W)) = Red then
95 Set_Color (N (W), Black);
96 Set_Color (N (Parent (N (X))), Red);
97 Left_Rotate (Tree, Parent (N (X)));
98 W := Right (N (Parent (N (X))));
101 if (Left (N (W)) = 0 or else Color (N (Left (N (W)))) = Black)
103 (Right (N (W)) = 0 or else Color (N (Right (N (W)))) = Black)
105 Set_Color (N (W), Red);
110 or else Color (N (Right (N (W)))) = Black
112 -- As a condition for setting the color of the left child to
113 -- black, the left child access value must be non-null. A
114 -- truth table analysis shows that if we arrive here, that
115 -- condition holds, so there's no need for an explicit test.
116 -- The assertion is here to document what we know is true.
118 pragma Assert (Left (N (W)) /= 0);
119 Set_Color (N (Left (N (W))), Black);
121 Set_Color (N (W), Red);
122 Right_Rotate (Tree, W);
123 W := Right (N (Parent (N (X))));
126 Set_Color (N (W), Color (N (Parent (N (X)))));
127 Set_Color (N (Parent (N (X))), Black);
128 Set_Color (N (Right (N (W))), Black);
129 Left_Rotate (Tree, Parent (N (X)));
134 pragma Assert (X = Right (N (Parent (N (X)))));
136 W := Left (N (Parent (N (X))));
138 if Color (N (W)) = Red then
139 Set_Color (N (W), Black);
140 Set_Color (N (Parent (N (X))), Red);
141 Right_Rotate (Tree, Parent (N (X)));
142 W := Left (N (Parent (N (X))));
145 if (Left (N (W)) = 0 or else Color (N (Left (N (W)))) = Black)
147 (Right (N (W)) = 0 or else Color (N (Right (N (W)))) = Black)
149 Set_Color (N (W), Red);
154 or else Color (N (Left (N (W)))) = Black
156 -- As a condition for setting the color of the right child
157 -- to black, the right child access value must be non-null.
158 -- A truth table analysis shows that if we arrive here, that
159 -- condition holds, so there's no need for an explicit test.
160 -- The assertion is here to document what we know is true.
162 pragma Assert (Right (N (W)) /= 0);
163 Set_Color (N (Right (N (W))), Black);
165 Set_Color (N (W), Red);
166 Left_Rotate (Tree, W);
167 W := Left (N (Parent (N (X))));
170 Set_Color (N (W), Color (N (Parent (N (X)))));
171 Set_Color (N (Parent (N (X))), Black);
172 Set_Color (N (Left (N (W))), Black);
173 Right_Rotate (Tree, Parent (N (X)));
179 Set_Color (N (X), Black);
182 ---------------------------
183 -- Delete_Node_Sans_Free --
184 ---------------------------
186 procedure Delete_Node_Sans_Free
187 (Tree : in out Tree_Type'Class;
194 Z : constant Count_Type := Node;
195 pragma Assert (Z /= 0);
197 N : Nodes_Type renames Tree.Nodes;
200 if Tree.Busy > 0 then
201 raise Program_Error with
202 "attempt to tamper with cursors (container is busy)";
205 pragma Assert (Tree.Length > 0);
206 pragma Assert (Tree.Root /= 0);
207 pragma Assert (Tree.First /= 0);
208 pragma Assert (Tree.Last /= 0);
209 pragma Assert (Parent (N (Tree.Root)) = 0);
211 pragma Assert ((Tree.Length > 1)
212 or else (Tree.First = Tree.Last
213 and then Tree.First = Tree.Root));
215 pragma Assert ((Left (N (Node)) = 0)
216 or else (Parent (N (Left (N (Node)))) = Node));
218 pragma Assert ((Right (N (Node)) = 0)
219 or else (Parent (N (Right (N (Node)))) = Node));
221 pragma Assert (((Parent (N (Node)) = 0) and then (Tree.Root = Node))
222 or else ((Parent (N (Node)) /= 0) and then
223 ((Left (N (Parent (N (Node)))) = Node)
225 (Right (N (Parent (N (Node)))) = Node))));
227 if Left (N (Z)) = 0 then
228 if Right (N (Z)) = 0 then
229 if Z = Tree.First then
230 Tree.First := Parent (N (Z));
233 if Z = Tree.Last then
234 Tree.Last := Parent (N (Z));
237 if Color (N (Z)) = Black then
238 Delete_Fixup (Tree, Z);
241 pragma Assert (Left (N (Z)) = 0);
242 pragma Assert (Right (N (Z)) = 0);
244 if Z = Tree.Root then
245 pragma Assert (Tree.Length = 1);
246 pragma Assert (Parent (N (Z)) = 0);
248 elsif Z = Left (N (Parent (N (Z)))) then
249 Set_Left (N (Parent (N (Z))), 0);
251 pragma Assert (Z = Right (N (Parent (N (Z)))));
252 Set_Right (N (Parent (N (Z))), 0);
256 pragma Assert (Z /= Tree.Last);
260 if Z = Tree.First then
261 Tree.First := Min (Tree, X);
264 if Z = Tree.Root then
266 elsif Z = Left (N (Parent (N (Z)))) then
267 Set_Left (N (Parent (N (Z))), X);
269 pragma Assert (Z = Right (N (Parent (N (Z)))));
270 Set_Right (N (Parent (N (Z))), X);
273 Set_Parent (N (X), Parent (N (Z)));
275 if Color (N (Z)) = Black then
276 Delete_Fixup (Tree, X);
280 elsif Right (N (Z)) = 0 then
281 pragma Assert (Z /= Tree.First);
285 if Z = Tree.Last then
286 Tree.Last := Max (Tree, X);
289 if Z = Tree.Root then
291 elsif Z = Left (N (Parent (N (Z)))) then
292 Set_Left (N (Parent (N (Z))), X);
294 pragma Assert (Z = Right (N (Parent (N (Z)))));
295 Set_Right (N (Parent (N (Z))), X);
298 Set_Parent (N (X), Parent (N (Z)));
300 if Color (N (Z)) = Black then
301 Delete_Fixup (Tree, X);
305 pragma Assert (Z /= Tree.First);
306 pragma Assert (Z /= Tree.Last);
309 pragma Assert (Left (N (Y)) = 0);
314 if Y = Left (N (Parent (N (Y)))) then
315 pragma Assert (Parent (N (Y)) /= Z);
316 Delete_Swap (Tree, Z, Y);
317 Set_Left (N (Parent (N (Z))), Z);
320 pragma Assert (Y = Right (N (Parent (N (Y)))));
321 pragma Assert (Parent (N (Y)) = Z);
322 Set_Parent (N (Y), Parent (N (Z)));
324 if Z = Tree.Root then
326 elsif Z = Left (N (Parent (N (Z)))) then
327 Set_Left (N (Parent (N (Z))), Y);
329 pragma Assert (Z = Right (N (Parent (N (Z)))));
330 Set_Right (N (Parent (N (Z))), Y);
333 Set_Left (N (Y), Left (N (Z)));
334 Set_Parent (N (Left (N (Y))), Y);
335 Set_Right (N (Y), Z);
337 Set_Parent (N (Z), Y);
339 Set_Right (N (Z), 0);
342 Y_Color : constant Color_Type := Color (N (Y));
344 Set_Color (N (Y), Color (N (Z)));
345 Set_Color (N (Z), Y_Color);
349 if Color (N (Z)) = Black then
350 Delete_Fixup (Tree, Z);
353 pragma Assert (Left (N (Z)) = 0);
354 pragma Assert (Right (N (Z)) = 0);
356 if Z = Right (N (Parent (N (Z)))) then
357 Set_Right (N (Parent (N (Z))), 0);
359 pragma Assert (Z = Left (N (Parent (N (Z)))));
360 Set_Left (N (Parent (N (Z))), 0);
364 if Y = Left (N (Parent (N (Y)))) then
365 pragma Assert (Parent (N (Y)) /= Z);
367 Delete_Swap (Tree, Z, Y);
369 Set_Left (N (Parent (N (Z))), X);
370 Set_Parent (N (X), Parent (N (Z)));
373 pragma Assert (Y = Right (N (Parent (N (Y)))));
374 pragma Assert (Parent (N (Y)) = Z);
376 Set_Parent (N (Y), Parent (N (Z)));
378 if Z = Tree.Root then
380 elsif Z = Left (N (Parent (N (Z)))) then
381 Set_Left (N (Parent (N (Z))), Y);
383 pragma Assert (Z = Right (N (Parent (N (Z)))));
384 Set_Right (N (Parent (N (Z))), Y);
387 Set_Left (N (Y), Left (N (Z)));
388 Set_Parent (N (Left (N (Y))), Y);
391 Y_Color : constant Color_Type := Color (N (Y));
393 Set_Color (N (Y), Color (N (Z)));
394 Set_Color (N (Z), Y_Color);
398 if Color (N (Z)) = Black then
399 Delete_Fixup (Tree, X);
404 Tree.Length := Tree.Length - 1;
405 end Delete_Node_Sans_Free;
411 procedure Delete_Swap
412 (Tree : in out Tree_Type'Class;
415 N : Nodes_Type renames Tree.Nodes;
417 pragma Assert (Z /= Y);
418 pragma Assert (Parent (N (Y)) /= Z);
420 Y_Parent : constant Count_Type := Parent (N (Y));
421 Y_Color : constant Color_Type := Color (N (Y));
424 Set_Parent (N (Y), Parent (N (Z)));
425 Set_Left (N (Y), Left (N (Z)));
426 Set_Right (N (Y), Right (N (Z)));
427 Set_Color (N (Y), Color (N (Z)));
429 if Tree.Root = Z then
431 elsif Right (N (Parent (N (Y)))) = Z then
432 Set_Right (N (Parent (N (Y))), Y);
434 pragma Assert (Left (N (Parent (N (Y)))) = Z);
435 Set_Left (N (Parent (N (Y))), Y);
438 if Right (N (Y)) /= 0 then
439 Set_Parent (N (Right (N (Y))), Y);
442 if Left (N (Y)) /= 0 then
443 Set_Parent (N (Left (N (Y))), Y);
446 Set_Parent (N (Z), Y_Parent);
447 Set_Color (N (Z), Y_Color);
449 Set_Right (N (Z), 0);
456 procedure Free (Tree : in out Tree_Type'Class; X : Count_Type) is
457 pragma Assert (X > 0);
458 pragma Assert (X <= Tree.Capacity);
460 N : Nodes_Type renames Tree.Nodes;
461 -- pragma Assert (N (X).Prev >= 0); -- node is active
462 -- Find a way to mark a node as active vs. inactive; we could
463 -- use a special value in Color_Type for this. ???
466 -- The set container actually contains two data structures: a list for
467 -- the "active" nodes that contain elements that have been inserted
468 -- onto the tree, and another for the "inactive" nodes of the free
471 -- We desire that merely declaring an object should have only minimal
472 -- cost; specially, we want to avoid having to initialize the free
473 -- store (to fill in the links), especially if the capacity is large.
475 -- The head of the free list is indicated by Container.Free. If its
476 -- value is non-negative, then the free store has been initialized
477 -- in the "normal" way: Container.Free points to the head of the list
478 -- of free (inactive) nodes, and the value 0 means the free list is
479 -- empty. Each node on the free list has been initialized to point
480 -- to the next free node (via its Parent component), and the value 0
481 -- means that this is the last free node.
483 -- If Container.Free is negative, then the links on the free store
484 -- have not been initialized. In this case the link values are
485 -- implied: the free store comprises the components of the node array
486 -- started with the absolute value of Container.Free, and continuing
487 -- until the end of the array (Nodes'Last).
490 -- It might be possible to perform an optimization here. Suppose that
491 -- the free store can be represented as having two parts: one
492 -- comprising the non-contiguous inactive nodes linked together
493 -- in the normal way, and the other comprising the contiguous
494 -- inactive nodes (that are not linked together, at the end of the
495 -- nodes array). This would allow us to never have to initialize
496 -- the free store, except in a lazy way as nodes become inactive.
498 -- When an element is deleted from the list container, its node
499 -- becomes inactive, and so we set its Prev component to a negative
500 -- value, to indicate that it is now inactive. This provides a useful
501 -- way to detect a dangling cursor reference.
503 -- The comment above is incorrect; we need some other way to
504 -- indicate a node is inactive, for example by using a special
505 -- Color_Type value. ???
506 -- N (X).Prev := -1; -- Node is deallocated (not on active list)
508 if Tree.Free >= 0 then
509 -- The free store has previously been initialized. All we need to
510 -- do here is link the newly-free'd node onto the free list.
512 Set_Parent (N (X), Tree.Free);
515 elsif X + 1 = abs Tree.Free then
516 -- The free store has not been initialized, and the node becoming
517 -- inactive immediately precedes the start of the free store. All
518 -- we need to do is move the start of the free store back by one.
520 Tree.Free := Tree.Free + 1;
523 -- The free store has not been initialized, and the node becoming
524 -- inactive does not immediately precede the free store. Here we
525 -- first initialize the free store (meaning the links are given
526 -- values in the traditional way), and then link the newly-free'd
527 -- node onto the head of the free store.
530 -- See the comments above for an optimization opportunity. If the
531 -- next link for a node on the free store is negative, then this
532 -- means the remaining nodes on the free store are physically
533 -- contiguous, starting as the absolute value of that index value.
535 Tree.Free := abs Tree.Free;
537 if Tree.Free > Tree.Capacity then
541 for I in Tree.Free .. Tree.Capacity - 1 loop
542 Set_Parent (N (I), I + 1);
545 Set_Parent (N (Tree.Capacity), 0);
548 Set_Parent (N (X), Tree.Free);
553 -----------------------
554 -- Generic_Allocate --
555 -----------------------
557 procedure Generic_Allocate
558 (Tree : in out Tree_Type'Class;
559 Node : out Count_Type)
561 N : Nodes_Type renames Tree.Nodes;
564 if Tree.Free >= 0 then
567 -- We always perform the assignment first, before we
568 -- change container state, in order to defend against
569 -- exceptions duration assignment.
571 Set_Element (N (Node));
572 Tree.Free := Parent (N (Node));
575 -- A negative free store value means that the links of the nodes
576 -- in the free store have not been initialized. In this case, the
577 -- nodes are physically contiguous in the array, starting at the
578 -- index that is the absolute value of the Container.Free, and
579 -- continuing until the end of the array (Nodes'Last).
581 Node := abs Tree.Free;
583 -- As above, we perform this assignment first, before modifying
584 -- any container state.
586 Set_Element (N (Node));
587 Tree.Free := Tree.Free - 1;
590 -- When a node is allocated from the free store, its pointer components
591 -- (the links to other nodes in the tree) must also be initialized (to
592 -- 0, the equivalent of null). This simplifies the post-allocation
593 -- handling of nodes inserted into terminal positions.
595 Set_Parent (N (Node), Parent => 0);
596 Set_Left (N (Node), Left => 0);
597 Set_Right (N (Node), Right => 0);
598 end Generic_Allocate;
604 function Generic_Equal (Left, Right : Tree_Type'Class) return Boolean is
609 if Left'Address = Right'Address then
613 if Left.Length /= Right.Length then
617 L_Node := Left.First;
618 R_Node := Right.First;
619 while L_Node /= 0 loop
620 if not Is_Equal (Left.Nodes (L_Node), Right.Nodes (R_Node)) then
624 L_Node := Next (Left, L_Node);
625 R_Node := Next (Right, R_Node);
631 -----------------------
632 -- Generic_Iteration --
633 -----------------------
635 procedure Generic_Iteration (Tree : Tree_Type'Class) is
636 procedure Iterate (P : Count_Type);
642 procedure Iterate (P : Count_Type) is
646 Iterate (Left (Tree.Nodes (X)));
648 X := Right (Tree.Nodes (X));
652 -- Start of processing for Generic_Iteration
656 end Generic_Iteration;
662 procedure Generic_Read
663 (Stream : not null access Root_Stream_Type'Class;
664 Tree : in out Tree_Type'Class)
666 Len : Count_Type'Base;
668 Node, Last_Node : Count_Type;
670 N : Nodes_Type renames Tree.Nodes;
674 Count_Type'Base'Read (Stream, Len);
677 raise Program_Error with "bad container length (corrupt stream)";
684 if Len > Tree.Capacity then
685 raise Constraint_Error with "length exceeds capacity";
688 -- Use Unconditional_Insert_With_Hint here instead ???
690 Allocate (Tree, Node);
691 pragma Assert (Node /= 0);
693 Set_Color (N (Node), Black);
700 for J in Count_Type range 2 .. Len loop
702 pragma Assert (Last_Node = Tree.Last);
704 Allocate (Tree, Node);
705 pragma Assert (Node /= 0);
707 Set_Color (N (Node), Red);
708 Set_Right (N (Last_Node), Right => Node);
710 Set_Parent (N (Node), Parent => Last_Node);
712 Rebalance_For_Insert (Tree, Node);
713 Tree.Length := Tree.Length + 1;
717 -------------------------------
718 -- Generic_Reverse_Iteration --
719 -------------------------------
721 procedure Generic_Reverse_Iteration (Tree : Tree_Type'Class) is
722 procedure Iterate (P : Count_Type);
728 procedure Iterate (P : Count_Type) is
732 Iterate (Right (Tree.Nodes (X)));
734 X := Left (Tree.Nodes (X));
738 -- Start of processing for Generic_Reverse_Iteration
742 end Generic_Reverse_Iteration;
748 procedure Generic_Write
749 (Stream : not null access Root_Stream_Type'Class;
750 Tree : Tree_Type'Class)
752 procedure Process (Node : Count_Type);
753 pragma Inline (Process);
755 procedure Iterate is new Generic_Iteration (Process);
761 procedure Process (Node : Count_Type) is
763 Write_Node (Stream, Tree.Nodes (Node));
766 -- Start of processing for Generic_Write
769 Count_Type'Base'Write (Stream, Tree.Length);
777 procedure Left_Rotate (Tree : in out Tree_Type'Class; X : Count_Type) is
780 N : Nodes_Type renames Tree.Nodes;
782 Y : constant Count_Type := Right (N (X));
783 pragma Assert (Y /= 0);
786 Set_Right (N (X), Left (N (Y)));
788 if Left (N (Y)) /= 0 then
789 Set_Parent (N (Left (N (Y))), X);
792 Set_Parent (N (Y), Parent (N (X)));
794 if X = Tree.Root then
796 elsif X = Left (N (Parent (N (X)))) then
797 Set_Left (N (Parent (N (X))), Y);
799 pragma Assert (X = Right (N (Parent (N (X)))));
800 Set_Right (N (Parent (N (X))), Y);
804 Set_Parent (N (X), Y);
812 (Tree : Tree_Type'Class;
813 Node : Count_Type) return Count_Type
817 X : Count_Type := Node;
822 Y := Right (Tree.Nodes (X));
837 (Tree : Tree_Type'Class;
838 Node : Count_Type) return Count_Type
842 X : Count_Type := Node;
847 Y := Left (Tree.Nodes (X));
862 (Tree : Tree_Type'Class;
863 Node : Count_Type) return Count_Type
872 if Right (Tree.Nodes (Node)) /= 0 then
873 return Min (Tree, Right (Tree.Nodes (Node)));
877 X : Count_Type := Node;
878 Y : Count_Type := Parent (Tree.Nodes (Node));
882 and then X = Right (Tree.Nodes (Y))
885 Y := Parent (Tree.Nodes (Y));
897 (Tree : Tree_Type'Class;
898 Node : Count_Type) return Count_Type
905 if Left (Tree.Nodes (Node)) /= 0 then
906 return Max (Tree, Left (Tree.Nodes (Node)));
910 X : Count_Type := Node;
911 Y : Count_Type := Parent (Tree.Nodes (Node));
915 and then X = Left (Tree.Nodes (Y))
918 Y := Parent (Tree.Nodes (Y));
925 --------------------------
926 -- Rebalance_For_Insert --
927 --------------------------
929 procedure Rebalance_For_Insert
930 (Tree : in out Tree_Type'Class;
935 N : Nodes_Type renames Tree.Nodes;
937 X : Count_Type := Node;
938 pragma Assert (X /= 0);
939 pragma Assert (Color (N (X)) = Red);
944 while X /= Tree.Root and then Color (N (Parent (N (X)))) = Red loop
945 if Parent (N (X)) = Left (N (Parent (N (Parent (N (X)))))) then
946 Y := Right (N (Parent (N (Parent (N (X))))));
948 if Y /= 0 and then Color (N (Y)) = Red then
949 Set_Color (N (Parent (N (X))), Black);
950 Set_Color (N (Y), Black);
951 Set_Color (N (Parent (N (Parent (N (X))))), Red);
952 X := Parent (N (Parent (N (X))));
955 if X = Right (N (Parent (N (X)))) then
957 Left_Rotate (Tree, X);
960 Set_Color (N (Parent (N (X))), Black);
961 Set_Color (N (Parent (N (Parent (N (X))))), Red);
962 Right_Rotate (Tree, Parent (N (Parent (N (X)))));
966 pragma Assert (Parent (N (X)) =
967 Right (N (Parent (N (Parent (N (X)))))));
969 Y := Left (N (Parent (N (Parent (N (X))))));
971 if Y /= 0 and then Color (N (Y)) = Red then
972 Set_Color (N (Parent (N (X))), Black);
973 Set_Color (N (Y), Black);
974 Set_Color (N (Parent (N (Parent (N (X))))), Red);
975 X := Parent (N (Parent (N (X))));
978 if X = Left (N (Parent (N (X)))) then
980 Right_Rotate (Tree, X);
983 Set_Color (N (Parent (N (X))), Black);
984 Set_Color (N (Parent (N (Parent (N (X))))), Red);
985 Left_Rotate (Tree, Parent (N (Parent (N (X)))));
990 Set_Color (N (Tree.Root), Black);
991 end Rebalance_For_Insert;
997 procedure Right_Rotate (Tree : in out Tree_Type'Class; Y : Count_Type) is
998 N : Nodes_Type renames Tree.Nodes;
1000 X : constant Count_Type := Left (N (Y));
1001 pragma Assert (X /= 0);
1004 Set_Left (N (Y), Right (N (X)));
1006 if Right (N (X)) /= 0 then
1007 Set_Parent (N (Right (N (X))), Y);
1010 Set_Parent (N (X), Parent (N (Y)));
1012 if Y = Tree.Root then
1014 elsif Y = Left (N (Parent (N (Y)))) then
1015 Set_Left (N (Parent (N (Y))), X);
1017 pragma Assert (Y = Right (N (Parent (N (Y)))));
1018 Set_Right (N (Parent (N (Y))), X);
1021 Set_Right (N (X), Y);
1022 Set_Parent (N (Y), X);
1029 function Vet (Tree : Tree_Type'Class; Index : Count_Type) return Boolean is
1030 Nodes : Nodes_Type renames Tree.Nodes;
1031 Node : Node_Type renames Nodes (Index);
1034 if Parent (Node) = Index
1035 or else Left (Node) = Index
1036 or else Right (Node) = Index
1042 or else Tree.Root = 0
1043 or else Tree.First = 0
1044 or else Tree.Last = 0
1049 if Parent (Nodes (Tree.Root)) /= 0 then
1053 if Left (Nodes (Tree.First)) /= 0 then
1057 if Right (Nodes (Tree.Last)) /= 0 then
1061 if Tree.Length = 1 then
1062 if Tree.First /= Tree.Last
1063 or else Tree.First /= Tree.Root
1068 if Index /= Tree.First then
1072 if Parent (Node) /= 0
1073 or else Left (Node) /= 0
1074 or else Right (Node) /= 0
1082 if Tree.First = Tree.Last then
1086 if Tree.Length = 2 then
1087 if Tree.First /= Tree.Root
1088 and then Tree.Last /= Tree.Root
1093 if Tree.First /= Index
1094 and then Tree.Last /= Index
1101 and then Parent (Nodes (Left (Node))) /= Index
1106 if Right (Node) /= 0
1107 and then Parent (Nodes (Right (Node))) /= Index
1112 if Parent (Node) = 0 then
1113 if Tree.Root /= Index then
1117 elsif Left (Nodes (Parent (Node))) /= Index
1118 and then Right (Nodes (Parent (Node))) /= Index
1126 end Ada.Containers.Red_Black_Trees.Generic_Bounded_Operations;