diff options
author | charlet <charlet@138bc75d-0d04-0410-961f-82ee72b054a4> | 2005-06-16 08:56:24 +0000 |
---|---|---|
committer | charlet <charlet@138bc75d-0d04-0410-961f-82ee72b054a4> | 2005-06-16 08:56:24 +0000 |
commit | ca64eb07de27f9c20b0b5b909f314afaae888e81 (patch) | |
tree | 60bbc3a40631ce4a825ff74330cd04720cf0d624 /gcc/ada/a-cdlili.adb | |
parent | d25effa88fc45b26bb1ac6135a42785ddb699037 (diff) | |
download | gcc-ca64eb07de27f9c20b0b5b909f314afaae888e81.tar.gz |
2005-06-14 Matthew Heaney <heaney@adacore.com>
* a-swunha.ads, a-swunha.adb: Removed. Replaced by a-swuwha.ad[sb]
* a-swuwha.ads, a-swuwha.adb: New files
* a-szunha.ads, a-szunha.adb: Removed, replaced by a-szuzha.ad[sb]
* a-szuzha.ads, a-szuzha.adb: New files.
* a-rbtgso.adb, a-crbtgo.ads, a-crbtgo.adb, a-crbtgk.ads,
a-crbtgk.adb, a-crbltr.ads, a-coorse.ads, a-coorse.adb, a-convec.ads,
a-convec.adb, a-coinve.ads, a-coinve.adb, a-cohata.ads, a-cohama.ads,
a-cohama.adb, a-ciorse.ads, a-ciorse.adb, a-cihama.ads, a-cihama.adb,
a-cidlli.ads, a-cidlli.adb, a-chtgop.ads, a-chtgop.adb, a-cdlili.ads,
a-cdlili.adb, a-coormu.adb, a-ciormu.adb, a-cihase.adb, a-cohase.adb,
a-cohase.ads, a-ciorma.ads, a-coorma.ads, a-ciormu.ads, a-coormu.ads,
a-swunha.adb, a-stunha.adb, a-ciorma.adb, a-coorma.adb, a-shcain.ads,
a-shcain.adb, a-chtgke.ads, a-chtgke.adb, a-stwiha.ads, a-stwiha.adb,
a-strhas.adb, a-stzhas.adb: synchronized to the latest version of the
Ada 2005 RM.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@101069 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/ada/a-cdlili.adb')
-rw-r--r-- | gcc/ada/a-cdlili.adb | 1151 |
1 files changed, 872 insertions, 279 deletions
diff --git a/gcc/ada/a-cdlili.adb b/gcc/ada/a-cdlili.adb index 435679d313d..a9801e22c3c 100644 --- a/gcc/ada/a-cdlili.adb +++ b/gcc/ada/a-cdlili.adb @@ -2,11 +2,11 @@ -- -- -- GNAT LIBRARY COMPONENTS -- -- -- --- ADA.CONTAINERS.DOUBLY_LINKED_LISTS -- +-- A D A . C O N T A I N E R S . D O U B L Y _ L I N K E D _ L I S T S -- -- -- -- B o d y -- -- -- --- Copyright (C) 2004 Free Software Foundation, Inc. -- +-- Copyright (C) 2004-2005 Free Software Foundation, Inc. -- -- -- -- This specification is derived from the Ada Reference Manual for use with -- -- GNAT. The copyright notice above, and the license provisions that follow -- @@ -45,10 +45,6 @@ package body Ada.Containers.Doubly_Linked_Lists is -- Local Subprograms -- ----------------------- - procedure Delete_Node - (Container : in out List; - Node : in out Node_Access); - procedure Insert_Internal (Container : in out List; Before : Node_Access; @@ -88,38 +84,42 @@ package body Ada.Containers.Doubly_Linked_Lists is ------------ procedure Adjust (Container : in out List) is - Src : Node_Access := Container.First; - Length : constant Count_Type := Container.Length; + Src : Node_Access := Container.First; begin if Src = null then pragma Assert (Container.Last = null); - pragma Assert (Length = 0); + pragma Assert (Container.Length = 0); + pragma Assert (Container.Busy = 0); + pragma Assert (Container.Lock = 0); return; end if; pragma Assert (Container.First.Prev = null); pragma Assert (Container.Last.Next = null); - pragma Assert (Length > 0); + pragma Assert (Container.Length > 0); Container.First := null; Container.Last := null; Container.Length := 0; + Container.Busy := 0; + Container.Lock := 0; Container.First := new Node_Type'(Src.Element, null, null); - Container.Last := Container.First; - loop - Container.Length := Container.Length + 1; - Src := Src.Next; - exit when Src = null; + Container.Length := 1; + + Src := Src.Next; + + while Src /= null loop Container.Last.Next := new Node_Type'(Element => Src.Element, Prev => Container.Last, Next => null); Container.Last := Container.Last.Next; - end loop; + Container.Length := Container.Length + 1; - pragma Assert (Container.Length = Length); + Src := Src.Next; + end loop; end Adjust; ------------ @@ -129,8 +129,7 @@ package body Ada.Containers.Doubly_Linked_Lists is procedure Append (Container : in out List; New_Item : Element_Type; - Count : Count_Type := 1) - is + Count : Count_Type := 1) is begin Insert (Container, No_Element, New_Item, Count); end Append; @@ -140,8 +139,45 @@ package body Ada.Containers.Doubly_Linked_Lists is ----------- procedure Clear (Container : in out List) is + X : Node_Access; + begin - Delete_Last (Container, Count => Container.Length); + if Container.Length = 0 then + pragma Assert (Container.First = null); + pragma Assert (Container.Last = null); + pragma Assert (Container.Busy = 0); + pragma Assert (Container.Lock = 0); + return; + end if; + + pragma Assert (Container.First.Prev = null); + pragma Assert (Container.Last.Next = null); + + if Container.Busy > 0 then + raise Program_Error; + end if; + + while Container.Length > 1 loop + X := Container.First; + pragma Assert (X.Next.Prev = Container.First); + + Container.First := X.Next; + X.Next := null; -- prevent mischief + + Container.First.Prev := null; + Container.Length := Container.Length - 1; + + Free (X); + end loop; + + X := Container.First; + pragma Assert (X = Container.Last); + + Container.First := null; + Container.Last := null; + Container.Length := 0; + + Free (X); end Clear; -------------- @@ -150,8 +186,7 @@ package body Ada.Containers.Doubly_Linked_Lists is function Contains (Container : List; - Item : Element_Type) return Boolean - is + Item : Element_Type) return Boolean is begin return Find (Container, Item) /= No_Element; end Contains; @@ -165,22 +200,68 @@ package body Ada.Containers.Doubly_Linked_Lists is Position : in out Cursor; Count : Count_Type := 1) is + X : Node_Access; + begin - if Position = No_Element then - return; + if Position.Node = null then + pragma Assert (Position.Container = null); + raise Constraint_Error; end if; if Position.Container /= List_Access'(Container'Unchecked_Access) then raise Program_Error; end if; + pragma Assert (Container.Length > 0); + pragma Assert (Container.First.Prev = null); + pragma Assert (Container.Last.Next = null); + + pragma Assert (Position.Node.Prev = null + or else Position.Node.Prev.Next = Position.Node); + pragma Assert (Position.Node.Next = null + or else Position.Node.Next.Prev = Position.Node); + pragma Assert (Position.Node.Prev /= null + or else Position.Node = Container.First); + pragma Assert (Position.Node.Next /= null + or else Position.Node = Container.Last); + + if Position.Node = Container.First then + Delete_First (Container, Count); + Position := First (Container); + return; + end if; + + if Count = 0 then + return; + end if; + + if Container.Busy > 0 then + raise Program_Error; + end if; + for Index in 1 .. Count loop - Delete_Node (Container, Position.Node); + X := Position.Node; + Container.Length := Container.Length - 1; - if Position.Node = null then - Position.Container := null; + if X = Container.Last then + Position := No_Element; + + Container.Last := X.Prev; + Container.Last.Next := null; + + X.Prev := null; -- prevent mischief + Free (X); return; end if; + + Position.Node := X.Next; + + X.Next.Prev := X.Prev; + X.Prev.Next := X.Next; + + X.Next := null; + X.Prev := null; + Free (X); end loop; end Delete; @@ -192,10 +273,33 @@ package body Ada.Containers.Doubly_Linked_Lists is (Container : in out List; Count : Count_Type := 1) is - Node : Node_Access := Container.First; + X : Node_Access; + begin - for J in 1 .. Count_Type'Min (Count, Container.Length) loop - Delete_Node (Container, Node); + if Count >= Container.Length then + Clear (Container); + return; + end if; + + if Count = 0 then + return; + end if; + + if Container.Busy > 0 then + raise Program_Error; + end if; + + for I in 1 .. Count loop + X := Container.First; + pragma Assert (X.Next.Prev = Container.First); + + Container.First := X.Next; + Container.First.Prev := null; + + Container.Length := Container.Length - 1; + + X.Next := null; -- prevent mischief + Free (X); end loop; end Delete_First; @@ -207,55 +311,35 @@ package body Ada.Containers.Doubly_Linked_Lists is (Container : in out List; Count : Count_Type := 1) is - Node : Node_Access; - begin - for J in 1 .. Count_Type'Min (Count, Container.Length) loop - Node := Container.Last; - Delete_Node (Container, Node); - end loop; - end Delete_Last; - - ----------------- - -- Delete_Node -- - ----------------- - - procedure Delete_Node - (Container : in out List; - Node : in out Node_Access) - is - X : Node_Access := Node; + X : Node_Access; begin - Node := X.Next; - Container.Length := Container.Length - 1; + if Count >= Container.Length then + Clear (Container); + return; + end if; - if X = Container.First then - Container.First := X.Next; + if Count = 0 then + return; + end if; - if X = Container.Last then - pragma Assert (Container.First = null); - pragma Assert (Container.Length = 0); - Container.Last := null; - else - pragma Assert (Container.Length > 0); - Container.First.Prev := null; - end if; + if Container.Busy > 0 then + raise Program_Error; + end if; - elsif X = Container.Last then - pragma Assert (Container.Length > 0); + for I in 1 .. Count loop + X := Container.Last; + pragma Assert (X.Prev.Next = Container.Last); Container.Last := X.Prev; Container.Last.Next := null; - else - pragma Assert (Container.Length > 0); + Container.Length := Container.Length - 1; - X.Next.Prev := X.Prev; - X.Prev.Next := X.Next; - end if; - - Free (X); - end Delete_Node; + X.Prev := null; -- prevent mischief + Free (X); + end loop; + end Delete_Last; ------------- -- Element -- @@ -263,6 +347,21 @@ package body Ada.Containers.Doubly_Linked_Lists is function Element (Position : Cursor) return Element_Type is begin + pragma Assert (Position.Container /= null); + pragma Assert (Position.Container.Length > 0); + pragma Assert (Position.Container.First.Prev = null); + pragma Assert (Position.Container.Last.Next = null); + + pragma Assert (Position.Node /= null); + pragma Assert (Position.Node.Prev = null + or else Position.Node.Prev.Next = Position.Node); + pragma Assert (Position.Node.Next = null + or else Position.Node.Next.Prev = Position.Node); + pragma Assert (Position.Node.Prev /= null + or else Position.Node = Position.Container.First); + pragma Assert (Position.Node.Next /= null + or else Position.Node = Position.Container.Last); + return Position.Node.Element; end Element; @@ -280,8 +379,23 @@ package body Ada.Containers.Doubly_Linked_Lists is begin if Node = null then Node := Container.First; - elsif Position.Container /= List_Access'(Container'Unchecked_Access) then - raise Program_Error; + else + if Position.Container /= List_Access'(Container'Unchecked_Access) then + raise Program_Error; + end if; + + pragma Assert (Container.Length > 0); + pragma Assert (Container.First.Prev = null); + pragma Assert (Container.Last.Next = null); + + pragma Assert (Position.Node.Prev = null + or else Position.Node.Prev.Next = Position.Node); + pragma Assert (Position.Node.Next = null + or else Position.Node.Next.Prev = Position.Node); + pragma Assert (Position.Node.Prev /= null + or else Position.Node = Container.First); + pragma Assert (Position.Node.Next /= null + or else Position.Node = Container.Last); end if; while Node /= null loop @@ -317,131 +431,173 @@ package body Ada.Containers.Doubly_Linked_Lists is return Container.First.Element; end First_Element; - ------------------- - -- Generic_Merge -- - ------------------- + --------------------- + -- Generic_Sorting -- + --------------------- - procedure Generic_Merge - (Target : in out List; - Source : in out List) - is - LI : Cursor := First (Target); - RI : Cursor := First (Source); + package body Generic_Sorting is - begin - if Target'Address = Source'Address then - return; - end if; + --------------- + -- Is_Sorted -- + --------------- - while RI.Node /= null loop - if LI.Node = null then - Splice (Target, No_Element, Source); + function Is_Sorted (Container : List) return Boolean is + Node : Node_Access := Container.First; + + begin + for I in 2 .. Container.Length loop + if Node.Next.Element < Node.Element then + return False; + end if; + + Node := Node.Next; + end loop; + + return True; + end Is_Sorted; + + ----------- + -- Merge -- + ----------- + + procedure Merge + (Target : in out List; + Source : in out List) + is + LI : Cursor := First (Target); + RI : Cursor := First (Source); + + begin + if Target'Address = Source'Address then return; end if; - if RI.Node.Element < LI.Node.Element then - declare - RJ : constant Cursor := RI; - begin - RI.Node := RI.Node.Next; - Splice (Target, LI, Source, RJ); - end; - - else - LI.Node := LI.Node.Next; + if Target.Busy > 0 + or else Source.Busy > 0 + then + raise Program_Error; end if; - end loop; - end Generic_Merge; - ------------------ - -- Generic_Sort -- - ------------------ + while RI.Node /= null loop + if LI.Node = null then + Splice (Target, No_Element, Source); + return; + end if; + + if RI.Node.Element < LI.Node.Element then + declare + RJ : Cursor := RI; + begin + RI.Node := RI.Node.Next; + Splice (Target, LI, Source, RJ); + end; + + else + LI.Node := LI.Node.Next; + end if; + end loop; + end Merge; - procedure Generic_Sort (Container : in out List) is + ---------- + -- Sort -- + ---------- - procedure Partition - (Pivot : in Node_Access; - Back : in Node_Access); + procedure Sort (Container : in out List) is - procedure Sort (Front, Back : Node_Access); + procedure Partition + (Pivot : in Node_Access; + Back : in Node_Access); - --------------- - -- Partition -- - --------------- + procedure Sort (Front, Back : Node_Access); - procedure Partition - (Pivot : Node_Access; - Back : Node_Access) - is - Node : Node_Access := Pivot.Next; + --------------- + -- Partition -- + --------------- - begin - while Node /= Back loop - if Node.Element < Pivot.Element then - declare - Prev : constant Node_Access := Node.Prev; - Next : constant Node_Access := Node.Next; + procedure Partition + (Pivot : Node_Access; + Back : Node_Access) + is + Node : Node_Access := Pivot.Next; - begin - Prev.Next := Next; + begin + while Node /= Back loop + if Node.Element < Pivot.Element then + declare + Prev : constant Node_Access := Node.Prev; + Next : constant Node_Access := Node.Next; - if Next = null then - Container.Last := Prev; - else - Next.Prev := Prev; - end if; + begin + Prev.Next := Next; - Node.Next := Pivot; - Node.Prev := Pivot.Prev; + if Next = null then + Container.Last := Prev; + else + Next.Prev := Prev; + end if; - Pivot.Prev := Node; + Node.Next := Pivot; + Node.Prev := Pivot.Prev; - if Node.Prev = null then - Container.First := Node; - else - Node.Prev.Next := Node; - end if; + Pivot.Prev := Node; - Node := Next; - end; + if Node.Prev = null then + Container.First := Node; + else + Node.Prev.Next := Node; + end if; + + Node := Next; + end; + else + Node := Node.Next; + end if; + end loop; + end Partition; + + ---------- + -- Sort -- + ---------- + + procedure Sort (Front, Back : Node_Access) is + Pivot : Node_Access; + + begin + if Front = null then + Pivot := Container.First; else - Node := Node.Next; + Pivot := Front.Next; end if; - end loop; - end Partition; - ---------- - -- Sort -- - ---------- + if Pivot /= Back then + Partition (Pivot, Back); + Sort (Front, Pivot); + Sort (Pivot, Back); + end if; + end Sort; - procedure Sort (Front, Back : Node_Access) is - Pivot : Node_Access; + -- Start of processing for Sort begin - if Front = null then - Pivot := Container.First; - else - Pivot := Front.Next; + if Container.Length <= 1 then + return; end if; - if Pivot /= Back then - Partition (Pivot, Back); - Sort (Front, Pivot); - Sort (Pivot, Back); + pragma Assert (Container.First.Prev = null); + pragma Assert (Container.Last.Next = null); + + if Container.Busy > 0 then + raise Program_Error; end if; - end Sort; - -- Start of processing for Generic_Sort + Sort (Front => null, Back => null); - begin - Sort (Front => null, Back => null); + pragma Assert (Container.First.Prev = null); + pragma Assert (Container.Last.Next = null); + end Sort; - pragma Assert (Container.Length = 0 - or else - (Container.First.Prev = null - and then Container.Last.Next = null)); - end Generic_Sort; + end Generic_Sorting; ----------------- -- Has_Element -- @@ -449,7 +605,26 @@ package body Ada.Containers.Doubly_Linked_Lists is function Has_Element (Position : Cursor) return Boolean is begin - return Position.Container /= null and then Position.Node /= null; + if Position.Node = null then + pragma Assert (Position.Container = null); + return False; + end if; + + pragma Assert (Position.Container /= null); + pragma Assert (Position.Container.Length > 0); + pragma Assert (Position.Container.First.Prev = null); + pragma Assert (Position.Container.Last.Next = null); + + pragma Assert (Position.Node.Prev = null + or else Position.Node.Prev.Next = Position.Node); + pragma Assert (Position.Node.Next = null + or else Position.Node.Next.Prev = Position.Node); + pragma Assert (Position.Node.Prev /= null + or else Position.Node = Position.Container.First); + pragma Assert (Position.Node.Next /= null + or else Position.Node = Position.Container.Last); + + return True; end Has_Element; ------------ @@ -466,10 +641,23 @@ package body Ada.Containers.Doubly_Linked_Lists is New_Node : Node_Access; begin - if Before.Container /= null - and then Before.Container /= List_Access'(Container'Unchecked_Access) - then - raise Program_Error; + if Before.Node /= null then + if Before.Container /= List_Access'(Container'Unchecked_Access) then + raise Program_Error; + end if; + + pragma Assert (Container.Length > 0); + pragma Assert (Container.First.Prev = null); + pragma Assert (Container.Last.Next = null); + + pragma Assert (Before.Node.Prev = null + or else Before.Node.Prev.Next = Before.Node); + pragma Assert (Before.Node.Next = null + or else Before.Node.Next.Prev = Before.Node); + pragma Assert (Before.Node.Prev /= null + or else Before.Node = Container.First); + pragma Assert (Before.Node.Next /= null + or else Before.Node = Container.Last); end if; if Count = 0 then @@ -477,10 +665,18 @@ package body Ada.Containers.Doubly_Linked_Lists is return; end if; + if Container.Length > Count_Type'Last - Count then + raise Constraint_Error; + end if; + + if Container.Busy > 0 then + raise Program_Error; + end if; + New_Node := new Node_Type'(New_Item, null, null); Insert_Internal (Container, Before.Node, New_Node); - Position := Cursor'(Before.Container, New_Node); + Position := Cursor'(Container'Unchecked_Access, New_Node); for J in Count_Type'(2) .. Count loop New_Node := new Node_Type'(New_Item, null, null); @@ -508,10 +704,23 @@ package body Ada.Containers.Doubly_Linked_Lists is New_Node : Node_Access; begin - if Before.Container /= null - and then Before.Container /= List_Access'(Container'Unchecked_Access) - then - raise Program_Error; + if Before.Node /= null then + if Before.Container /= List_Access'(Container'Unchecked_Access) then + raise Program_Error; + end if; + + pragma Assert (Container.Length > 0); + pragma Assert (Container.First.Prev = null); + pragma Assert (Container.Last.Next = null); + + pragma Assert (Before.Node.Prev = null + or else Before.Node.Prev.Next = Before.Node); + pragma Assert (Before.Node.Next = null + or else Before.Node.Next.Prev = Before.Node); + pragma Assert (Before.Node.Prev /= null + or else Before.Node = Container.First); + pragma Assert (Before.Node.Next /= null + or else Before.Node = Container.Last); end if; if Count = 0 then @@ -519,10 +728,18 @@ package body Ada.Containers.Doubly_Linked_Lists is return; end if; + if Container.Length > Count_Type'Last - Count then + raise Constraint_Error; + end if; + + if Container.Busy > 0 then + raise Program_Error; + end if; + New_Node := new Node_Type; Insert_Internal (Container, Before.Node, New_Node); - Position := Cursor'(Before.Container, New_Node); + Position := Cursor'(Container'Unchecked_Access, New_Node); for J in Count_Type'(2) .. Count loop New_Node := new Node_Type; @@ -595,12 +812,26 @@ package body Ada.Containers.Doubly_Linked_Lists is (Container : List; Process : not null access procedure (Position : Cursor)) is + C : List renames Container'Unrestricted_Access.all; + B : Natural renames C.Busy; + Node : Node_Access := Container.First; + begin - while Node /= null loop - Process (Cursor'(Container'Unchecked_Access, Node)); - Node := Node.Next; - end loop; + B := B + 1; + + begin + while Node /= null loop + Process (Cursor'(Container'Unchecked_Access, Node)); + Node := Node.Next; + end loop; + exception + when others => + B := B - 1; + raise; + end; + + B := B - 1; end Iterate; ---------- @@ -647,10 +878,12 @@ package body Ada.Containers.Doubly_Linked_Lists is return; end if; - if Target.Length > 0 then - raise Constraint_Error; + if Source.Busy > 0 then + raise Program_Error; end if; + Clear (Target); + Target.First := Source.First; Source.First := null; @@ -668,9 +901,24 @@ package body Ada.Containers.Doubly_Linked_Lists is procedure Next (Position : in out Cursor) is begin if Position.Node = null then + pragma Assert (Position.Container = null); return; end if; + pragma Assert (Position.Container /= null); + pragma Assert (Position.Container.Length > 0); + pragma Assert (Position.Container.First.Prev = null); + pragma Assert (Position.Container.Last.Next = null); + + pragma Assert (Position.Node.Prev = null + or else Position.Node.Prev.Next = Position.Node); + pragma Assert (Position.Node.Next = null + or else Position.Node.Next.Prev = Position.Node); + pragma Assert (Position.Node.Prev /= null + or else Position.Node = Position.Container.First); + pragma Assert (Position.Node.Next /= null + or else Position.Node = Position.Container.Last); + Position.Node := Position.Node.Next; if Position.Node = null then @@ -681,9 +929,24 @@ package body Ada.Containers.Doubly_Linked_Lists is function Next (Position : Cursor) return Cursor is begin if Position.Node = null then + pragma Assert (Position.Container = null); return No_Element; end if; + pragma Assert (Position.Container /= null); + pragma Assert (Position.Container.Length > 0); + pragma Assert (Position.Container.First.Prev = null); + pragma Assert (Position.Container.Last.Next = null); + + pragma Assert (Position.Node.Prev = null + or else Position.Node.Prev.Next = Position.Node); + pragma Assert (Position.Node.Next = null + or else Position.Node.Next.Prev = Position.Node); + pragma Assert (Position.Node.Prev /= null + or else Position.Node = Position.Container.First); + pragma Assert (Position.Node.Next /= null + or else Position.Node = Position.Container.Last); + declare Next_Node : constant Node_Access := Position.Node.Next; begin @@ -715,9 +978,24 @@ package body Ada.Containers.Doubly_Linked_Lists is procedure Previous (Position : in out Cursor) is begin if Position.Node = null then + pragma Assert (Position.Container = null); return; end if; + pragma Assert (Position.Container /= null); + pragma Assert (Position.Container.Length > 0); + pragma Assert (Position.Container.First.Prev = null); + pragma Assert (Position.Container.Last.Next = null); + + pragma Assert (Position.Node.Prev = null + or else Position.Node.Prev.Next = Position.Node); + pragma Assert (Position.Node.Next = null + or else Position.Node.Next.Prev = Position.Node); + pragma Assert (Position.Node.Prev /= null + or else Position.Node = Position.Container.First); + pragma Assert (Position.Node.Next /= null + or else Position.Node = Position.Container.Last); + Position.Node := Position.Node.Prev; if Position.Node = null then @@ -728,9 +1006,24 @@ package body Ada.Containers.Doubly_Linked_Lists is function Previous (Position : Cursor) return Cursor is begin if Position.Node = null then + pragma Assert (Position.Container = null); return No_Element; end if; + pragma Assert (Position.Container /= null); + pragma Assert (Position.Container.Length > 0); + pragma Assert (Position.Container.First.Prev = null); + pragma Assert (Position.Container.Last.Next = null); + + pragma Assert (Position.Node.Prev = null + or else Position.Node.Prev.Next = Position.Node); + pragma Assert (Position.Node.Next = null + or else Position.Node.Next.Prev = Position.Node); + pragma Assert (Position.Node.Prev /= null + or else Position.Node = Position.Container.First); + pragma Assert (Position.Node.Next /= null + or else Position.Node = Position.Container.Last); + declare Prev_Node : constant Node_Access := Position.Node.Prev; begin @@ -750,8 +1043,42 @@ package body Ada.Containers.Doubly_Linked_Lists is (Position : Cursor; Process : not null access procedure (Element : in Element_Type)) is + pragma Assert (Position.Container /= null); + pragma Assert (Position.Container.Length > 0); + pragma Assert (Position.Container.First.Prev = null); + pragma Assert (Position.Container.Last.Next = null); + + pragma Assert (Position.Node /= null); + pragma Assert (Position.Node.Prev = null + or else Position.Node.Prev.Next = Position.Node); + pragma Assert (Position.Node.Next = null + or else Position.Node.Next.Prev = Position.Node); + pragma Assert (Position.Node.Prev /= null + or else Position.Node = Position.Container.First); + pragma Assert (Position.Node.Next /= null + or else Position.Node = Position.Container.Last); + + E : Element_Type renames Position.Node.Element; + + C : List renames Position.Container.all'Unrestricted_Access.all; + B : Natural renames C.Busy; + L : Natural renames C.Lock; + begin - Process (Position.Node.Element); + B := B + 1; + L := L + 1; + + begin + Process (E); + exception + when others => + L := L - 1; + B := B - 1; + raise; + end; + + L := L - 1; + B := B - 1; end Query_Element; ---------- @@ -766,7 +1093,7 @@ package body Ada.Containers.Doubly_Linked_Lists is X : Node_Access; begin - Clear (Item); -- ??? + Clear (Item); Count_Type'Base'Read (Stream, N); if N = 0 then @@ -814,8 +1141,29 @@ package body Ada.Containers.Doubly_Linked_Lists is (Position : Cursor; By : Element_Type) is + pragma Assert (Position.Container /= null); + pragma Assert (Position.Container.Length > 0); + pragma Assert (Position.Container.First.Prev = null); + pragma Assert (Position.Container.Last.Next = null); + + pragma Assert (Position.Node /= null); + pragma Assert (Position.Node.Prev = null + or else Position.Node.Prev.Next = Position.Node); + pragma Assert (Position.Node.Next = null + or else Position.Node.Next.Prev = Position.Node); + pragma Assert (Position.Node.Prev /= null + or else Position.Node = Position.Container.First); + pragma Assert (Position.Node.Next /= null + or else Position.Node = Position.Container.Last); + + E : Element_Type renames Position.Node.Element; + begin - Position.Node.Element := By; + if Position.Container.Lock > 0 then + raise Program_Error; + end if; + + E := By; end Replace_Element; ------------------ @@ -832,8 +1180,23 @@ package body Ada.Containers.Doubly_Linked_Lists is begin if Node = null then Node := Container.Last; - elsif Position.Container /= List_Access'(Container'Unchecked_Access) then - raise Program_Error; + else + if Position.Container /= List_Access'(Container'Unchecked_Access) then + raise Program_Error; + end if; + + pragma Assert (Container.Length > 0); + pragma Assert (Container.First.Prev = null); + pragma Assert (Container.Last.Next = null); + + pragma Assert (Position.Node.Prev = null + or else Position.Node.Prev.Next = Position.Node); + pragma Assert (Position.Node.Next = null + or else Position.Node.Next.Prev = Position.Node); + pragma Assert (Position.Node.Prev /= null + or else Position.Node = Container.First); + pragma Assert (Position.Node.Next /= null + or else Position.Node = Container.Last); end if; while Node /= null loop @@ -855,12 +1218,26 @@ package body Ada.Containers.Doubly_Linked_Lists is (Container : List; Process : not null access procedure (Position : Cursor)) is + C : List renames Container'Unrestricted_Access.all; + B : Natural renames C.Busy; + Node : Node_Access := Container.Last; + begin - while Node /= null loop - Process (Cursor'(Container'Unchecked_Access, Node)); - Node := Node.Prev; - end loop; + B := B + 1; + + begin + while Node /= null loop + Process (Cursor'(Container'Unchecked_Access, Node)); + Node := Node.Prev; + end loop; + exception + when others => + B := B - 1; + raise; + end; + + B := B - 1; end Reverse_Iterate; ------------------ @@ -918,6 +1295,13 @@ package body Ada.Containers.Doubly_Linked_Lists is return; end if; + pragma Assert (Container.First.Prev = null); + pragma Assert (Container.Last.Next = null); + + if Container.Busy > 0 then + raise Program_Error; + end if; + Container.First := J; Container.Last := I; loop @@ -952,10 +1336,23 @@ package body Ada.Containers.Doubly_Linked_Lists is Source : in out List) is begin - if Before.Container /= null - and then Before.Container /= List_Access'(Target'Unchecked_Access) - then - raise Program_Error; + if Before.Node /= null then + if Before.Container /= List_Access'(Target'Unchecked_Access) then + raise Program_Error; + end if; + + pragma Assert (Target.Length >= 1); + pragma Assert (Target.First.Prev = null); + pragma Assert (Target.Last.Next = null); + + pragma Assert (Before.Node.Prev = null + or else Before.Node.Prev.Next = Before.Node); + pragma Assert (Before.Node.Next = null + or else Before.Node.Next.Prev = Before.Node); + pragma Assert (Before.Node.Prev /= null + or else Before.Node = Target.First); + pragma Assert (Before.Node.Next /= null + or else Before.Node = Target.Last); end if; if Target'Address = Source'Address @@ -964,7 +1361,22 @@ package body Ada.Containers.Doubly_Linked_Lists is return; end if; + pragma Assert (Source.First.Prev = null); + pragma Assert (Source.Last.Next = null); + + if Target.Length > Count_Type'Last - Source.Length then + raise Constraint_Error; + end if; + + if Target.Busy > 0 + or else Source.Busy > 0 + then + raise Program_Error; + end if; + if Target.Length = 0 then + pragma Assert (Target.First = null); + pragma Assert (Target.Last = null); pragma Assert (Before = No_Element); Target.First := Source.First; @@ -987,6 +1399,8 @@ package body Ada.Containers.Doubly_Linked_Lists is Target.First := Source.First; else + pragma Assert (Target.Length >= 2); + Before.Node.Prev.Next := Source.First; Source.First.Prev := Before.Node.Prev; @@ -1006,189 +1420,309 @@ package body Ada.Containers.Doubly_Linked_Lists is Before : Cursor; Position : Cursor) is - X : Node_Access := Position.Node; - begin - if Before.Container /= null - and then Before.Container /= List_Access'(Target'Unchecked_Access) - then - raise Program_Error; + if Before.Node /= null then + if Before.Container /= List_Access'(Target'Unchecked_Access) then + raise Program_Error; + end if; + + pragma Assert (Target.Length >= 1); + pragma Assert (Target.First.Prev = null); + pragma Assert (Target.Last.Next = null); + + pragma Assert (Before.Node.Prev = null + or else Before.Node.Prev.Next = Before.Node); + pragma Assert (Before.Node.Next = null + or else Before.Node.Next.Prev = Before.Node); + pragma Assert (Before.Node.Prev /= null + or else Before.Node = Target.First); + pragma Assert (Before.Node.Next /= null + or else Before.Node = Target.Last); end if; - if Position.Container /= null - and then Position.Container /= List_Access'(Target'Unchecked_Access) - then + if Position.Node = null then + raise Constraint_Error; + end if; + + if Position.Container /= List_Access'(Target'Unchecked_Access) then raise Program_Error; end if; - if X = null - or else X = Before.Node - or else X.Next = Before.Node + pragma Assert (Target.Length >= 1); + pragma Assert (Target.First.Prev = null); + pragma Assert (Target.Last.Next = null); + + pragma Assert (Position.Node.Prev = null + or else Position.Node.Prev.Next = Position.Node); + pragma Assert (Position.Node.Next = null + or else Position.Node.Next.Prev = Position.Node); + pragma Assert (Position.Node.Prev /= null + or else Position.Node = Target.First); + pragma Assert (Position.Node.Next /= null + or else Position.Node = Target.Last); + + if Position.Node = Before.Node + or else Position.Node.Next = Before.Node then return; end if; - pragma Assert (Target.Length > 0); + pragma Assert (Target.Length >= 2); + + if Target.Busy > 0 then + raise Program_Error; + end if; if Before.Node = null then - pragma Assert (X /= Target.Last); + pragma Assert (Position.Node /= Target.Last); - if X = Target.First then - Target.First := X.Next; + if Position.Node = Target.First then + Target.First := Position.Node.Next; Target.First.Prev := null; else - X.Prev.Next := X.Next; - X.Next.Prev := X.Prev; + Position.Node.Prev.Next := Position.Node.Next; + Position.Node.Next.Prev := Position.Node.Prev; end if; - Target.Last.Next := X; - X.Prev := Target.Last; + Target.Last.Next := Position.Node; + Position.Node.Prev := Target.Last; - Target.Last := X; + Target.Last := Position.Node; Target.Last.Next := null; return; end if; if Before.Node = Target.First then - pragma Assert (X /= Target.First); + pragma Assert (Position.Node /= Target.First); - if X = Target.Last then - Target.Last := X.Prev; + if Position.Node = Target.Last then + Target.Last := Position.Node.Prev; Target.Last.Next := null; else - X.Prev.Next := X.Next; - X.Next.Prev := X.Prev; + Position.Node.Prev.Next := Position.Node.Next; + Position.Node.Next.Prev := Position.Node.Prev; end if; - Target.First.Prev := X; - X.Next := Target.First; + Target.First.Prev := Position.Node; + Position.Node.Next := Target.First; - Target.First := X; + Target.First := Position.Node; Target.First.Prev := null; return; end if; - if X = Target.First then - Target.First := X.Next; + if Position.Node = Target.First then + Target.First := Position.Node.Next; Target.First.Prev := null; - elsif X = Target.Last then - Target.Last := X.Prev; + elsif Position.Node = Target.Last then + Target.Last := Position.Node.Prev; Target.Last.Next := null; else - X.Prev.Next := X.Next; - X.Next.Prev := X.Prev; + Position.Node.Prev.Next := Position.Node.Next; + Position.Node.Next.Prev := Position.Node.Prev; end if; - Before.Node.Prev.Next := X; - X.Prev := Before.Node.Prev; + Before.Node.Prev.Next := Position.Node; + Position.Node.Prev := Before.Node.Prev; + + Before.Node.Prev := Position.Node; + Position.Node.Next := Before.Node; - Before.Node.Prev := X; - X.Next := Before.Node; + pragma Assert (Target.First.Prev = null); + pragma Assert (Target.Last.Next = null); end Splice; procedure Splice (Target : in out List; Before : Cursor; Source : in out List; - Position : Cursor) + Position : in out Cursor) is - X : Node_Access := Position.Node; - begin if Target'Address = Source'Address then Splice (Target, Before, Position); return; end if; - if Before.Container /= null - and then Before.Container /= List_Access'(Target'Unchecked_Access) - then - raise Program_Error; + if Before.Node /= null then + if Before.Container /= List_Access'(Target'Unchecked_Access) then + raise Program_Error; + end if; + + pragma Assert (Target.Length >= 1); + pragma Assert (Target.First.Prev = null); + pragma Assert (Target.Last.Next = null); + + pragma Assert (Before.Node.Prev = null + or else Before.Node.Prev.Next = Before.Node); + pragma Assert (Before.Node.Next = null + or else Before.Node.Next.Prev = Before.Node); + pragma Assert (Before.Node.Prev /= null + or else Before.Node = Target.First); + pragma Assert (Before.Node.Next /= null + or else Before.Node = Target.Last); end if; - if Position.Container /= null - and then Position.Container /= List_Access'(Source'Unchecked_Access) - then - raise Program_Error; + if Position.Node = null then + raise Constraint_Error; end if; - if X = null then - return; + if Position.Container /= List_Access'(Source'Unchecked_Access) then + raise Program_Error; end if; - pragma Assert (Source.Length > 0); + pragma Assert (Source.Length >= 1); pragma Assert (Source.First.Prev = null); pragma Assert (Source.Last.Next = null); - if X = Source.First then - Source.First := X.Next; + pragma Assert (Position.Node.Prev = null + or else Position.Node.Prev.Next = Position.Node); + pragma Assert (Position.Node.Next = null + or else Position.Node.Next.Prev = Position.Node); + pragma Assert (Position.Node.Prev /= null + or else Position.Node = Source.First); + pragma Assert (Position.Node.Next /= null + or else Position.Node = Source.Last); + + if Target.Length = Count_Type'Last then + raise Constraint_Error; + end if; + + if Target.Busy > 0 + or else Source.Busy > 0 + then + raise Program_Error; + end if; + + if Position.Node = Source.First then + Source.First := Position.Node.Next; Source.First.Prev := null; - if X = Source.Last then + if Position.Node = Source.Last then pragma Assert (Source.First = null); pragma Assert (Source.Length = 1); Source.Last := null; end if; - elsif X = Source.Last then - Source.Last := X.Prev; + elsif Position.Node = Source.Last then + pragma Assert (Source.Length >= 2); + Source.Last := Position.Node.Prev; Source.Last.Next := null; else - X.Prev.Next := X.Next; - X.Next.Prev := X.Prev; + pragma Assert (Source.Length >= 3); + Position.Node.Prev.Next := Position.Node.Next; + Position.Node.Next.Prev := Position.Node.Prev; end if; if Target.Length = 0 then - pragma Assert (Before = No_Element); pragma Assert (Target.First = null); pragma Assert (Target.Last = null); + pragma Assert (Before = No_Element); - Target.First := X; - Target.Last := X; + Target.First := Position.Node; + Target.Last := Position.Node; + + Target.First.Prev := null; + Target.Last.Next := null; elsif Before.Node = null then - Target.Last.Next := X; - X.Next := Target.Last; + pragma Assert (Target.Last.Next = null); + Target.Last.Next := Position.Node; + Position.Node.Prev := Target.Last; - Target.Last := X; + Target.Last := Position.Node; Target.Last.Next := null; elsif Before.Node = Target.First then - Target.First.Prev := X; - X.Next := Target.First; + pragma Assert (Target.First.Prev = null); + Target.First.Prev := Position.Node; + Position.Node.Next := Target.First; - Target.First := X; + Target.First := Position.Node; Target.First.Prev := null; else - Before.Node.Prev.Next := X; - X.Prev := Before.Node.Prev; + pragma Assert (Target.Length >= 2); + Before.Node.Prev.Next := Position.Node; + Position.Node.Prev := Before.Node.Prev; - Before.Node.Prev := X; - X.Next := Before.Node; + Before.Node.Prev := Position.Node; + Position.Node.Next := Before.Node; end if; Target.Length := Target.Length + 1; Source.Length := Source.Length - 1; + + Position.Container := Target'Unchecked_Access; end Splice; ---------- -- Swap -- ---------- - -- Is this defined when I and J designate elements in different containers, - -- or should it raise an exception (Program_Error)??? - - procedure Swap (I, J : in Cursor) is - EI : constant Element_Type := I.Node.Element; + procedure Swap (I, J : Cursor) is begin - I.Node.Element := J.Node.Element; - J.Node.Element := EI; + if I.Container = null + or else J.Container = null + then + raise Constraint_Error; + end if; + + if I.Container /= J.Container then + raise Program_Error; + end if; + + declare + C : List renames I.Container.all; + begin + pragma Assert (C.Length >= 1); + pragma Assert (C.First.Prev = null); + pragma Assert (C.Last.Next = null); + + pragma Assert (I.Node /= null); + pragma Assert (I.Node.Prev = null + or else I.Node.Prev.Next = I.Node); + pragma Assert (I.Node.Next = null + or else I.Node.Next.Prev = I.Node); + pragma Assert (I.Node.Prev /= null + or else I.Node = C.First); + pragma Assert (I.Node.Next /= null + or else I.Node = C.Last); + + if I.Node = J.Node then + return; + end if; + + pragma Assert (C.Length >= 2); + pragma Assert (J.Node /= null); + pragma Assert (J.Node.Prev = null + or else J.Node.Prev.Next = J.Node); + pragma Assert (J.Node.Next = null + or else J.Node.Next.Prev = J.Node); + pragma Assert (J.Node.Prev /= null + or else J.Node = C.First); + pragma Assert (J.Node.Next /= null + or else J.Node = C.Last); + + if C.Lock > 0 then + raise Program_Error; + end if; + + declare + EI : Element_Type renames I.Node.Element; + EJ : Element_Type renames J.Node.Element; + + EI_Copy : constant Element_Type := EI; + begin + EI := EJ; + EJ := EI_Copy; + end; + end; end Swap; ---------------- @@ -1197,11 +1731,10 @@ package body Ada.Containers.Doubly_Linked_Lists is procedure Swap_Links (Container : in out List; - I, J : Cursor) - is + I, J : Cursor) is begin - if I = No_Element - or else J = No_Element + if I.Container = null + or else J.Container = null then raise Constraint_Error; end if; @@ -1215,6 +1748,18 @@ package body Ada.Containers.Doubly_Linked_Lists is end if; pragma Assert (Container.Length >= 1); + pragma Assert (Container.First.Prev = null); + pragma Assert (Container.Last.Next = null); + + pragma Assert (I.Node /= null); + pragma Assert (I.Node.Prev = null + or else I.Node.Prev.Next = I.Node); + pragma Assert (I.Node.Next = null + or else I.Node.Next.Prev = I.Node); + pragma Assert (I.Node.Prev /= null + or else I.Node = Container.First); + pragma Assert (I.Node.Next /= null + or else I.Node = Container.Last); if I.Node = J.Node then return; @@ -1222,6 +1767,20 @@ package body Ada.Containers.Doubly_Linked_Lists is pragma Assert (Container.Length >= 2); + pragma Assert (J.Node /= null); + pragma Assert (J.Node.Prev = null + or else J.Node.Prev.Next = J.Node); + pragma Assert (J.Node.Next = null + or else J.Node.Next.Prev = J.Node); + pragma Assert (J.Node.Prev /= null + or else J.Node = Container.First); + pragma Assert (J.Node.Next /= null + or else J.Node = Container.Last); + + if Container.Busy > 0 then + raise Program_Error; + end if; + declare I_Next : constant Cursor := Next (I); @@ -1255,8 +1814,43 @@ package body Ada.Containers.Doubly_Linked_Lists is procedure Update_Element (Position : Cursor; Process : not null access procedure (Element : in out Element_Type)) is + + pragma Assert (Position.Container /= null); + pragma Assert (Position.Container.Length >= 1); + pragma Assert (Position.Container.First.Prev = null); + pragma Assert (Position.Container.Last.Next = null); + + pragma Assert (Position.Node /= null); + pragma Assert (Position.Node.Prev = null + or else Position.Node.Prev.Next = Position.Node); + pragma Assert (Position.Node.Next = null + or else Position.Node.Next.Prev = Position.Node); + pragma Assert (Position.Node.Prev /= null + or else Position.Node = Position.Container.First); + pragma Assert (Position.Node.Next /= null + or else Position.Node = Position.Container.Last); + + E : Element_Type renames Position.Node.Element; + + C : List renames Position.Container.all'Unrestricted_Access.all; + B : Natural renames C.Busy; + L : Natural renames C.Lock; + begin - Process (Position.Node.Element); + B := B + 1; + L := L + 1; + + begin + Process (E); + exception + when others => + L := L - 1; + B := B - 1; + raise; + end; + + L := L - 1; + B := B - 1; end Update_Element; ----------- @@ -1279,4 +1873,3 @@ package body Ada.Containers.Doubly_Linked_Lists is end Write; end Ada.Containers.Doubly_Linked_Lists; - |