diff options
Diffstat (limited to 'gcc-4.7/gcc/ada/a-rbtgbo.adb')
-rw-r--r-- | gcc-4.7/gcc/ada/a-rbtgbo.adb | 1130 |
1 files changed, 0 insertions, 1130 deletions
diff --git a/gcc-4.7/gcc/ada/a-rbtgbo.adb b/gcc-4.7/gcc/ada/a-rbtgbo.adb deleted file mode 100644 index d66571396..000000000 --- a/gcc-4.7/gcc/ada/a-rbtgbo.adb +++ /dev/null @@ -1,1130 +0,0 @@ ------------------------------------------------------------------------------- --- -- --- GNAT LIBRARY COMPONENTS -- --- -- --- ADA.CONTAINERS.RED_BLACK_TREES.GENERIC_BOUNDED_OPERATIONS -- --- -- --- B o d y -- --- -- --- Copyright (C) 2004-2011, Free Software Foundation, Inc. -- --- -- --- GNAT is free software; you can redistribute it and/or modify it under -- --- terms of the GNU General Public License as published by the Free Soft- -- --- ware Foundation; either version 3, or (at your option) any later ver- -- --- sion. GNAT is distributed in the hope that it will be useful, but WITH- -- --- OUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY -- --- or FITNESS FOR A PARTICULAR PURPOSE. -- --- -- --- As a special exception under Section 7 of GPL version 3, you are granted -- --- additional permissions described in the GCC Runtime Library Exception, -- --- version 3.1, as published by the Free Software Foundation. -- --- -- --- You should have received a copy of the GNU General Public License and -- --- a copy of the GCC Runtime Library Exception along with this program; -- --- see the files COPYING3 and COPYING.RUNTIME respectively. If not, see -- --- <http://www.gnu.org/licenses/>. -- --- -- --- This unit was originally developed by Matthew J Heaney. -- ------------------------------------------------------------------------------- - --- The references below to "CLR" refer to the following book, from which --- several of the algorithms here were adapted: --- Introduction to Algorithms --- by Thomas H. Cormen, Charles E. Leiserson, Ronald L. Rivest --- Publisher: The MIT Press (June 18, 1990) --- ISBN: 0262031418 - -with System; use type System.Address; - -package body Ada.Containers.Red_Black_Trees.Generic_Bounded_Operations is - - ----------------------- - -- Local Subprograms -- - ----------------------- - - procedure Delete_Fixup (Tree : in out Tree_Type'Class; Node : Count_Type); - procedure Delete_Swap (Tree : in out Tree_Type'Class; Z, Y : Count_Type); - - procedure Left_Rotate (Tree : in out Tree_Type'Class; X : Count_Type); - procedure Right_Rotate (Tree : in out Tree_Type'Class; Y : Count_Type); - - ---------------- - -- Clear_Tree -- - ---------------- - - procedure Clear_Tree (Tree : in out Tree_Type'Class) is - begin - if Tree.Busy > 0 then - raise Program_Error with - "attempt to tamper with cursors (container is busy)"; - end if; - - -- The lock status (which monitors "element tampering") always implies - -- that the busy status (which monitors "cursor tampering") is set too; - -- this is a representation invariant. Thus if the busy bit is not set, - -- then the lock bit must not be set either. - - pragma Assert (Tree.Lock = 0); - - Tree.First := 0; - Tree.Last := 0; - Tree.Root := 0; - Tree.Length := 0; - Tree.Free := -1; - end Clear_Tree; - - ------------------ - -- Delete_Fixup -- - ------------------ - - procedure Delete_Fixup - (Tree : in out Tree_Type'Class; - Node : Count_Type) - is - -- CLR p. 274 - - X : Count_Type; - W : Count_Type; - N : Nodes_Type renames Tree.Nodes; - - begin - X := Node; - while X /= Tree.Root - and then Color (N (X)) = Black - loop - if X = Left (N (Parent (N (X)))) then - W := Right (N (Parent (N (X)))); - - if Color (N (W)) = Red then - Set_Color (N (W), Black); - Set_Color (N (Parent (N (X))), Red); - Left_Rotate (Tree, Parent (N (X))); - W := Right (N (Parent (N (X)))); - end if; - - if (Left (N (W)) = 0 or else Color (N (Left (N (W)))) = Black) - and then - (Right (N (W)) = 0 or else Color (N (Right (N (W)))) = Black) - then - Set_Color (N (W), Red); - X := Parent (N (X)); - - else - if Right (N (W)) = 0 - or else Color (N (Right (N (W)))) = Black - then - -- As a condition for setting the color of the left child to - -- black, the left child access value must be non-null. A - -- truth table analysis shows that if we arrive here, that - -- condition holds, so there's no need for an explicit test. - -- The assertion is here to document what we know is true. - - pragma Assert (Left (N (W)) /= 0); - Set_Color (N (Left (N (W))), Black); - - Set_Color (N (W), Red); - Right_Rotate (Tree, W); - W := Right (N (Parent (N (X)))); - end if; - - Set_Color (N (W), Color (N (Parent (N (X))))); - Set_Color (N (Parent (N (X))), Black); - Set_Color (N (Right (N (W))), Black); - Left_Rotate (Tree, Parent (N (X))); - X := Tree.Root; - end if; - - else - pragma Assert (X = Right (N (Parent (N (X))))); - - W := Left (N (Parent (N (X)))); - - if Color (N (W)) = Red then - Set_Color (N (W), Black); - Set_Color (N (Parent (N (X))), Red); - Right_Rotate (Tree, Parent (N (X))); - W := Left (N (Parent (N (X)))); - end if; - - if (Left (N (W)) = 0 or else Color (N (Left (N (W)))) = Black) - and then - (Right (N (W)) = 0 or else Color (N (Right (N (W)))) = Black) - then - Set_Color (N (W), Red); - X := Parent (N (X)); - - else - if Left (N (W)) = 0 - or else Color (N (Left (N (W)))) = Black - then - -- As a condition for setting the color of the right child - -- to black, the right child access value must be non-null. - -- A truth table analysis shows that if we arrive here, that - -- condition holds, so there's no need for an explicit test. - -- The assertion is here to document what we know is true. - - pragma Assert (Right (N (W)) /= 0); - Set_Color (N (Right (N (W))), Black); - - Set_Color (N (W), Red); - Left_Rotate (Tree, W); - W := Left (N (Parent (N (X)))); - end if; - - Set_Color (N (W), Color (N (Parent (N (X))))); - Set_Color (N (Parent (N (X))), Black); - Set_Color (N (Left (N (W))), Black); - Right_Rotate (Tree, Parent (N (X))); - X := Tree.Root; - end if; - end if; - end loop; - - Set_Color (N (X), Black); - end Delete_Fixup; - - --------------------------- - -- Delete_Node_Sans_Free -- - --------------------------- - - procedure Delete_Node_Sans_Free - (Tree : in out Tree_Type'Class; - Node : Count_Type) - is - -- CLR p. 273 - - X, Y : Count_Type; - - Z : constant Count_Type := Node; - pragma Assert (Z /= 0); - - N : Nodes_Type renames Tree.Nodes; - - begin - if Tree.Busy > 0 then - raise Program_Error with - "attempt to tamper with cursors (container is busy)"; - end if; - - pragma Assert (Tree.Length > 0); - pragma Assert (Tree.Root /= 0); - pragma Assert (Tree.First /= 0); - pragma Assert (Tree.Last /= 0); - pragma Assert (Parent (N (Tree.Root)) = 0); - - pragma Assert ((Tree.Length > 1) - or else (Tree.First = Tree.Last - and then Tree.First = Tree.Root)); - - pragma Assert ((Left (N (Node)) = 0) - or else (Parent (N (Left (N (Node)))) = Node)); - - pragma Assert ((Right (N (Node)) = 0) - or else (Parent (N (Right (N (Node)))) = Node)); - - pragma Assert (((Parent (N (Node)) = 0) and then (Tree.Root = Node)) - or else ((Parent (N (Node)) /= 0) and then - ((Left (N (Parent (N (Node)))) = Node) - or else - (Right (N (Parent (N (Node)))) = Node)))); - - if Left (N (Z)) = 0 then - if Right (N (Z)) = 0 then - if Z = Tree.First then - Tree.First := Parent (N (Z)); - end if; - - if Z = Tree.Last then - Tree.Last := Parent (N (Z)); - end if; - - if Color (N (Z)) = Black then - Delete_Fixup (Tree, Z); - end if; - - pragma Assert (Left (N (Z)) = 0); - pragma Assert (Right (N (Z)) = 0); - - if Z = Tree.Root then - pragma Assert (Tree.Length = 1); - pragma Assert (Parent (N (Z)) = 0); - Tree.Root := 0; - elsif Z = Left (N (Parent (N (Z)))) then - Set_Left (N (Parent (N (Z))), 0); - else - pragma Assert (Z = Right (N (Parent (N (Z))))); - Set_Right (N (Parent (N (Z))), 0); - end if; - - else - pragma Assert (Z /= Tree.Last); - - X := Right (N (Z)); - - if Z = Tree.First then - Tree.First := Min (Tree, X); - end if; - - if Z = Tree.Root then - Tree.Root := X; - elsif Z = Left (N (Parent (N (Z)))) then - Set_Left (N (Parent (N (Z))), X); - else - pragma Assert (Z = Right (N (Parent (N (Z))))); - Set_Right (N (Parent (N (Z))), X); - end if; - - Set_Parent (N (X), Parent (N (Z))); - - if Color (N (Z)) = Black then - Delete_Fixup (Tree, X); - end if; - end if; - - elsif Right (N (Z)) = 0 then - pragma Assert (Z /= Tree.First); - - X := Left (N (Z)); - - if Z = Tree.Last then - Tree.Last := Max (Tree, X); - end if; - - if Z = Tree.Root then - Tree.Root := X; - elsif Z = Left (N (Parent (N (Z)))) then - Set_Left (N (Parent (N (Z))), X); - else - pragma Assert (Z = Right (N (Parent (N (Z))))); - Set_Right (N (Parent (N (Z))), X); - end if; - - Set_Parent (N (X), Parent (N (Z))); - - if Color (N (Z)) = Black then - Delete_Fixup (Tree, X); - end if; - - else - pragma Assert (Z /= Tree.First); - pragma Assert (Z /= Tree.Last); - - Y := Next (Tree, Z); - pragma Assert (Left (N (Y)) = 0); - - X := Right (N (Y)); - - if X = 0 then - if Y = Left (N (Parent (N (Y)))) then - pragma Assert (Parent (N (Y)) /= Z); - Delete_Swap (Tree, Z, Y); - Set_Left (N (Parent (N (Z))), Z); - - else - pragma Assert (Y = Right (N (Parent (N (Y))))); - pragma Assert (Parent (N (Y)) = Z); - Set_Parent (N (Y), Parent (N (Z))); - - if Z = Tree.Root then - Tree.Root := Y; - elsif Z = Left (N (Parent (N (Z)))) then - Set_Left (N (Parent (N (Z))), Y); - else - pragma Assert (Z = Right (N (Parent (N (Z))))); - Set_Right (N (Parent (N (Z))), Y); - end if; - - Set_Left (N (Y), Left (N (Z))); - Set_Parent (N (Left (N (Y))), Y); - Set_Right (N (Y), Z); - - Set_Parent (N (Z), Y); - Set_Left (N (Z), 0); - Set_Right (N (Z), 0); - - declare - Y_Color : constant Color_Type := Color (N (Y)); - begin - Set_Color (N (Y), Color (N (Z))); - Set_Color (N (Z), Y_Color); - end; - end if; - - if Color (N (Z)) = Black then - Delete_Fixup (Tree, Z); - end if; - - pragma Assert (Left (N (Z)) = 0); - pragma Assert (Right (N (Z)) = 0); - - if Z = Right (N (Parent (N (Z)))) then - Set_Right (N (Parent (N (Z))), 0); - else - pragma Assert (Z = Left (N (Parent (N (Z))))); - Set_Left (N (Parent (N (Z))), 0); - end if; - - else - if Y = Left (N (Parent (N (Y)))) then - pragma Assert (Parent (N (Y)) /= Z); - - Delete_Swap (Tree, Z, Y); - - Set_Left (N (Parent (N (Z))), X); - Set_Parent (N (X), Parent (N (Z))); - - else - pragma Assert (Y = Right (N (Parent (N (Y))))); - pragma Assert (Parent (N (Y)) = Z); - - Set_Parent (N (Y), Parent (N (Z))); - - if Z = Tree.Root then - Tree.Root := Y; - elsif Z = Left (N (Parent (N (Z)))) then - Set_Left (N (Parent (N (Z))), Y); - else - pragma Assert (Z = Right (N (Parent (N (Z))))); - Set_Right (N (Parent (N (Z))), Y); - end if; - - Set_Left (N (Y), Left (N (Z))); - Set_Parent (N (Left (N (Y))), Y); - - declare - Y_Color : constant Color_Type := Color (N (Y)); - begin - Set_Color (N (Y), Color (N (Z))); - Set_Color (N (Z), Y_Color); - end; - end if; - - if Color (N (Z)) = Black then - Delete_Fixup (Tree, X); - end if; - end if; - end if; - - Tree.Length := Tree.Length - 1; - end Delete_Node_Sans_Free; - - ----------------- - -- Delete_Swap -- - ----------------- - - procedure Delete_Swap - (Tree : in out Tree_Type'Class; - Z, Y : Count_Type) - is - N : Nodes_Type renames Tree.Nodes; - - pragma Assert (Z /= Y); - pragma Assert (Parent (N (Y)) /= Z); - - Y_Parent : constant Count_Type := Parent (N (Y)); - Y_Color : constant Color_Type := Color (N (Y)); - - begin - Set_Parent (N (Y), Parent (N (Z))); - Set_Left (N (Y), Left (N (Z))); - Set_Right (N (Y), Right (N (Z))); - Set_Color (N (Y), Color (N (Z))); - - if Tree.Root = Z then - Tree.Root := Y; - elsif Right (N (Parent (N (Y)))) = Z then - Set_Right (N (Parent (N (Y))), Y); - else - pragma Assert (Left (N (Parent (N (Y)))) = Z); - Set_Left (N (Parent (N (Y))), Y); - end if; - - if Right (N (Y)) /= 0 then - Set_Parent (N (Right (N (Y))), Y); - end if; - - if Left (N (Y)) /= 0 then - Set_Parent (N (Left (N (Y))), Y); - end if; - - Set_Parent (N (Z), Y_Parent); - Set_Color (N (Z), Y_Color); - Set_Left (N (Z), 0); - Set_Right (N (Z), 0); - end Delete_Swap; - - ---------- - -- Free -- - ---------- - - procedure Free (Tree : in out Tree_Type'Class; X : Count_Type) is - pragma Assert (X > 0); - pragma Assert (X <= Tree.Capacity); - - N : Nodes_Type renames Tree.Nodes; - -- pragma Assert (N (X).Prev >= 0); -- node is active - -- Find a way to mark a node as active vs. inactive; we could - -- use a special value in Color_Type for this. ??? - - begin - -- The set container actually contains two data structures: a list for - -- the "active" nodes that contain elements that have been inserted - -- onto the tree, and another for the "inactive" nodes of the free - -- store. - -- - -- We desire that merely declaring an object should have only minimal - -- cost; specially, we want to avoid having to initialize the free - -- store (to fill in the links), especially if the capacity is large. - -- - -- The head of the free list is indicated by Container.Free. If its - -- value is non-negative, then the free store has been initialized - -- in the "normal" way: Container.Free points to the head of the list - -- of free (inactive) nodes, and the value 0 means the free list is - -- empty. Each node on the free list has been initialized to point - -- to the next free node (via its Parent component), and the value 0 - -- means that this is the last free node. - -- - -- If Container.Free is negative, then the links on the free store - -- have not been initialized. In this case the link values are - -- implied: the free store comprises the components of the node array - -- started with the absolute value of Container.Free, and continuing - -- until the end of the array (Nodes'Last). - -- - -- ??? - -- It might be possible to perform an optimization here. Suppose that - -- the free store can be represented as having two parts: one - -- comprising the non-contiguous inactive nodes linked together - -- in the normal way, and the other comprising the contiguous - -- inactive nodes (that are not linked together, at the end of the - -- nodes array). This would allow us to never have to initialize - -- the free store, except in a lazy way as nodes become inactive. - - -- When an element is deleted from the list container, its node - -- becomes inactive, and so we set its Prev component to a negative - -- value, to indicate that it is now inactive. This provides a useful - -- way to detect a dangling cursor reference. - - -- The comment above is incorrect; we need some other way to - -- indicate a node is inactive, for example by using a special - -- Color_Type value. ??? - -- N (X).Prev := -1; -- Node is deallocated (not on active list) - - if Tree.Free >= 0 then - -- The free store has previously been initialized. All we need to - -- do here is link the newly-free'd node onto the free list. - - Set_Parent (N (X), Tree.Free); - Tree.Free := X; - - elsif X + 1 = abs Tree.Free then - -- The free store has not been initialized, and the node becoming - -- inactive immediately precedes the start of the free store. All - -- we need to do is move the start of the free store back by one. - - Tree.Free := Tree.Free + 1; - - else - -- The free store has not been initialized, and the node becoming - -- inactive does not immediately precede the free store. Here we - -- first initialize the free store (meaning the links are given - -- values in the traditional way), and then link the newly-free'd - -- node onto the head of the free store. - - -- ??? - -- See the comments above for an optimization opportunity. If the - -- next link for a node on the free store is negative, then this - -- means the remaining nodes on the free store are physically - -- contiguous, starting as the absolute value of that index value. - - Tree.Free := abs Tree.Free; - - if Tree.Free > Tree.Capacity then - Tree.Free := 0; - - else - for I in Tree.Free .. Tree.Capacity - 1 loop - Set_Parent (N (I), I + 1); - end loop; - - Set_Parent (N (Tree.Capacity), 0); - end if; - - Set_Parent (N (X), Tree.Free); - Tree.Free := X; - end if; - end Free; - - ----------------------- - -- Generic_Allocate -- - ----------------------- - - procedure Generic_Allocate - (Tree : in out Tree_Type'Class; - Node : out Count_Type) - is - N : Nodes_Type renames Tree.Nodes; - - begin - if Tree.Free >= 0 then - Node := Tree.Free; - - -- We always perform the assignment first, before we - -- change container state, in order to defend against - -- exceptions duration assignment. - - Set_Element (N (Node)); - Tree.Free := Parent (N (Node)); - - else - -- A negative free store value means that the links of the nodes - -- in the free store have not been initialized. In this case, the - -- nodes are physically contiguous in the array, starting at the - -- index that is the absolute value of the Container.Free, and - -- continuing until the end of the array (Nodes'Last). - - Node := abs Tree.Free; - - -- As above, we perform this assignment first, before modifying - -- any container state. - - Set_Element (N (Node)); - Tree.Free := Tree.Free - 1; - end if; - - -- When a node is allocated from the free store, its pointer components - -- (the links to other nodes in the tree) must also be initialized (to - -- 0, the equivalent of null). This simplifies the post-allocation - -- handling of nodes inserted into terminal positions. - - Set_Parent (N (Node), Parent => 0); - Set_Left (N (Node), Left => 0); - Set_Right (N (Node), Right => 0); - end Generic_Allocate; - - ------------------- - -- Generic_Equal -- - ------------------- - - function Generic_Equal (Left, Right : Tree_Type'Class) return Boolean is - L_Node : Count_Type; - R_Node : Count_Type; - - begin - if Left'Address = Right'Address then - return True; - end if; - - if Left.Length /= Right.Length then - return False; - end if; - - L_Node := Left.First; - R_Node := Right.First; - while L_Node /= 0 loop - if not Is_Equal (Left.Nodes (L_Node), Right.Nodes (R_Node)) then - return False; - end if; - - L_Node := Next (Left, L_Node); - R_Node := Next (Right, R_Node); - end loop; - - return True; - end Generic_Equal; - - ----------------------- - -- Generic_Iteration -- - ----------------------- - - procedure Generic_Iteration (Tree : Tree_Type'Class) is - procedure Iterate (P : Count_Type); - - ------------- - -- Iterate -- - ------------- - - procedure Iterate (P : Count_Type) is - X : Count_Type := P; - begin - while X /= 0 loop - Iterate (Left (Tree.Nodes (X))); - Process (X); - X := Right (Tree.Nodes (X)); - end loop; - end Iterate; - - -- Start of processing for Generic_Iteration - - begin - Iterate (Tree.Root); - end Generic_Iteration; - - ------------------ - -- Generic_Read -- - ------------------ - - procedure Generic_Read - (Stream : not null access Root_Stream_Type'Class; - Tree : in out Tree_Type'Class) - is - Len : Count_Type'Base; - - Node, Last_Node : Count_Type; - - N : Nodes_Type renames Tree.Nodes; - - begin - Clear_Tree (Tree); - Count_Type'Base'Read (Stream, Len); - - if Len < 0 then - raise Program_Error with "bad container length (corrupt stream)"; - end if; - - if Len = 0 then - return; - end if; - - if Len > Tree.Capacity then - raise Constraint_Error with "length exceeds capacity"; - end if; - - -- Use Unconditional_Insert_With_Hint here instead ??? - - Allocate (Tree, Node); - pragma Assert (Node /= 0); - - Set_Color (N (Node), Black); - - Tree.Root := Node; - Tree.First := Node; - Tree.Last := Node; - Tree.Length := 1; - - for J in Count_Type range 2 .. Len loop - Last_Node := Node; - pragma Assert (Last_Node = Tree.Last); - - Allocate (Tree, Node); - pragma Assert (Node /= 0); - - Set_Color (N (Node), Red); - Set_Right (N (Last_Node), Right => Node); - Tree.Last := Node; - Set_Parent (N (Node), Parent => Last_Node); - - Rebalance_For_Insert (Tree, Node); - Tree.Length := Tree.Length + 1; - end loop; - end Generic_Read; - - ------------------------------- - -- Generic_Reverse_Iteration -- - ------------------------------- - - procedure Generic_Reverse_Iteration (Tree : Tree_Type'Class) is - procedure Iterate (P : Count_Type); - - ------------- - -- Iterate -- - ------------- - - procedure Iterate (P : Count_Type) is - X : Count_Type := P; - begin - while X /= 0 loop - Iterate (Right (Tree.Nodes (X))); - Process (X); - X := Left (Tree.Nodes (X)); - end loop; - end Iterate; - - -- Start of processing for Generic_Reverse_Iteration - - begin - Iterate (Tree.Root); - end Generic_Reverse_Iteration; - - ------------------- - -- Generic_Write -- - ------------------- - - procedure Generic_Write - (Stream : not null access Root_Stream_Type'Class; - Tree : Tree_Type'Class) - is - procedure Process (Node : Count_Type); - pragma Inline (Process); - - procedure Iterate is new Generic_Iteration (Process); - - ------------- - -- Process -- - ------------- - - procedure Process (Node : Count_Type) is - begin - Write_Node (Stream, Tree.Nodes (Node)); - end Process; - - -- Start of processing for Generic_Write - - begin - Count_Type'Base'Write (Stream, Tree.Length); - Iterate (Tree); - end Generic_Write; - - ----------------- - -- Left_Rotate -- - ----------------- - - procedure Left_Rotate (Tree : in out Tree_Type'Class; X : Count_Type) is - -- CLR p. 266 - - N : Nodes_Type renames Tree.Nodes; - - Y : constant Count_Type := Right (N (X)); - pragma Assert (Y /= 0); - - begin - Set_Right (N (X), Left (N (Y))); - - if Left (N (Y)) /= 0 then - Set_Parent (N (Left (N (Y))), X); - end if; - - Set_Parent (N (Y), Parent (N (X))); - - if X = Tree.Root then - Tree.Root := Y; - elsif X = Left (N (Parent (N (X)))) then - Set_Left (N (Parent (N (X))), Y); - else - pragma Assert (X = Right (N (Parent (N (X))))); - Set_Right (N (Parent (N (X))), Y); - end if; - - Set_Left (N (Y), X); - Set_Parent (N (X), Y); - end Left_Rotate; - - --------- - -- Max -- - --------- - - function Max - (Tree : Tree_Type'Class; - Node : Count_Type) return Count_Type - is - -- CLR p. 248 - - X : Count_Type := Node; - Y : Count_Type; - - begin - loop - Y := Right (Tree.Nodes (X)); - - if Y = 0 then - return X; - end if; - - X := Y; - end loop; - end Max; - - --------- - -- Min -- - --------- - - function Min - (Tree : Tree_Type'Class; - Node : Count_Type) return Count_Type - is - -- CLR p. 248 - - X : Count_Type := Node; - Y : Count_Type; - - begin - loop - Y := Left (Tree.Nodes (X)); - - if Y = 0 then - return X; - end if; - - X := Y; - end loop; - end Min; - - ---------- - -- Next -- - ---------- - - function Next - (Tree : Tree_Type'Class; - Node : Count_Type) return Count_Type - is - begin - -- CLR p. 249 - - if Node = 0 then - return 0; - end if; - - if Right (Tree.Nodes (Node)) /= 0 then - return Min (Tree, Right (Tree.Nodes (Node))); - end if; - - declare - X : Count_Type := Node; - Y : Count_Type := Parent (Tree.Nodes (Node)); - - begin - while Y /= 0 - and then X = Right (Tree.Nodes (Y)) - loop - X := Y; - Y := Parent (Tree.Nodes (Y)); - end loop; - - return Y; - end; - end Next; - - -------------- - -- Previous -- - -------------- - - function Previous - (Tree : Tree_Type'Class; - Node : Count_Type) return Count_Type - is - begin - if Node = 0 then - return 0; - end if; - - if Left (Tree.Nodes (Node)) /= 0 then - return Max (Tree, Left (Tree.Nodes (Node))); - end if; - - declare - X : Count_Type := Node; - Y : Count_Type := Parent (Tree.Nodes (Node)); - - begin - while Y /= 0 - and then X = Left (Tree.Nodes (Y)) - loop - X := Y; - Y := Parent (Tree.Nodes (Y)); - end loop; - - return Y; - end; - end Previous; - - -------------------------- - -- Rebalance_For_Insert -- - -------------------------- - - procedure Rebalance_For_Insert - (Tree : in out Tree_Type'Class; - Node : Count_Type) - is - -- CLR p. 268 - - N : Nodes_Type renames Tree.Nodes; - - X : Count_Type := Node; - pragma Assert (X /= 0); - pragma Assert (Color (N (X)) = Red); - - Y : Count_Type; - - begin - while X /= Tree.Root and then Color (N (Parent (N (X)))) = Red loop - if Parent (N (X)) = Left (N (Parent (N (Parent (N (X)))))) then - Y := Right (N (Parent (N (Parent (N (X)))))); - - if Y /= 0 and then Color (N (Y)) = Red then - Set_Color (N (Parent (N (X))), Black); - Set_Color (N (Y), Black); - Set_Color (N (Parent (N (Parent (N (X))))), Red); - X := Parent (N (Parent (N (X)))); - - else - if X = Right (N (Parent (N (X)))) then - X := Parent (N (X)); - Left_Rotate (Tree, X); - end if; - - Set_Color (N (Parent (N (X))), Black); - Set_Color (N (Parent (N (Parent (N (X))))), Red); - Right_Rotate (Tree, Parent (N (Parent (N (X))))); - end if; - - else - pragma Assert (Parent (N (X)) = - Right (N (Parent (N (Parent (N (X))))))); - - Y := Left (N (Parent (N (Parent (N (X)))))); - - if Y /= 0 and then Color (N (Y)) = Red then - Set_Color (N (Parent (N (X))), Black); - Set_Color (N (Y), Black); - Set_Color (N (Parent (N (Parent (N (X))))), Red); - X := Parent (N (Parent (N (X)))); - - else - if X = Left (N (Parent (N (X)))) then - X := Parent (N (X)); - Right_Rotate (Tree, X); - end if; - - Set_Color (N (Parent (N (X))), Black); - Set_Color (N (Parent (N (Parent (N (X))))), Red); - Left_Rotate (Tree, Parent (N (Parent (N (X))))); - end if; - end if; - end loop; - - Set_Color (N (Tree.Root), Black); - end Rebalance_For_Insert; - - ------------------ - -- Right_Rotate -- - ------------------ - - procedure Right_Rotate (Tree : in out Tree_Type'Class; Y : Count_Type) is - N : Nodes_Type renames Tree.Nodes; - - X : constant Count_Type := Left (N (Y)); - pragma Assert (X /= 0); - - begin - Set_Left (N (Y), Right (N (X))); - - if Right (N (X)) /= 0 then - Set_Parent (N (Right (N (X))), Y); - end if; - - Set_Parent (N (X), Parent (N (Y))); - - if Y = Tree.Root then - Tree.Root := X; - elsif Y = Left (N (Parent (N (Y)))) then - Set_Left (N (Parent (N (Y))), X); - else - pragma Assert (Y = Right (N (Parent (N (Y))))); - Set_Right (N (Parent (N (Y))), X); - end if; - - Set_Right (N (X), Y); - Set_Parent (N (Y), X); - end Right_Rotate; - - --------- - -- Vet -- - --------- - - function Vet (Tree : Tree_Type'Class; Index : Count_Type) return Boolean is - Nodes : Nodes_Type renames Tree.Nodes; - Node : Node_Type renames Nodes (Index); - - begin - if Parent (Node) = Index - or else Left (Node) = Index - or else Right (Node) = Index - then - return False; - end if; - - if Tree.Length = 0 - or else Tree.Root = 0 - or else Tree.First = 0 - or else Tree.Last = 0 - then - return False; - end if; - - if Parent (Nodes (Tree.Root)) /= 0 then - return False; - end if; - - if Left (Nodes (Tree.First)) /= 0 then - return False; - end if; - - if Right (Nodes (Tree.Last)) /= 0 then - return False; - end if; - - if Tree.Length = 1 then - if Tree.First /= Tree.Last - or else Tree.First /= Tree.Root - then - return False; - end if; - - if Index /= Tree.First then - return False; - end if; - - if Parent (Node) /= 0 - or else Left (Node) /= 0 - or else Right (Node) /= 0 - then - return False; - end if; - - return True; - end if; - - if Tree.First = Tree.Last then - return False; - end if; - - if Tree.Length = 2 then - if Tree.First /= Tree.Root - and then Tree.Last /= Tree.Root - then - return False; - end if; - - if Tree.First /= Index - and then Tree.Last /= Index - then - return False; - end if; - end if; - - if Left (Node) /= 0 - and then Parent (Nodes (Left (Node))) /= Index - then - return False; - end if; - - if Right (Node) /= 0 - and then Parent (Nodes (Right (Node))) /= Index - then - return False; - end if; - - if Parent (Node) = 0 then - if Tree.Root /= Index then - return False; - end if; - - elsif Left (Nodes (Parent (Node))) /= Index - and then Right (Nodes (Parent (Node))) /= Index - then - return False; - end if; - - return True; - end Vet; - -end Ada.Containers.Red_Black_Trees.Generic_Bounded_Operations; |