===================================================================
@@ -3233,7 +3233,7 @@
Make_Selected_Component (Loc,
Prefix => New_Occurrence_Of (Pack, Loc),
Selector_Name =>
- Make_Identifier (Loc, Name_Has_Element)),
+ Make_Identifier (Loc, Name_Has_Element)),
Parameter_Associations =>
New_List (
@@ -3250,21 +3250,19 @@
-- I : Iterator_Type renames Container;
-- C : Pack.Cursor_Type := Container.[First | Last];
- declare
- Decl1 : Node_Id;
- Decl2 : Node_Id;
- Decl3 : Node_Id;
+ Insert_Action (N,
+ Make_Object_Renaming_Declaration (Loc,
+ Defining_Identifier => Iterator,
+ Subtype_Mark => New_Occurrence_Of (Iter_Type, Loc),
+ Name => Relocate_Node (Name (I_Spec))));
- begin
- Decl1 :=
- Make_Object_Renaming_Declaration (Loc,
- Defining_Identifier => Iterator,
- Subtype_Mark => New_Occurrence_Of (Iter_Type, Loc),
- Name => Relocate_Node (Name (I_Spec)));
+ -- Create declaration for cursor
- -- Create declaration for cursor
+ declare
+ Decl : Node_Id;
- Decl2 :=
+ begin
+ Decl :=
Make_Object_Declaration (Loc,
Defining_Identifier => Cursor,
Object_Definition =>
@@ -3275,31 +3273,14 @@
Selector_Name =>
Make_Identifier (Loc, Name_Init)));
- Set_Assignment_OK (Decl2);
-
-- The cursor is only modified in expanded code, so it appears
-- as unassigned to the warning machinery. We must suppress
-- this spurious warning explicitly.
- Decl3 :=
- Make_Pragma (Loc,
- Chars => Name_Warnings,
- Pragma_Argument_Associations => New_List (
- Make_Pragma_Argument_Association (Loc,
- Expression => Make_Identifier (Loc, Name_Off)),
- Make_Pragma_Argument_Association (Loc,
- Expression =>
- New_Occurrence_Of (Cursor, Loc))));
+ Set_Warnings_Off (Cursor);
+ Set_Assignment_OK (Decl);
- -- The expanded loop is wrapped in a block, to make the loop
- -- variable local.
-
- New_Loop :=
- Make_Block_Statement (Loc,
- Declarations => New_List (Decl1, Decl2, Decl3),
- Handled_Statement_Sequence =>
- Make_Handled_Sequence_Of_Statements (Loc,
- Statements => New_List (New_Loop)));
+ Insert_Action (N, Decl);
end;
-- If the range of iteration is given by a function call that
===================================================================
@@ -27,18 +27,20 @@
-- This unit was originally developed by Matthew J Heaney. --
------------------------------------------------------------------------------
-with System; use type System.Address;
-
with Ada.Unchecked_Deallocation;
+with System; use type System.Address;
package body Ada.Containers.Doubly_Linked_Lists is
- type Iterator is limited new
- List_Iterator_Interfaces.Reversible_Iterator with record
- Container : List_Access;
- Node : Node_Access;
+ type Iterator is new Limited_Controlled and
+ List_Iterator_Interfaces.Reversible_Iterator with
+ record
+ Container : List_Access;
+ Node : Node_Access;
end record;
+ overriding procedure Finalize (Object : in out Iterator);
+
overriding function First (Object : Iterator) return Cursor;
overriding function Last (Object : Iterator) return Cursor;
@@ -396,6 +398,22 @@
return Position.Node.Element;
end Element;
+ --------------
+ -- Finalize --
+ --------------
+
+ procedure Finalize (Object : in out Iterator) is
+ begin
+ if Object.Container /= null then
+ declare
+ B : Natural renames Object.Container.all.Busy;
+
+ begin
+ B := B - 1;
+ end;
+ end if;
+ end Finalize;
+
----------
-- Find --
----------
@@ -422,7 +440,7 @@
while Node /= null loop
if Node.Element = Item then
- return Cursor'(Container'Unchecked_Access, Node);
+ return Cursor'(Container'Unrestricted_Access, Node);
end if;
Node := Node.Next;
@@ -441,7 +459,7 @@
return No_Element;
end if;
- return Cursor'(Container'Unchecked_Access, Container.First);
+ return Cursor'(Container'Unrestricted_Access, Container.First);
end First;
function First (Object : Iterator) return Cursor is
@@ -857,9 +875,7 @@
(Container : List;
Process : not null access procedure (Position : Cursor))
is
- C : List renames Container'Unrestricted_Access.all;
- B : Natural renames C.Busy;
-
+ B : Natural renames Container'Unrestricted_Access.all.Busy;
Node : Node_Access := Container.First;
begin
@@ -867,7 +883,7 @@
begin
while Node /= null loop
- Process (Cursor'(Container'Unchecked_Access, Node));
+ Process (Cursor'(Container'Unrestricted_Access, Node));
Node := Node.Next;
end loop;
exception
@@ -882,6 +898,8 @@
function Iterate (Container : List)
return List_Iterator_Interfaces.Reversible_Iterator'Class
is
+ B : Natural renames Container'Unrestricted_Access.all.Busy;
+
begin
-- The value of the Node component influences the behavior of the First
-- and Last selector functions of the iterator object. When the Node
@@ -893,12 +911,20 @@
-- Note: For a forward iterator, Container.First is the beginning, and
-- for a reverse iterator, Container.Last is the beginning.
- return Iterator'(Container'Unrestricted_Access, Node => null);
+ return It : constant Iterator :=
+ Iterator'(Limited_Controlled with
+ Container => Container'Unrestricted_Access,
+ Node => null)
+ do
+ B := B + 1;
+ end return;
end Iterate;
function Iterate (Container : List; Start : Cursor)
return List_Iterator_Interfaces.Reversible_Iterator'Class
is
+ B : Natural renames Container'Unrestricted_Access.all.Busy;
+
begin
-- It was formerly the case that when Start = No_Element, the partial
-- iterator was defined to behave the same as for a complete iterator,
@@ -932,7 +958,13 @@
-- the start position has the same value irrespective of whether this
-- is a forward or reverse iteration.
- return Iterator'(Container'Unrestricted_Access, Node => Start.Node);
+ return It : constant Iterator :=
+ Iterator'(Limited_Controlled with
+ Container => Container'Unrestricted_Access,
+ Node => Start.Node)
+ do
+ B := B + 1;
+ end return;
end Iterate;
----------
@@ -945,7 +977,7 @@
return No_Element;
end if;
- return Cursor'(Container'Unchecked_Access, Container.Last);
+ return Cursor'(Container'Unrestricted_Access, Container.Last);
end Last;
function Last (Object : Iterator) return Cursor is
@@ -1412,7 +1444,7 @@
while Node /= null loop
if Node.Element = Item then
- return Cursor'(Container'Unchecked_Access, Node);
+ return Cursor'(Container'Unrestricted_Access, Node);
end if;
Node := Node.Prev;
@@ -1439,7 +1471,7 @@
begin
while Node /= null loop
- Process (Cursor'(Container'Unchecked_Access, Node));
+ Process (Cursor'(Container'Unrestricted_Access, Node));
Node := Node.Prev;
end loop;
===================================================================
@@ -306,7 +306,7 @@
for List'Write use Write;
- type List_Access is access constant List;
+ type List_Access is access all List;
for List_Access'Storage_Size use 0;
type Cursor is
===================================================================
@@ -34,7 +34,6 @@
pragma Elaborate_All (Ada.Containers.Hash_Tables.Generic_Keys);
with Ada.Unchecked_Deallocation;
-
with System; use type System.Address;
package body Ada.Containers.Indefinite_Hashed_Maps is
@@ -45,11 +44,14 @@
procedure Free_Element is
new Ada.Unchecked_Deallocation (Element_Type, Element_Access);
- type Iterator is limited new
- Map_Iterator_Interfaces.Forward_Iterator with record
- Container : Map_Access;
- end record;
+ type Iterator is new Limited_Controlled and
+ Map_Iterator_Interfaces.Forward_Iterator with
+ record
+ Container : Map_Access;
+ end record;
+ overriding procedure Finalize (Object : in out Iterator);
+
overriding function First (Object : Iterator) return Cursor;
overriding function Next
@@ -421,6 +423,18 @@
HT_Ops.Finalize (Container.HT);
end Finalize;
+ procedure Finalize (Object : in out Iterator) is
+ begin
+ if Object.Container /= null then
+ declare
+ B : Natural renames Object.Container.all.HT.Busy;
+
+ begin
+ B := B - 1;
+ end;
+ end if;
+ end Finalize;
+
----------
-- Find --
----------
@@ -433,7 +447,7 @@
return No_Element;
end if;
- return Cursor'(Container'Unchecked_Access, Node);
+ return Cursor'(Container'Unrestricted_Access, Node);
end Find;
--------------------
@@ -471,7 +485,7 @@
return No_Element;
end if;
- return Cursor'(Container'Unchecked_Access, Node);
+ return Cursor'(Container'Unrestricted_Access, Node);
end First;
function First (Object : Iterator) return Cursor is
@@ -687,10 +701,10 @@
procedure Process_Node (Node : Node_Access) is
begin
- Process (Cursor'(Container'Unchecked_Access, Node));
+ Process (Cursor'(Container'Unrestricted_Access, Node));
end Process_Node;
- B : Natural renames Container'Unrestricted_Access.HT.Busy;
+ B : Natural renames Container'Unrestricted_Access.all.HT.Busy;
-- Start of processing Iterate
@@ -711,8 +725,15 @@
function Iterate
(Container : Map) return Map_Iterator_Interfaces.Forward_Iterator'Class
is
+ B : Natural renames Container'Unrestricted_Access.all.HT.Busy;
+
begin
- return Iterator'(Container => Container'Unrestricted_Access);
+ return It : constant Iterator :=
+ (Limited_Controlled with
+ Container => Container'Unrestricted_Access)
+ do
+ B := B + 1;
+ end return;
end Iterate;
---------
===================================================================
@@ -341,11 +341,10 @@
use HT_Types;
use Ada.Finalization;
- overriding procedure Adjust (Container : in out Map);
-
+ overriding procedure Adjust (Container : in out Map);
overriding procedure Finalize (Container : in out Map);
- type Map_Access is access constant Map;
+ type Map_Access is access all Map;
for Map_Access'Storage_Size use 0;
type Cursor is record
===================================================================
@@ -29,7 +29,7 @@
with Ada.Containers.Generic_Array_Sort;
with Ada.Unchecked_Deallocation;
-with System; use type System.Address;
+with System; use type System.Address;
package body Ada.Containers.Indefinite_Vectors is
@@ -39,16 +39,18 @@
procedure Free is
new Ada.Unchecked_Deallocation (Element_Type, Element_Access);
- type Iterator is new
- Vector_Iterator_Interfaces.Reversible_Iterator with record
+ type Iterator is new Limited_Controlled and
+ Vector_Iterator_Interfaces.Reversible_Iterator with
+ record
Container : Vector_Access;
Index : Index_Type;
end record;
+ overriding procedure Finalize (Object : in out Iterator);
+
overriding function First (Object : Iterator) return Cursor;
+ overriding function Last (Object : Iterator) return Cursor;
- overriding function Last (Object : Iterator) return Cursor;
-
overriding function Next
(Object : Iterator;
Position : Cursor) return Cursor;
@@ -1105,6 +1107,18 @@
end;
end Finalize;
+ procedure Finalize (Object : in out Iterator) is
+ begin
+ if Object.Container /= null then
+ declare
+ B : Natural renames Object.Container.all.Busy;
+
+ begin
+ B := B - 1;
+ end;
+ end if;
+ end Finalize;
+
----------
-- Find --
----------
@@ -1129,7 +1143,7 @@
if Container.Elements.EA (J) /= null
and then Container.Elements.EA (J).all = Item
then
- return (Container'Unchecked_Access, J);
+ return (Container'Unrestricted_Access, J);
end if;
end loop;
@@ -1167,7 +1181,7 @@
return No_Element;
end if;
- return (Container'Unchecked_Access, Index_Type'First);
+ return (Container'Unrestricted_Access, Index_Type'First);
end First;
function First (Object : Iterator) return Cursor is
@@ -1982,7 +1996,7 @@
begin
if Before.Container /= null
- and then Before.Container /= Container'Unchecked_Access
+ and then Before.Container /= Container'Unrestricted_Access
then
raise Program_Error with "Before cursor denotes wrong container";
end if;
@@ -2018,7 +2032,8 @@
begin
if Before.Container /= null
- and then Before.Container /= Vector_Access'(Container'Unchecked_Access)
+ and then Before.Container /=
+ Vector_Access'(Container'Unrestricted_Access)
then
raise Program_Error with "Before cursor denotes wrong container";
end if;
@@ -2029,7 +2044,7 @@
then
Position := No_Element;
else
- Position := (Container'Unchecked_Access, Before.Index);
+ Position := (Container'Unrestricted_Access, Before.Index);
end if;
return;
@@ -2051,7 +2066,7 @@
Insert (Container, Index, New_Item);
- Position := Cursor'(Container'Unchecked_Access, Index);
+ Position := Cursor'(Container'Unrestricted_Access, Index);
end Insert;
procedure Insert
@@ -2064,7 +2079,7 @@
begin
if Before.Container /= null
- and then Before.Container /= Container'Unchecked_Access
+ and then Before.Container /= Container'Unrestricted_Access
then
raise Program_Error with "Before cursor denotes wrong container";
end if;
@@ -2101,7 +2116,7 @@
begin
if Before.Container /= null
- and then Before.Container /= Container'Unchecked_Access
+ and then Before.Container /= Container'Unrestricted_Access
then
raise Program_Error with "Before cursor denotes wrong container";
end if;
@@ -2112,7 +2127,7 @@
then
Position := No_Element;
else
- Position := (Container'Unchecked_Access, Before.Index);
+ Position := (Container'Unrestricted_Access, Before.Index);
end if;
return;
@@ -2134,7 +2149,7 @@
Insert (Container, Index, New_Item, Count);
- Position := (Container'Unchecked_Access, Index);
+ Position := (Container'Unrestricted_Access, Index);
end Insert;
------------------
@@ -2465,7 +2480,7 @@
begin
if Before.Container /= null
- and then Before.Container /= Container'Unchecked_Access
+ and then Before.Container /= Container'Unrestricted_Access
then
raise Program_Error with "Before cursor denotes wrong container";
end if;
@@ -2476,7 +2491,7 @@
then
Position := No_Element;
else
- Position := (Container'Unchecked_Access, Before.Index);
+ Position := (Container'Unrestricted_Access, Before.Index);
end if;
return;
@@ -2498,7 +2513,7 @@
Insert_Space (Container, Index, Count);
- Position := Cursor'(Container'Unchecked_Access, Index);
+ Position := Cursor'(Container'Unrestricted_Access, Index);
end Insert_Space;
--------------
@@ -2518,15 +2533,14 @@
(Container : Vector;
Process : not null access procedure (Position : Cursor))
is
- V : Vector renames Container'Unrestricted_Access.all;
- B : Natural renames V.Busy;
+ B : Natural renames Container'Unrestricted_Access.all.Busy;
begin
B := B + 1;
begin
for Indx in Index_Type'First .. Container.Last loop
- Process (Cursor'(Container'Unchecked_Access, Indx));
+ Process (Cursor'(Container'Unrestricted_Access, Indx));
end loop;
exception
when others =>
@@ -2540,9 +2554,16 @@
function Iterate (Container : Vector)
return Vector_Iterator_Interfaces.Reversible_Iterator'class
is
- It : constant Iterator := (Container'Unchecked_Access, Index_Type'First);
+ B : Natural renames Container'Unrestricted_Access.all.Busy;
+
begin
- return It;
+ return It : constant Iterator :=
+ (Limited_Controlled with
+ Container => Container'Unrestricted_Access,
+ Index => Index_Type'First)
+ do
+ B := B + 1;
+ end return;
end Iterate;
function Iterate
@@ -2550,10 +2571,16 @@
Start : Cursor)
return Vector_Iterator_Interfaces.Reversible_Iterator'class
is
- It : constant Iterator :=
- (Container'Unchecked_Access, Start.Index);
+ B : Natural renames Container'Unrestricted_Access.all.Busy;
+
begin
- return It;
+ return It : constant Iterator :=
+ (Limited_Controlled with
+ Container => Container'Unrestricted_Access,
+ Index => Start.Index)
+ do
+ B := B + 1;
+ end return;
end Iterate;
----------
@@ -2566,7 +2593,7 @@
return No_Element;
end if;
- return (Container'Unchecked_Access, Container.Last);
+ return (Container'Unrestricted_Access, Container.Last);
end Last;
function Last (Object : Iterator) return Cursor is
@@ -3313,7 +3340,7 @@
begin
if Position.Container /= null
- and then Position.Container /= Container'Unchecked_Access
+ and then Position.Container /= Container'Unrestricted_Access
then
raise Program_Error with "Position cursor denotes wrong container";
end if;
@@ -3330,7 +3357,7 @@
if Container.Elements.EA (Indx) /= null
and then Container.Elements.EA (Indx).all = Item
then
- return (Container'Unchecked_Access, Indx);
+ return (Container'Unrestricted_Access, Indx);
end if;
end loop;
@@ -3376,7 +3403,7 @@
begin
for Indx in reverse Index_Type'First .. Container.Last loop
- Process (Cursor'(Container'Unchecked_Access, Indx));
+ Process (Cursor'(Container'Unrestricted_Access, Indx));
end loop;
exception
when others =>
@@ -3491,7 +3518,7 @@
return No_Element;
end if;
- return Cursor'(Container'Unchecked_Access, Index);
+ return Cursor'(Container'Unrestricted_Access, Index);
end To_Cursor;
--------------
===================================================================
@@ -426,7 +426,7 @@
for Vector'Read use Read;
- type Vector_Access is access constant Vector;
+ type Vector_Access is access all Vector;
for Vector_Access'Storage_Size use 0;
type Cursor is record
===================================================================
@@ -75,6 +75,14 @@
-- messages. This variable is recursively saved on entry to processing the
-- construct, and restored on exit.
+ procedure Pre_Analyze_Range (R_Copy : Node_Id);
+ -- Determine expected type of range or domain of iteration of Ada 2012
+ -- loop by analyzing separate copy. Do the analysis and resolution of the
+ -- copy of the bound(s) with expansion disabled, to prevent the generation
+ -- of finalization actions. This prevents memory leaks when the bounds
+ -- contain calls to functions returning controlled arrays or when the
+ -- domain of iteration is a container.
+
------------------------
-- Analyze_Assignment --
------------------------
@@ -1618,90 +1626,6 @@
-- calls that use the secondary stack, returning True if any such call
-- is found, and False otherwise.
- procedure Pre_Analyze_Range (R_Copy : Node_Id);
- -- Determine expected type of range or domain of iteration of Ada 2012
- -- loop by analyzing separate copy. Do the analysis and resolution of
- -- the copy of the bound(s) with expansion disabled, to prevent the
- -- generation of finalization actions. This prevents memory leaks when
- -- the bounds contain calls to functions returning controlled arrays or
- -- when the domain of iteration is a container.
-
- -----------------------
- -- Pre_Analyze_Range --
- -----------------------
-
- procedure Pre_Analyze_Range (R_Copy : Node_Id) is
- Save_Analysis : Boolean;
- begin
- Save_Analysis := Full_Analysis;
- Full_Analysis := False;
- Expander_Mode_Save_And_Set (False);
-
- Analyze (R_Copy);
-
- if Nkind (R_Copy) in N_Subexpr
- and then Is_Overloaded (R_Copy)
- then
-
- -- Apply preference rules for range of predefined integer types,
- -- or diagnose true ambiguity.
-
- declare
- I : Interp_Index;
- It : Interp;
- Found : Entity_Id := Empty;
-
- begin
- Get_First_Interp (R_Copy, I, It);
- while Present (It.Typ) loop
- if Is_Discrete_Type (It.Typ) then
- if No (Found) then
- Found := It.Typ;
- else
- if Scope (Found) = Standard_Standard then
- null;
-
- elsif Scope (It.Typ) = Standard_Standard then
- Found := It.Typ;
-
- else
- -- Both of them are user-defined
-
- Error_Msg_N
- ("ambiguous bounds in range of iteration",
- R_Copy);
- Error_Msg_N ("\possible interpretations:", R_Copy);
- Error_Msg_NE ("\\} ", R_Copy, Found);
- Error_Msg_NE ("\\} ", R_Copy, It.Typ);
- exit;
- end if;
- end if;
- end if;
-
- Get_Next_Interp (I, It);
- end loop;
- end;
- end if;
-
- if Is_Entity_Name (R_Copy)
- and then Is_Type (Entity (R_Copy))
- then
-
- -- Subtype mark in iteration scheme
-
- null;
-
- elsif Nkind (R_Copy) in N_Subexpr then
-
- -- Expression in range, or Ada 2012 iterator
-
- Resolve (R_Copy);
- end if;
-
- Expander_Mode_Restore;
- Full_Analysis := Save_Analysis;
- end Pre_Analyze_Range;
-
--------------------
-- Process_Bounds --
--------------------
@@ -1855,7 +1779,7 @@
if New_Lo_Bound /= Lo
and then Is_Static_Expression (New_Lo_Bound)
then
- Rewrite (Low_Bound (R), New_Copy (New_Lo_Bound));
+ Rewrite (Low_Bound (R), New_Copy (New_Lo_Bound));
end if;
if New_Hi_Bound /= Hi
@@ -2034,7 +1958,7 @@
begin
if Present (H)
and then Enclosing_Dynamic_Scope (H) =
- Enclosing_Dynamic_Scope (Id)
+ Enclosing_Dynamic_Scope (Id)
and then Ekind (H) = E_Variable
and then Is_Discrete_Type (Etype (H))
then
@@ -2059,7 +1983,7 @@
then
Process_Bounds (DS);
- -- expander not active or else range of iteration is a subtype
+ -- Expander not active or else range of iteration is a subtype
-- indication, an entity, or a function call that yields an
-- aggregate or a container.
@@ -2513,12 +2437,95 @@
----------------------------
procedure Analyze_Loop_Statement (N : Node_Id) is
- Loop_Statement : constant Node_Id := N;
- Id : constant Node_Id := Identifier (Loop_Statement);
- Iter : constant Node_Id := Iteration_Scheme (Loop_Statement);
+ function Is_Container_Iterator (Iter : Node_Id) return Boolean;
+ -- Given a loop iteration scheme, determine whether it is an Ada 2012
+ -- container iteration.
+
+ function Is_Wrapped_In_Block (N : Node_Id) return Boolean;
+ -- Determine whether node N is the sole statement of a block
+
+ ---------------------------
+ -- Is_Container_Iterator --
+ ---------------------------
+
+ function Is_Container_Iterator (Iter : Node_Id) return Boolean is
+ begin
+ -- Infinite loop
+
+ if No (Iter) then
+ return False;
+
+ -- While loop
+
+ elsif Present (Condition (Iter)) then
+ return False;
+
+ -- for Def_Id in [reverse] Name loop
+ -- for Def_Id [: Subtype_Indication] of [reverse] Name loop
+
+ elsif Present (Iterator_Specification (Iter)) then
+ declare
+ Nam : constant Node_Id := Name (Iterator_Specification (Iter));
+ Nam_Copy : Node_Id;
+
+ begin
+ Nam_Copy := New_Copy_Tree (Nam);
+ Set_Parent (Nam_Copy, Parent (Nam));
+ Pre_Analyze_Range (Nam_Copy);
+
+ -- The only two options here are iteration over a container or
+ -- an array.
+
+ return not Is_Array_Type (Etype (Nam_Copy));
+ end;
+
+ -- for Def_Id in [reverse] Discrete_Subtype_Definition loop
+
+ else
+ declare
+ LP : constant Node_Id := Loop_Parameter_Specification (Iter);
+ DS : constant Node_Id := Discrete_Subtype_Definition (LP);
+ DS_Copy : Node_Id;
+
+ begin
+ DS_Copy := New_Copy_Tree (DS);
+ Set_Parent (DS_Copy, Parent (DS));
+ Pre_Analyze_Range (DS_Copy);
+
+ -- Check for a call to Iterate ()
+
+ return
+ Nkind (DS_Copy) = N_Function_Call
+ and then Needs_Finalization (Etype (DS_Copy));
+ end;
+ end if;
+ end Is_Container_Iterator;
+
+ -------------------------
+ -- Is_Wrapped_In_Block --
+ -------------------------
+
+ function Is_Wrapped_In_Block (N : Node_Id) return Boolean is
+ HSS : constant Node_Id := Parent (N);
+
+ begin
+ return
+ Nkind (HSS) = N_Handled_Sequence_Of_Statements
+ and then Nkind (Parent (HSS)) = N_Block_Statement
+ and then First (Statements (HSS)) = N
+ and then No (Next (First (Statements (HSS))));
+ end Is_Wrapped_In_Block;
+
+ -- Local declarations
+
+ Id : constant Node_Id := Identifier (N);
+ Iter : constant Node_Id := Iteration_Scheme (N);
+ Loc : constant Source_Ptr := Sloc (N);
Ent : Entity_Id;
+ -- Start of processing for Analyze_Loop_Statement
+
begin
if Present (Id) then
@@ -2534,15 +2541,13 @@
if No (Ent) then
if Total_Errors_Detected /= 0 then
- Ent :=
- New_Internal_Entity
- (E_Loop, Current_Scope, Sloc (Loop_Statement), 'L');
+ Ent := New_Internal_Entity (E_Loop, Current_Scope, Loc, 'L');
else
raise Program_Error;
end if;
else
- Generate_Reference (Ent, Loop_Statement, ' ');
+ Generate_Reference (Ent, N, ' ');
Generate_Definition (Ent);
-- If we found a label, mark its type. If not, ignore it, since it
@@ -2555,7 +2560,7 @@
Set_Ekind (Ent, E_Loop);
if Nkind (Parent (Ent)) = N_Implicit_Label_Declaration then
- Set_Label_Construct (Parent (Ent), Loop_Statement);
+ Set_Label_Construct (Parent (Ent), N);
end if;
end if;
end if;
@@ -2563,13 +2568,30 @@
-- Case of no identifier present
else
- Ent :=
- New_Internal_Entity
- (E_Loop, Current_Scope, Sloc (Loop_Statement), 'L');
- Set_Etype (Ent, Standard_Void_Type);
- Set_Parent (Ent, Loop_Statement);
+ Ent := New_Internal_Entity (E_Loop, Current_Scope, Loc, 'L');
+ Set_Etype (Ent, Standard_Void_Type);
+ Set_Parent (Ent, N);
end if;
+ -- Iteration over a container in Ada 2012 involves the creation of a
+ -- controlled iterator object. Wrap the loop in a block to ensure the
+ -- timely finalization of the iterator and release of container locks.
+
+ if Ada_Version >= Ada_2012
+ and then Is_Container_Iterator (Iter)
+ and then not Is_Wrapped_In_Block (N)
+ then
+ Rewrite (N,
+ Make_Block_Statement (Loc,
+ Declarations => New_List,
+ Handled_Statement_Sequence =>
+ Make_Handled_Sequence_Of_Statements (Loc,
+ Statements => New_List (Relocate_Node (N)))));
+
+ Analyze (N);
+ return;
+ end if;
+
-- Kill current values on entry to loop, since statements in the body of
-- the loop may have been executed before the loop is entered. Similarly
-- we kill values after the loop, since we do not know that the body of
@@ -2610,7 +2632,7 @@
end;
end if;
- Analyze_Statements (Statements (Loop_Statement));
+ Analyze_Statements (Statements (N));
end if;
-- Finish up processing for the loop. We kill all current values, since
@@ -2619,7 +2641,7 @@
-- know will execute at least once, but it's not worth the trouble and
-- the front end is not in the business of flow tracing.
- Process_End_Label (Loop_Statement, 'e', Ent);
+ Process_End_Label (N, 'e', Ent);
End_Scope;
Kill_Current_Values;
@@ -2871,4 +2893,76 @@
end if;
end Check_Unreachable_Code;
+ -----------------------
+ -- Pre_Analyze_Range --
+ -----------------------
+
+ procedure Pre_Analyze_Range (R_Copy : Node_Id) is
+ Save_Analysis : constant Boolean := Full_Analysis;
+
+ begin
+ Full_Analysis := False;
+ Expander_Mode_Save_And_Set (False);
+
+ Analyze (R_Copy);
+
+ if Nkind (R_Copy) in N_Subexpr
+ and then Is_Overloaded (R_Copy)
+ then
+ -- Apply preference rules for range of predefined integer types, or
+ -- diagnose true ambiguity.
+
+ declare
+ I : Interp_Index;
+ It : Interp;
+ Found : Entity_Id := Empty;
+
+ begin
+ Get_First_Interp (R_Copy, I, It);
+ while Present (It.Typ) loop
+ if Is_Discrete_Type (It.Typ) then
+ if No (Found) then
+ Found := It.Typ;
+ else
+ if Scope (Found) = Standard_Standard then
+ null;
+
+ elsif Scope (It.Typ) = Standard_Standard then
+ Found := It.Typ;
+
+ else
+ -- Both of them are user-defined
+
+ Error_Msg_N
+ ("ambiguous bounds in range of iteration", R_Copy);
+ Error_Msg_N ("\possible interpretations:", R_Copy);
+ Error_Msg_NE ("\\} ", R_Copy, Found);
+ Error_Msg_NE ("\\} ", R_Copy, It.Typ);
+ exit;
+ end if;
+ end if;
+ end if;
+
+ Get_Next_Interp (I, It);
+ end loop;
+ end;
+ end if;
+
+ -- Subtype mark in iteration scheme
+
+ if Is_Entity_Name (R_Copy)
+ and then Is_Type (Entity (R_Copy))
+ then
+ null;
+
+ -- Expression in range, or Ada 2012 iterator
+
+ elsif Nkind (R_Copy) in N_Subexpr then
+ Resolve (R_Copy);
+ end if;
+
+ Expander_Mode_Restore;
+ Full_Analysis := Save_Analysis;
+ end Pre_Analyze_Range;
+
end Sem_Ch5;
===================================================================
@@ -37,21 +37,22 @@
pragma Elaborate_All (Ada.Containers.Red_Black_Trees.Generic_Set_Operations);
with Ada.Unchecked_Deallocation;
-
with System; use type System.Address;
package body Ada.Containers.Indefinite_Ordered_Sets is
- type Iterator is limited new
- Set_Iterator_Interfaces.Reversible_Iterator with record
- Container : Set_Access;
- Node : Node_Access;
- end record;
+ type Iterator is new Limited_Controlled and
+ Set_Iterator_Interfaces.Reversible_Iterator with
+ record
+ Container : Set_Access;
+ Node : Node_Access;
+ end record;
+ overriding procedure Finalize (Object : in out Iterator);
+
overriding function First (Object : Iterator) return Cursor;
+ overriding function Last (Object : Iterator) return Cursor;
- overriding function Last (Object : Iterator) return Cursor;
-
overriding function Next
(Object : Iterator;
Position : Cursor) return Cursor;
@@ -571,6 +572,22 @@
end if;
end Exclude;
+ --------------
+ -- Finalize --
+ --------------
+
+ procedure Finalize (Object : in out Iterator) is
+ begin
+ if Object.Container /= null then
+ declare
+ B : Natural renames Object.Container.all.Tree.Busy;
+
+ begin
+ B := B - 1;
+ end;
+ end if;
+ end Finalize;
+
----------
-- Find --
----------
@@ -1254,7 +1271,7 @@
Process (Cursor'(Container'Unrestricted_Access, Node));
end Process_Node;
- T : Tree_Type renames Container.Tree'Unrestricted_Access.all;
+ T : Tree_Type renames Container'Unrestricted_Access.all.Tree;
B : Natural renames T.Busy;
-- Start of processing for Iterate
@@ -1275,8 +1292,10 @@
function Iterate
(Container : Set)
- return Set_Iterator_Interfaces.Reversible_Iterator'Class
+ return Set_Iterator_Interfaces.Reversible_Iterator'class
is
+ B : Natural renames Container'Unrestricted_Access.all.Tree.Busy;
+
begin
-- The value of the Node component influences the behavior of the First
-- and Last selector functions of the iterator object. When the Node
@@ -1288,14 +1307,22 @@
-- Note: For a forward iterator, Container.First is the beginning, and
-- for a reverse iterator, Container.Last is the beginning.
- return Iterator'(Container'Unrestricted_Access, Node => null);
+ return It : constant Iterator :=
+ Iterator'(Limited_Controlled with
+ Container => Container'Unrestricted_Access,
+ Node => null)
+ do
+ B := B + 1;
+ end return;
end Iterate;
function Iterate
(Container : Set;
Start : Cursor)
- return Set_Iterator_Interfaces.Reversible_Iterator'Class
+ return Set_Iterator_Interfaces.Reversible_Iterator'class
is
+ B : Natural renames Container'Unrestricted_Access.all.Tree.Busy;
+
begin
-- It was formerly the case that when Start = No_Element, the partial
-- iterator was defined to behave the same as for a complete iterator,
@@ -1330,7 +1357,13 @@
-- the start position has the same value irrespective of whether this is
-- a forward or reverse iteration.
- return Iterator'(Container'Unrestricted_Access, Node => Start.Node);
+ return It : constant Iterator :=
+ (Limited_Controlled with
+ Container => Container'Unrestricted_Access,
+ Node => Start.Node)
+ do
+ B := B + 1;
+ end return;
end Iterate;
----------
===================================================================
@@ -39,16 +39,18 @@
package body Ada.Containers.Ordered_Maps is
- type Iterator is limited new
- Map_Iterator_Interfaces.Reversible_Iterator with record
- Container : Map_Access;
- Node : Node_Access;
- end record;
+ type Iterator is new Limited_Controlled and
+ Map_Iterator_Interfaces.Reversible_Iterator with
+ record
+ Container : Map_Access;
+ Node : Node_Access;
+ end record;
+ overriding procedure Finalize (Object : in out Iterator);
+
overriding function First (Object : Iterator) return Cursor;
+ overriding function Last (Object : Iterator) return Cursor;
- overriding function Last (Object : Iterator) return Cursor;
-
overriding function Next
(Object : Iterator;
Position : Cursor) return Cursor;
@@ -488,6 +490,22 @@
end if;
end Exclude;
+ --------------
+ -- Finalize --
+ --------------
+
+ procedure Finalize (Object : in out Iterator) is
+ begin
+ if Object.Container /= null then
+ declare
+ B : Natural renames Object.Container.all.Tree.Busy;
+
+ begin
+ B := B - 1;
+ end;
+ end if;
+ end Finalize;
+
----------
-- Find --
----------
@@ -839,6 +857,8 @@
function Iterate
(Container : Map) return Map_Iterator_Interfaces.Reversible_Iterator'Class
is
+ B : Natural renames Container.Tree'Unrestricted_Access.all.Busy;
+
begin
-- The value of the Node component influences the behavior of the First
-- and Last selector functions of the iterator object. When the Node
@@ -850,12 +870,20 @@
-- Note: For a forward iterator, Container.First is the beginning, and
-- for a reverse iterator, Container.Last is the beginning.
- return Iterator'(Container'Unrestricted_Access, Node => null);
+ return It : constant Iterator :=
+ (Limited_Controlled with
+ Container => Container'Unrestricted_Access,
+ Node => null)
+ do
+ B := B + 1;
+ end return;
end Iterate;
function Iterate (Container : Map; Start : Cursor)
return Map_Iterator_Interfaces.Reversible_Iterator'Class
is
+ B : Natural renames Container.Tree'Unrestricted_Access.all.Busy;
+
begin
-- It was formerly the case that when Start = No_Element, the partial
-- iterator was defined to behave the same as for a complete iterator,
@@ -890,7 +918,13 @@
-- the start position has the same value irrespective of whether this
-- is a forward or reverse iteration.
- return Iterator'(Container'Unrestricted_Access, Node => Start.Node);
+ return It : constant Iterator :=
+ (Limited_Controlled with
+ Container => Container'Unrestricted_Access,
+ Node => Start.Node)
+ do
+ B := B + 1;
+ end return;
end Iterate;
---------
===================================================================
@@ -35,20 +35,23 @@
pragma Elaborate_All
(Ada.Containers.Red_Black_Trees.Generic_Bounded_Keys);
-with System; use type System.Address;
+with Ada.Finalization; use Ada.Finalization;
+with System; use type System.Address;
package body Ada.Containers.Bounded_Ordered_Maps is
- type Iterator is limited new
- Map_Iterator_Interfaces.Reversible_Iterator with record
- Container : Map_Access;
- Node : Count_Type;
- end record;
+ type Iterator is new Limited_Controlled and
+ Map_Iterator_Interfaces.Reversible_Iterator with
+ record
+ Container : Map_Access;
+ Node : Count_Type;
+ end record;
+ overriding procedure Finalize (Object : in out Iterator);
+
overriding function First (Object : Iterator) return Cursor;
+ overriding function Last (Object : Iterator) return Cursor;
- overriding function Last (Object : Iterator) return Cursor;
-
overriding function Next
(Object : Iterator;
Position : Cursor) return Cursor;
@@ -551,6 +554,22 @@
end if;
end Exclude;
+ --------------
+ -- Finalize --
+ --------------
+
+ procedure Finalize (Object : in out Iterator) is
+ begin
+ if Object.Container /= null then
+ declare
+ B : Natural renames Object.Container.all.Busy;
+
+ begin
+ B := B - 1;
+ end;
+ end if;
+ end Finalize;
+
----------
-- Find --
----------
@@ -900,6 +919,8 @@
function Iterate
(Container : Map) return Map_Iterator_Interfaces.Reversible_Iterator'Class
is
+ B : Natural renames Container'Unrestricted_Access.all.Busy;
+
begin
-- The value of the Node component influences the behavior of the First
-- and Last selector functions of the iterator object. When the Node
@@ -911,7 +932,13 @@
-- Note: For a forward iterator, Container.First is the beginning, and
-- for a reverse iterator, Container.Last is the beginning.
- return Iterator'(Container'Unrestricted_Access, Node => 0);
+ return It : constant Iterator :=
+ (Limited_Controlled with
+ Container => Container'Unrestricted_Access,
+ Node => Container.First)
+ do
+ B := B + 1;
+ end return;
end Iterate;
function Iterate
@@ -919,9 +946,10 @@
Start : Cursor)
return Map_Iterator_Interfaces.Reversible_Iterator'Class
is
+ B : Natural renames Container'Unrestricted_Access.all.Busy;
+
begin
-
- -- iterator was defined to behave the same as for a complete iterator,
+ -- Iterator was defined to behave the same as for a complete iterator,
-- and iterate over the entire sequence of items. However, those
-- semantics were unintuitive and arguably error-prone (it is too easy
-- to accidentally create an endless loop), and so they were changed,
@@ -953,7 +981,13 @@
-- the start position has the same value irrespective of whether this
-- is a forward or reverse iteration.)
- return Iterator'(Container'Unrestricted_Access, Node => Start.Node);
+ return It : constant Iterator :=
+ (Limited_Controlled with
+ Container => Container'Unrestricted_Access,
+ Node => Start.Node)
+ do
+ B := B + 1;
+ end return;
end Iterate;
---------
===================================================================
@@ -27,24 +27,26 @@
-- This unit was originally developed by Matthew J Heaney. --
------------------------------------------------------------------------------
-with System; use type System.Address;
with Ada.Unchecked_Deallocation;
+with System; use type System.Address;
package body Ada.Containers.Indefinite_Doubly_Linked_Lists is
procedure Free is
new Ada.Unchecked_Deallocation (Element_Type, Element_Access);
- type Iterator is limited new
- List_Iterator_Interfaces.Reversible_Iterator with record
- Container : List_Access;
- Node : Node_Access;
- end record;
+ type Iterator is new Limited_Controlled and
+ List_Iterator_Interfaces.Reversible_Iterator with
+ record
+ Container : List_Access;
+ Node : Node_Access;
+ end record;
+ overriding procedure Finalize (Object : in out Iterator);
+
overriding function First (Object : Iterator) return Cursor;
+ overriding function Last (Object : Iterator) return Cursor;
- overriding function Last (Object : Iterator) return Cursor;
-
overriding function Next
(Object : Iterator;
Position : Cursor) return Cursor;
@@ -429,6 +431,22 @@
return Position.Node.Element.all;
end Element;
+ --------------
+ -- Finalize --
+ --------------
+
+ procedure Finalize (Object : in out Iterator) is
+ begin
+ if Object.Container /= null then
+ declare
+ B : Natural renames Object.Container.all.Busy;
+
+ begin
+ B := B - 1;
+ end;
+ end if;
+ end Finalize;
+
----------
-- Find --
----------
@@ -459,7 +477,7 @@
while Node /= null loop
if Node.Element.all = Item then
- return Cursor'(Container'Unchecked_Access, Node);
+ return Cursor'(Container'Unrestricted_Access, Node);
end if;
Node := Node.Next;
@@ -478,7 +496,7 @@
return No_Element;
end if;
- return Cursor'(Container'Unchecked_Access, Container.First);
+ return Cursor'(Container'Unrestricted_Access, Container.First);
end First;
function First (Object : Iterator) return Cursor is
@@ -884,9 +902,7 @@
(Container : List;
Process : not null access procedure (Position : Cursor))
is
- C : List renames Container'Unrestricted_Access.all;
- B : Natural renames C.Busy;
-
+ B : Natural renames Container'Unrestricted_Access.all.Busy;
Node : Node_Access := Container.First;
begin
@@ -894,7 +910,7 @@
begin
while Node /= null loop
- Process (Cursor'(Container'Unchecked_Access, Node));
+ Process (Cursor'(Container'Unrestricted_Access, Node));
Node := Node.Next;
end loop;
exception
@@ -908,8 +924,10 @@
function Iterate
(Container : List)
- return List_Iterator_Interfaces.Reversible_Iterator'Class
+ return List_Iterator_Interfaces.Reversible_Iterator'class
is
+ B : Natural renames Container'Unrestricted_Access.all.Busy;
+
begin
-- The value of the Node component influences the behavior of the First
-- and Last selector functions of the iterator object. When the Node
@@ -921,7 +939,13 @@
-- Note: For a forward iterator, Container.First is the beginning, and
-- for a reverse iterator, Container.Last is the beginning.
- return Iterator'(Container'Unrestricted_Access, Node => null);
+ return It : constant Iterator :=
+ Iterator'(Limited_Controlled with
+ Container => Container'Unrestricted_Access,
+ Node => null)
+ do
+ B := B + 1;
+ end return;
end Iterate;
function Iterate
@@ -929,6 +953,8 @@
Start : Cursor)
return List_Iterator_Interfaces.Reversible_Iterator'Class
is
+ B : Natural renames Container'Unrestricted_Access.all.Busy;
+
begin
-- It was formerly the case that when Start = No_Element, the partial
-- iterator was defined to behave the same as for a complete iterator,
@@ -962,7 +988,13 @@
-- the start position has the same value irrespective of whether this
-- is a forward or reverse iteration.
- return Iterator'(Container'Unrestricted_Access, Node => Start.Node);
+ return It : constant Iterator :=
+ Iterator'(Limited_Controlled with
+ Container => Container'Unrestricted_Access,
+ Node => Start.Node)
+ do
+ B := B + 1;
+ end return;
end Iterate;
----------
@@ -975,7 +1007,7 @@
return No_Element;
end if;
- return Cursor'(Container'Unchecked_Access, Container.Last);
+ return Cursor'(Container'Unrestricted_Access, Container.Last);
end Last;
function Last (Object : Iterator) return Cursor is
@@ -1452,7 +1484,7 @@
while Node /= null loop
if Node.Element.all = Item then
- return Cursor'(Container'Unchecked_Access, Node);
+ return Cursor'(Container'Unrestricted_Access, Node);
end if;
Node := Node.Prev;
@@ -1479,7 +1511,7 @@
begin
while Node /= null loop
- Process (Cursor'(Container'Unchecked_Access, Node));
+ Process (Cursor'(Container'Unrestricted_Access, Node));
Node := Node.Prev;
end loop;
exception
===================================================================
@@ -309,7 +309,7 @@
for List'Write use Write;
- type List_Access is access constant List;
+ type List_Access is access all List;
for List_Access'Storage_Size use 0;
type Cursor is
===================================================================
@@ -28,35 +28,41 @@
------------------------------------------------------------------------------
with Ada.Unchecked_Deallocation;
-with System; use type System.Address;
+with System; use type System.Address;
package body Ada.Containers.Indefinite_Multiway_Trees is
- type Iterator is new Tree_Iterator_Interfaces.Forward_Iterator with
+ type Iterator is new Limited_Controlled and
+ Tree_Iterator_Interfaces.Forward_Iterator with
record
Container : Tree_Access;
Position : Cursor;
From_Root : Boolean;
end record;
- type Child_Iterator is new Tree_Iterator_Interfaces.Reversible_Iterator with
+ type Child_Iterator is new Limited_Controlled and
+ Tree_Iterator_Interfaces.Reversible_Iterator with
record
Container : Tree_Access;
Position : Cursor;
end record;
+ overriding procedure Finalize (Object : in out Iterator);
+
overriding function First (Object : Iterator) return Cursor;
overriding function Next
- (Object : Iterator;
+ (Object : Iterator;
Position : Cursor) return Cursor;
+ overriding procedure Finalize (Object : in out Child_Iterator);
+
overriding function First (Object : Child_Iterator) return Cursor;
overriding function Next
- (Object : Child_Iterator;
+ (Object : Child_Iterator;
Position : Cursor) return Cursor;
overriding function Previous
- (Object : Child_Iterator;
+ (Object : Child_Iterator;
Position : Cursor) return Cursor;
overriding function Last (Object : Child_Iterator) return Cursor;
@@ -925,6 +931,34 @@
return Equal_Children (Left_Subtree, Right_Subtree);
end Equal_Subtree;
+ --------------
+ -- Finalize --
+ --------------
+
+ procedure Finalize (Object : in out Iterator) is
+ begin
+ if Object.Container /= null then
+ declare
+ B : Natural renames Object.Container.all.Busy;
+
+ begin
+ B := B - 1;
+ end;
+ end if;
+ end Finalize;
+
+ procedure Finalize (Object : in out Child_Iterator) is
+ begin
+ if Object.Container /= null then
+ declare
+ B : Natural renames Object.Container.all.Busy;
+
+ begin
+ B := B - 1;
+ end;
+ end if;
+ end Finalize;
+
----------
-- Find --
----------
@@ -1304,8 +1338,7 @@
(Container : Tree;
Process : not null access procedure (Position : Cursor))
is
- T : Tree renames Container'Unrestricted_Access.all;
- B : Integer renames T.Busy;
+ B : Natural renames Container'Unrestricted_Access.all.Busy;
begin
B := B + 1;
@@ -1326,13 +1359,19 @@
function Iterate (Container : Tree)
return Tree_Iterator_Interfaces.Forward_Iterator'Class
is
- Root_Cursor : constant Cursor :=
- (Container'Unrestricted_Access, Root_Node (Container));
+ B : Natural renames Container'Unrestricted_Access.all.Busy;
+ RC : constant Cursor :=
+ (Container'Unrestricted_Access, Root_Node (Container));
+
begin
- return
- Iterator'(Container'Unrestricted_Access,
- First_Child (Root_Cursor),
- From_Root => True);
+ return It : constant Iterator :=
+ Iterator'(Limited_Controlled with
+ Container => Container'Unrestricted_Access,
+ Position => First_Child (RC),
+ From_Root => True)
+ do
+ B := B + 1;
+ end return;
end Iterate;
----------------------
@@ -1349,7 +1388,7 @@
end if;
declare
- B : Integer renames Parent.Container.Busy;
+ B : Natural renames Parent.Container.Busy;
C : Tree_Node_Access;
begin
@@ -1396,9 +1435,16 @@
Parent : Cursor)
return Tree_Iterator_Interfaces.Reversible_Iterator'Class
is
- pragma Unreferenced (Container);
+ B : Natural renames Container'Unrestricted_Access.all.Busy;
+
begin
- return Child_Iterator'(Parent.Container, Parent);
+ return It : constant Child_Iterator :=
+ Child_Iterator'(Limited_Controlled with
+ Container => Parent.Container,
+ Position => Parent)
+ do
+ B := B + 1;
+ end return;
end Iterate_Children;
---------------------
@@ -1409,8 +1455,17 @@
(Position : Cursor)
return Tree_Iterator_Interfaces.Forward_Iterator'Class
is
+ B : Natural renames Position.Container'Unrestricted_Access.all.Busy;
+
begin
- return Iterator'(Position.Container, Position, From_Root => False);
+ return It : constant Iterator :=
+ Iterator'(Limited_Controlled with
+ Container => Position.Container,
+ Position => Position,
+ From_Root => False)
+ do
+ B := B + 1;
+ end return;
end Iterate_Subtree;
procedure Iterate_Subtree
@@ -1423,7 +1478,7 @@
end if;
declare
- B : Integer renames Position.Container.Busy;
+ B : Natural renames Position.Container.Busy;
begin
B := B + 1;
@@ -1789,8 +1844,8 @@
declare
T : Tree renames Position.Container.all'Unrestricted_Access.all;
- B : Integer renames T.Busy;
- L : Integer renames T.Lock;
+ B : Natural renames T.Busy;
+ L : Natural renames T.Lock;
begin
B := B + 1;
@@ -2052,7 +2107,7 @@
end if;
declare
- B : Integer renames Parent.Container.Busy;
+ B : Natural renames Parent.Container.Busy;
C : Tree_Node_Access;
begin
@@ -2555,8 +2610,8 @@
declare
T : Tree renames Position.Container.all'Unrestricted_Access.all;
- B : Integer renames T.Busy;
- L : Integer renames T.Lock;
+ B : Natural renames T.Busy;
+ L : Natural renames T.Lock;
begin
B := B + 1;
===================================================================
@@ -327,8 +327,8 @@
type Tree is new Controlled with record
Root : aliased Tree_Node_Type;
- Busy : Integer := 0;
- Lock : Integer := 0;
+ Busy : Natural := 0;
+ Lock : Natural := 0;
Count : Count_Type := 0;
end record;
===================================================================
@@ -36,16 +36,18 @@
pragma Elaborate_All (Ada.Containers.Hash_Tables.Generic_Keys);
with Ada.Containers.Prime_Numbers;
+with System; use type System.Address;
-with System; use type System.Address;
-
package body Ada.Containers.Indefinite_Hashed_Sets is
- type Iterator is limited new
- Set_Iterator_Interfaces.Forward_Iterator with record
- Container : Set_Access;
- end record;
+ type Iterator is new Limited_Controlled and
+ Set_Iterator_Interfaces.Forward_Iterator with
+ record
+ Container : Set_Access;
+ end record;
+ overriding procedure Finalize (Object : in out Iterator);
+
overriding function First (Object : Iterator) return Cursor;
overriding function Next
@@ -569,6 +571,18 @@
HT_Ops.Finalize (Container.HT);
end Finalize;
+ procedure Finalize (Object : in out Iterator) is
+ begin
+ if Object.Container /= null then
+ declare
+ B : Natural renames Object.Container.all.HT.Busy;
+
+ begin
+ B := B - 1;
+ end;
+ end if;
+ end Finalize;
+
----------
-- Find --
----------
@@ -988,7 +1002,7 @@
Process (Cursor'(Container'Unrestricted_Access, Node));
end Process_Node;
- B : Natural renames Container'Unrestricted_Access.HT.Busy;
+ B : Natural renames Container'Unrestricted_Access.all.HT.Busy;
-- Start of processing for Iterate
@@ -1007,9 +1021,17 @@
end Iterate;
function Iterate (Container : Set)
- return Set_Iterator_Interfaces.Forward_Iterator'Class is
+ return Set_Iterator_Interfaces.Forward_Iterator'Class
+ is
+ B : Natural renames Container'Unrestricted_Access.all.HT.Busy;
+
begin
- return Iterator'(Container => Container'Unrestricted_Access);
+ return It : constant Iterator :=
+ Iterator'(Limited_Controlled with
+ Container => Container'Unrestricted_Access)
+ do
+ B := B + 1;
+ end return;
end Iterate;
------------
@@ -1897,7 +1919,7 @@
Key_Keys.Delete_Key_Sans_Free (Container.HT, Key, X);
if X = null then
- raise Constraint_Error with "key not in map"; -- ??? "set"
+ raise Constraint_Error with "key not in map"; -- ??? "set"
end if;
Free (X);
@@ -1915,7 +1937,7 @@
begin
if Node = null then
- raise Constraint_Error with "key not in map"; -- ??? "set"
+ raise Constraint_Error with "key not in map"; -- ??? "set"
end if;
return Node.Element.all;
===================================================================
@@ -39,11 +39,14 @@
package body Ada.Containers.Hashed_Maps is
- type Iterator is limited new
- Map_Iterator_Interfaces.Forward_Iterator with record
- Container : Map_Access;
- end record;
+ type Iterator is new Limited_Controlled and
+ Map_Iterator_Interfaces.Forward_Iterator with
+ record
+ Container : Map_Access;
+ end record;
+ overriding procedure Finalize (Object : in out Iterator);
+
overriding function First (Object : Iterator) return Cursor;
overriding function Next
@@ -385,6 +388,18 @@
HT_Ops.Finalize (Container.HT);
end Finalize;
+ procedure Finalize (Object : in out Iterator) is
+ begin
+ if Object.Container /= null then
+ declare
+ B : Natural renames Object.Container.all.HT.Busy;
+
+ begin
+ B := B - 1;
+ end;
+ end if;
+ end Finalize;
+
----------
-- Find --
----------
@@ -397,7 +412,7 @@
return No_Element;
end if;
- return Cursor'(Container'Unchecked_Access, Node);
+ return Cursor'(Container'Unrestricted_Access, Node);
end Find;
--------------------
@@ -435,7 +450,7 @@
return No_Element;
end if;
- return Cursor'(Container'Unchecked_Access, Node);
+ return Cursor'(Container'Unrestricted_Access, Node);
end First;
function First (Object : Iterator) return Cursor is
@@ -546,7 +561,7 @@
HT_Ops.Reserve_Capacity (HT, HT.Length);
end if;
- Position.Container := Container'Unchecked_Access;
+ Position.Container := Container'Unrestricted_Access;
end Insert;
procedure Insert
@@ -588,7 +603,7 @@
HT_Ops.Reserve_Capacity (HT, HT.Length);
end if;
- Position.Container := Container'Unchecked_Access;
+ Position.Container := Container'Unrestricted_Access;
end Insert;
procedure Insert
@@ -638,10 +653,10 @@
procedure Process_Node (Node : Node_Access) is
begin
- Process (Cursor'(Container'Unchecked_Access, Node));
+ Process (Cursor'(Container'Unrestricted_Access, Node));
end Process_Node;
- B : Natural renames Container'Unrestricted_Access.HT.Busy;
+ B : Natural renames Container'Unrestricted_Access.all.HT.Busy;
-- Start of processing for Iterate
@@ -662,8 +677,15 @@
function Iterate
(Container : Map) return Map_Iterator_Interfaces.Forward_Iterator'Class
is
+ B : Natural renames Container'Unrestricted_Access.all.HT.Busy;
+
begin
- return Iterator'(Container => Container'Unrestricted_Access);
+ return It : constant Iterator :=
+ (Limited_Controlled with
+ Container => Container'Unrestricted_Access)
+ do
+ B := B + 1;
+ end return;
end Iterate;
---------
===================================================================
@@ -384,7 +384,7 @@
for Map'Read use Read;
- type Map_Access is access constant Map;
+ type Map_Access is access all Map;
for Map_Access'Storage_Size use 0;
type Cursor is record
===================================================================
@@ -42,16 +42,18 @@
package body Ada.Containers.Ordered_Sets is
- type Iterator is limited new
- Set_Iterator_Interfaces.Reversible_Iterator with record
- Container : Set_Access;
- Node : Node_Access;
- end record;
+ type Iterator is new Limited_Controlled and
+ Set_Iterator_Interfaces.Reversible_Iterator with
+ record
+ Container : Set_Access;
+ Node : Node_Access;
+ end record;
+ overriding procedure Finalize (Object : in out Iterator);
+
overriding function First (Object : Iterator) return Cursor;
+ overriding function Last (Object : Iterator) return Cursor;
- overriding function Last (Object : Iterator) return Cursor;
-
overriding function Next
(Object : Iterator;
Position : Cursor) return Cursor;
@@ -512,6 +514,22 @@
end if;
end Exclude;
+ --------------
+ -- Finalize --
+ --------------
+
+ procedure Finalize (Object : in out Iterator) is
+ begin
+ if Object.Container /= null then
+ declare
+ B : Natural renames Object.Container.all.Tree.Busy;
+
+ begin
+ B := B - 1;
+ end;
+ end if;
+ end Finalize;
+
----------
-- Find --
----------
@@ -1160,7 +1178,7 @@
Process (Cursor'(Container'Unrestricted_Access, Node));
end Process_Node;
- T : Tree_Type renames Container.Tree'Unrestricted_Access.all;
+ T : Tree_Type renames Container'Unrestricted_Access.all.Tree;
B : Natural renames T.Busy;
-- Start of processing for Iterate
@@ -1182,6 +1200,8 @@
function Iterate (Container : Set)
return Set_Iterator_Interfaces.Reversible_Iterator'Class
is
+ B : Natural renames Container'Unrestricted_Access.all.Tree.Busy;
+
begin
-- The value of the Node component influences the behavior of the First
-- and Last selector functions of the iterator object. When the Node
@@ -1193,12 +1213,19 @@
-- Note: For a forward iterator, Container.First is the beginning, and
-- for a reverse iterator, Container.Last is the beginning.
- return Iterator'(Container'Unrestricted_Access, Node => null);
+ B := B + 1;
+
+ return It : constant Iterator :=
+ Iterator'(Limited_Controlled with
+ Container => Container'Unrestricted_Access,
+ Node => null);
end Iterate;
function Iterate (Container : Set; Start : Cursor)
return Set_Iterator_Interfaces.Reversible_Iterator'Class
is
+ B : Natural renames Container'Unrestricted_Access.all.Tree.Busy;
+
begin
-- It was formerly the case that when Start = No_Element, the partial
-- iterator was defined to behave the same as for a complete iterator,
@@ -1233,7 +1260,12 @@
-- the start position has the same value irrespective of whether this is
-- a forward or reverse iteration.
- return Iterator'(Container'Unrestricted_Access, Node => Start.Node);
+ B := B + 1;
+
+ return It : constant Iterator :=
+ Iterator'(Limited_Controlled with
+ Container => Container'Unrestricted_Access,
+ Node => Start.Node);
end Iterate;
----------
===================================================================
@@ -34,15 +34,19 @@
pragma Elaborate_All (Ada.Containers.Hash_Tables.Generic_Bounded_Keys);
with Ada.Containers.Prime_Numbers; use Ada.Containers.Prime_Numbers;
+with Ada.Finalization; use Ada.Finalization;
with System; use type System.Address;
package body Ada.Containers.Bounded_Hashed_Maps is
- type Iterator is new
- Map_Iterator_Interfaces.Forward_Iterator with record
- Container : Map_Access;
- end record;
+ type Iterator is new Limited_Controlled and
+ Map_Iterator_Interfaces.Forward_Iterator with
+ record
+ Container : Map_Access;
+ end record;
+ overriding procedure Finalize (Object : in out Iterator);
+
overriding function First (Object : Iterator) return Cursor;
overriding function Next
@@ -392,6 +396,22 @@
HT_Ops.Free (Container, X);
end Exclude;
+ --------------
+ -- Finalize --
+ --------------
+
+ procedure Finalize (Object : in out Iterator) is
+ begin
+ if Object.Container /= null then
+ declare
+ B : Natural renames Object.Container.all.Busy;
+
+ begin
+ B := B - 1;
+ end;
+ end if;
+ end Finalize;
+
----------
-- Find --
----------
@@ -649,7 +669,7 @@
Process (Cursor'(Container'Unrestricted_Access, Node));
end Process_Node;
- B : Natural renames Container'Unrestricted_Access.Busy;
+ B : Natural renames Container'Unrestricted_Access.all.Busy;
-- Start of processing for Iterate
@@ -670,8 +690,15 @@
function Iterate
(Container : Map) return Map_Iterator_Interfaces.Forward_Iterator'Class
is
+ B : Natural renames Container'Unrestricted_Access.all.Busy;
+
begin
- return Iterator'(Container => Container'Unrestricted_Access);
+ return It : constant Iterator :=
+ (Limited_Controlled with
+ Container => Container'Unrestricted_Access)
+ do
+ B := B + 1;
+ end return;
end Iterate;
---------
===================================================================
@@ -38,20 +38,23 @@
pragma Elaborate_All
(Ada.Containers.Red_Black_Trees.Generic_Bounded_Set_Operations);
+with Ada.Finalization; use Ada.Finalization;
with System; use type System.Address;
package body Ada.Containers.Bounded_Ordered_Sets is
- type Iterator is limited new
- Set_Iterator_Interfaces.Reversible_Iterator with record
- Container : Set_Access;
- Node : Count_Type;
- end record;
+ type Iterator is new Limited_Controlled and
+ Set_Iterator_Interfaces.Reversible_Iterator with
+ record
+ Container : Set_Access;
+ Node : Count_Type;
+ end record;
+ overriding procedure Finalize (Object : in out Iterator);
+
overriding function First (Object : Iterator) return Cursor;
+ overriding function Last (Object : Iterator) return Cursor;
- overriding function Last (Object : Iterator) return Cursor;
-
overriding function Next
(Object : Iterator;
Position : Cursor) return Cursor;
@@ -568,6 +571,22 @@
end if;
end Exclude;
+ --------------
+ -- Finalize --
+ --------------
+
+ procedure Finalize (Object : in out Iterator) is
+ begin
+ if Object.Container /= null then
+ declare
+ B : Natural renames Object.Container.all.Busy;
+
+ begin
+ B := B - 1;
+ end;
+ end if;
+ end Finalize;
+
----------
-- Find --
----------
@@ -1221,8 +1240,10 @@
end Iterate;
function Iterate (Container : Set)
- return Set_Iterator_Interfaces.Reversible_Iterator'Class
+ return Set_Iterator_Interfaces.Reversible_Iterator'class
is
+ B : Natural renames Container'Unrestricted_Access.all.Busy;
+
begin
-- The value of the Node component influences the behavior of the First
-- and Last selector functions of the iterator object. When the Node
@@ -1234,12 +1255,20 @@
-- Note: For a forward iterator, Container.First is the beginning, and
-- for a reverse iterator, Container.Last is the beginning.
- return Iterator'(Container'Unrestricted_Access, Node => 0);
+ return It : constant Iterator :=
+ Iterator'(Limited_Controlled with
+ Container => Container'Unrestricted_Access,
+ Node => 0)
+ do
+ B := B + 1;
+ end return;
end Iterate;
function Iterate (Container : Set; Start : Cursor)
- return Set_Iterator_Interfaces.Reversible_Iterator'Class
+ return Set_Iterator_Interfaces.Reversible_Iterator'class
is
+ B : Natural renames Container'Unrestricted_Access.all.Busy;
+
begin
-- It was formerly the case that when Start = No_Element, the partial
-- iterator was defined to behave the same as for a complete iterator,
@@ -1274,7 +1303,13 @@
-- the start position has the same value irrespective of whether this
-- is a forward or reverse iteration.)
- return Iterator'(Container'Unrestricted_Access, Node => Start.Node);
+ return It : constant Iterator :=
+ Iterator'(Limited_Controlled with
+ Container => Container'Unrestricted_Access,
+ Node => Start.Node)
+ do
+ B := B + 1;
+ end return;
end Iterate;
----------
===================================================================
@@ -29,28 +29,34 @@
with Ada.Unchecked_Conversion;
with Ada.Unchecked_Deallocation;
-with System; use type System.Address;
+with System; use type System.Address;
package body Ada.Containers.Multiway_Trees is
- type Iterator is new Tree_Iterator_Interfaces.Forward_Iterator with
+ type Iterator is new Limited_Controlled and
+ Tree_Iterator_Interfaces.Forward_Iterator with
record
Container : Tree_Access;
Position : Cursor;
From_Root : Boolean;
end record;
- type Child_Iterator is new Tree_Iterator_Interfaces.Reversible_Iterator with
+ type Child_Iterator is new Limited_Controlled and
+ Tree_Iterator_Interfaces.Reversible_Iterator with
record
Container : Tree_Access;
Position : Cursor;
end record;
+ overriding procedure Finalize (Object : in out Iterator);
+
overriding function First (Object : Iterator) return Cursor;
overriding function Next
(Object : Iterator;
Position : Cursor) return Cursor;
+ overriding procedure Finalize (Object : in out Child_Iterator);
+
overriding function First (Object : Child_Iterator) return Cursor;
overriding function Next
(Object : Child_Iterator;
@@ -898,6 +904,34 @@
return Equal_Children (Left_Subtree, Right_Subtree);
end Equal_Subtree;
+ --------------
+ -- Finalize --
+ --------------
+
+ procedure Finalize (Object : in out Iterator) is
+ begin
+ if Object.Container /= null then
+ declare
+ B : Natural renames Object.Container.all.Busy;
+
+ begin
+ B := B - 1;
+ end;
+ end if;
+ end Finalize;
+
+ procedure Finalize (Object : in out Child_Iterator) is
+ begin
+ if Object.Container /= null then
+ declare
+ B : Natural renames Object.Container.all.Busy;
+
+ begin
+ B := B - 1;
+ end;
+ end if;
+ end Finalize;
+
----------
-- Find --
----------
@@ -1342,8 +1376,7 @@
(Container : Tree;
Process : not null access procedure (Position : Cursor))
is
- T : Tree renames Container'Unrestricted_Access.all;
- B : Integer renames T.Busy;
+ B : Natural renames Container'Unrestricted_Access.all.Busy;
begin
B := B + 1;
@@ -1364,13 +1397,19 @@
function Iterate (Container : Tree)
return Tree_Iterator_Interfaces.Forward_Iterator'Class
is
- Root_Cursor : constant Cursor :=
- (Container'Unrestricted_Access, Root_Node (Container));
+ B : Natural renames Container'Unrestricted_Access.all.Busy;
+ RC : constant Cursor :=
+ (Container'Unrestricted_Access, Root_Node (Container));
+
begin
- return
- Iterator'(Container'Unrestricted_Access,
- First_Child (Root_Cursor),
- From_Root => True);
+ return It : constant Iterator :=
+ Iterator'(Limited_Controlled with
+ Container => Container'Unrestricted_Access,
+ Position => First_Child (RC),
+ From_Root => True)
+ do
+ B := B + 1;
+ end return;
end Iterate;
----------------------
@@ -1387,7 +1426,7 @@
end if;
declare
- B : Integer renames Parent.Container.Busy;
+ B : Natural renames Parent.Container.Busy;
C : Tree_Node_Access;
begin
@@ -1434,9 +1473,16 @@
Parent : Cursor)
return Tree_Iterator_Interfaces.Reversible_Iterator'Class
is
- pragma Unreferenced (Container);
+ B : Natural renames Container'Unrestricted_Access.all.Busy;
+
begin
- return Child_Iterator'(Parent.Container, Parent);
+ return It : constant Child_Iterator :=
+ Child_Iterator'(Limited_Controlled with
+ Container => Parent.Container,
+ Position => Parent)
+ do
+ B := B + 1;
+ end return;
end Iterate_Children;
---------------------
@@ -1447,8 +1493,17 @@
(Position : Cursor)
return Tree_Iterator_Interfaces.Forward_Iterator'Class
is
+ B : Natural renames Position.Container'Unrestricted_Access.all.Busy;
+
begin
- return Iterator'(Position.Container, Position, From_Root => False);
+ return It : constant Iterator :=
+ Iterator'(Limited_Controlled with
+ Container => Position.Container,
+ Position => Position,
+ From_Root => False)
+ do
+ B := B + 1;
+ end return;
end Iterate_Subtree;
procedure Iterate_Subtree
@@ -1461,7 +1516,7 @@
end if;
declare
- B : Integer renames Position.Container.Busy;
+ B : Natural renames Position.Container.Busy;
begin
B := B + 1;
@@ -1807,8 +1862,8 @@
declare
T : Tree renames Position.Container.all'Unrestricted_Access.all;
- B : Integer renames T.Busy;
- L : Integer renames T.Lock;
+ B : Natural renames T.Busy;
+ L : Natural renames T.Lock;
begin
B := B + 1;
@@ -2060,7 +2115,7 @@
end if;
declare
- B : Integer renames Parent.Container.Busy;
+ B : Natural renames Parent.Container.Busy;
C : Tree_Node_Access;
begin
@@ -2578,8 +2633,8 @@
declare
T : Tree renames Position.Container.all'Unrestricted_Access.all;
- B : Integer renames T.Busy;
- L : Integer renames T.Lock;
+ B : Natural renames T.Busy;
+ L : Natural renames T.Lock;
begin
B := B + 1;
===================================================================
@@ -372,8 +372,8 @@
type Tree is new Controlled with record
Root : aliased Root_Node_Type;
- Busy : Integer := 0;
- Lock : Integer := 0;
+ Busy : Natural := 0;
+ Lock : Natural := 0;
Count : Count_Type := 0;
end record;
===================================================================
@@ -40,16 +40,18 @@
package body Ada.Containers.Indefinite_Ordered_Maps is
pragma Suppress (All_Checks);
- type Iterator is limited new
- Map_Iterator_Interfaces.Reversible_Iterator with record
- Container : Map_Access;
- Node : Node_Access;
- end record;
+ type Iterator is new Limited_Controlled and
+ Map_Iterator_Interfaces.Reversible_Iterator with
+ record
+ Container : Map_Access;
+ Node : Node_Access;
+ end record;
+ overriding procedure Finalize (Object : in out Iterator);
+
overriding function First (Object : Iterator) return Cursor;
+ overriding function Last (Object : Iterator) return Cursor;
- overriding function Last (Object : Iterator) return Cursor;
-
overriding function Next
(Object : Iterator;
Position : Cursor) return Cursor;
@@ -535,6 +537,22 @@
end if;
end Exclude;
+ --------------
+ -- Finalize --
+ --------------
+
+ procedure Finalize (Object : in out Iterator) is
+ begin
+ if Object.Container /= null then
+ declare
+ B : Natural renames Object.Container.all.Tree.Busy;
+
+ begin
+ B := B - 1;
+ end;
+ end if;
+ end Finalize;
+
----------
-- Find --
----------
@@ -857,7 +875,7 @@
Process (Cursor'(Container'Unrestricted_Access, Node));
end Process_Node;
- B : Natural renames Container.Tree'Unrestricted_Access.all.Busy;
+ B : Natural renames Container'Unrestricted_Access.all.Tree.Busy;
-- Start of processing for Iterate
@@ -878,6 +896,8 @@
function Iterate
(Container : Map) return Map_Iterator_Interfaces.Reversible_Iterator'Class
is
+ B : Natural renames Container'Unrestricted_Access.all.Tree.Busy;
+
begin
-- The value of the Node component influences the behavior of the First
-- and Last selector functions of the iterator object. When the Node
@@ -889,7 +909,13 @@
-- Note: For a forward iterator, Container.First is the beginning, and
-- for a reverse iterator, Container.Last is the beginning.
- return Iterator'(Container'Unrestricted_Access, Node => null);
+ return It : constant Iterator :=
+ (Limited_Controlled with
+ Container => Container'Unrestricted_Access,
+ Node => null)
+ do
+ B := B + 1;
+ end return;
end Iterate;
function Iterate
@@ -897,6 +923,8 @@
Start : Cursor)
return Map_Iterator_Interfaces.Reversible_Iterator'Class
is
+ B : Natural renames Container'Unrestricted_Access.all.Tree.Busy;
+
begin
-- It was formerly the case that when Start = No_Element, the partial
-- iterator was defined to behave the same as for a complete iterator,
@@ -931,7 +959,13 @@
-- the start position has the same value irrespective of whether this
-- is a forward or reverse iteration.
- return Iterator'(Container'Unrestricted_Access, Node => Start.Node);
+ return It : constant Iterator :=
+ (Limited_Controlled with
+ Container => Container'Unrestricted_Access,
+ Node => Start.Node)
+ do
+ B := B + 1;
+ end return;
end Iterate;
---------
===================================================================
@@ -28,17 +28,20 @@
------------------------------------------------------------------------------
with Ada.Containers.Generic_Array_Sort;
-
+with Ada.Finalization; use Ada.Finalization;
with System; use type System.Address;
package body Ada.Containers.Bounded_Vectors is
- type Iterator is new
- Vector_Iterator_Interfaces.Reversible_Iterator with record
- Container : Vector_Access;
- Index : Index_Type;
- end record;
+ type Iterator is new Limited_Controlled and
+ Vector_Iterator_Interfaces.Reversible_Iterator with
+ record
+ Container : Vector_Access;
+ Index : Index_Type;
+ end record;
+ overriding procedure Finalize (Object : in out Iterator);
+
overriding function First (Object : Iterator) return Cursor;
overriding function Last (Object : Iterator) return Cursor;
@@ -658,6 +661,22 @@
end if;
end Element;
+ --------------
+ -- Finalize --
+ --------------
+
+ procedure Finalize (Object : in out Iterator) is
+ begin
+ if Object.Container /= null then
+ declare
+ B : Natural renames Object.Container.all.Busy;
+
+ begin
+ B := B - 1;
+ end;
+ end if;
+ end Finalize;
+
----------
-- Find --
----------
@@ -1607,8 +1626,7 @@
(Container : Vector;
Process : not null access procedure (Position : Cursor))
is
- V : Vector renames Container'Unrestricted_Access.all;
- B : Natural renames V.Busy;
+ B : Natural renames Container'Unrestricted_Access.all.Busy;
begin
B := B + 1;
@@ -1630,8 +1648,16 @@
(Container : Vector)
return Vector_Iterator_Interfaces.Reversible_Iterator'Class
is
+ B : Natural renames Container'Unrestricted_Access.all.Busy;
+
begin
- return Iterator'(Container'Unrestricted_Access, Index_Type'First);
+ return It : constant Iterator :=
+ Iterator'(Limited_Controlled with
+ Container => Container'Unrestricted_Access,
+ Index => Index_Type'First)
+ do
+ B := B + 1;
+ end return;
end Iterate;
function Iterate
@@ -1639,8 +1665,16 @@
Start : Cursor)
return Vector_Iterator_Interfaces.Reversible_Iterator'class
is
+ B : Natural renames Container'Unrestricted_Access.all.Busy;
+
begin
- return Iterator'(Container'Unrestricted_Access, Start.Index);
+ return It : constant Iterator :=
+ Iterator'(Limited_Controlled with
+ Container => Container'Unrestricted_Access,
+ Index => Start.Index)
+ do
+ B := B + 1;
+ end return;
end Iterate;
----------
===================================================================
@@ -29,7 +29,6 @@
with Ada.Containers.Generic_Array_Sort;
with Ada.Unchecked_Deallocation;
-
with System; use type System.Address;
package body Ada.Containers.Vectors is
@@ -37,12 +36,15 @@
procedure Free is
new Ada.Unchecked_Deallocation (Elements_Type, Elements_Access);
- type Iterator is new Vector_Iterator_Interfaces.Reversible_Iterator with
+ type Iterator is new Limited_Controlled and
+ Vector_Iterator_Interfaces.Reversible_Iterator with
record
Container : Vector_Access;
Index : Index_Type;
end record;
+ overriding procedure Finalize (Object : in out Iterator);
+
overriding function First (Object : Iterator) return Cursor;
overriding function Last (Object : Iterator) return Cursor;
overriding function Next
@@ -778,6 +780,18 @@
Free (X);
end Finalize;
+ procedure Finalize (Object : in out Iterator) is
+ begin
+ if Object.Container /= null then
+ declare
+ B : Natural renames Object.Container.all.Busy;
+
+ begin
+ B := B - 1;
+ end;
+ end if;
+ end Finalize;
+
----------
-- Find --
----------
@@ -800,7 +814,7 @@
for J in Position.Index .. Container.Last loop
if Container.Elements.EA (J) = Item then
- return (Container'Unchecked_Access, J);
+ return (Container'Unrestricted_Access, J);
end if;
end loop;
@@ -835,7 +849,7 @@
if Is_Empty (Container) then
return No_Element;
else
- return (Container'Unchecked_Access, Index_Type'First);
+ return (Container'Unrestricted_Access, Index_Type'First);
end if;
end First;
@@ -1500,7 +1514,7 @@
begin
if Before.Container /= null
- and then Before.Container /= Container'Unchecked_Access
+ and then Before.Container /= Container'Unrestricted_Access
then
raise Program_Error with "Before cursor denotes wrong container";
end if;
@@ -1536,7 +1550,7 @@
begin
if Before.Container /= null
- and then Before.Container /= Container'Unchecked_Access
+ and then Before.Container /= Container'Unrestricted_Access
then
raise Program_Error with "Before cursor denotes wrong container";
end if;
@@ -1547,7 +1561,7 @@
then
Position := No_Element;
else
- Position := (Container'Unchecked_Access, Before.Index);
+ Position := (Container'Unrestricted_Access, Before.Index);
end if;
return;
@@ -1569,7 +1583,7 @@
Insert (Container, Index, New_Item);
- Position := (Container'Unchecked_Access, Index);
+ Position := (Container'Unrestricted_Access, Index);
end Insert;
procedure Insert
@@ -1582,7 +1596,7 @@
begin
if Before.Container /= null
- and then Before.Container /= Container'Unchecked_Access
+ and then Before.Container /= Container'Unrestricted_Access
then
raise Program_Error with "Before cursor denotes wrong container";
end if;
@@ -1619,7 +1633,7 @@
begin
if Before.Container /= null
- and then Before.Container /= Container'Unchecked_Access
+ and then Before.Container /= Container'Unrestricted_Access
then
raise Program_Error with "Before cursor denotes wrong container";
end if;
@@ -1630,7 +1644,7 @@
then
Position := No_Element;
else
- Position := (Container'Unchecked_Access, Before.Index);
+ Position := (Container'Unrestricted_Access, Before.Index);
end if;
return;
@@ -1652,7 +1666,7 @@
Insert (Container, Index, New_Item, Count);
- Position := (Container'Unchecked_Access, Index);
+ Position := (Container'Unrestricted_Access, Index);
end Insert;
procedure Insert
@@ -2036,7 +2050,7 @@
begin
if Before.Container /= null
- and then Before.Container /= Container'Unchecked_Access
+ and then Before.Container /= Container'Unrestricted_Access
then
raise Program_Error with "Before cursor denotes wrong container";
end if;
@@ -2047,7 +2061,7 @@
then
Position := No_Element;
else
- Position := (Container'Unchecked_Access, Before.Index);
+ Position := (Container'Unrestricted_Access, Before.Index);
end if;
return;
@@ -2069,7 +2083,7 @@
Insert_Space (Container, Index, Count => Count);
- Position := (Container'Unchecked_Access, Index);
+ Position := (Container'Unrestricted_Access, Index);
end Insert_Space;
--------------
@@ -2089,15 +2103,14 @@
(Container : Vector;
Process : not null access procedure (Position : Cursor))
is
- V : Vector renames Container'Unrestricted_Access.all;
- B : Natural renames V.Busy;
+ B : Natural renames Container'Unrestricted_Access.all.Busy;
begin
B := B + 1;
begin
for Indx in Index_Type'First .. Container.Last loop
- Process (Cursor'(Container'Unchecked_Access, Indx));
+ Process (Cursor'(Container'Unrestricted_Access, Indx));
end loop;
exception
when others =>
@@ -2112,9 +2125,16 @@
(Container : Vector)
return Vector_Iterator_Interfaces.Reversible_Iterator'Class
is
- It : constant Iterator := (Container'Unchecked_Access, Index_Type'First);
+ B : Natural renames Container'Unrestricted_Access.all.Busy;
+
begin
- return It;
+ return It : constant Iterator :=
+ (Limited_Controlled with
+ Container => Container'Unrestricted_Access,
+ Index => Index_Type'First)
+ do
+ B := B + 1;
+ end return;
end Iterate;
function Iterate
@@ -2122,9 +2142,16 @@
Start : Cursor)
return Vector_Iterator_Interfaces.Reversible_Iterator'class
is
- It : constant Iterator := (Container'Unchecked_Access, Start.Index);
+ B : Natural renames Container'Unrestricted_Access.all.Busy;
+
begin
- return It;
+ return It : constant Iterator :=
+ (Limited_Controlled with
+ Container => Container'Unrestricted_Access,
+ Index => Start.Index)
+ do
+ B := B + 1;
+ end return;
end Iterate;
----------
@@ -2136,7 +2163,7 @@
if Is_Empty (Container) then
return No_Element;
else
- return (Container'Unchecked_Access, Container.Last);
+ return (Container'Unrestricted_Access, Container.Last);
end if;
end Last;
@@ -2903,7 +2930,7 @@
begin
if Position.Container /= null
- and then Position.Container /= Container'Unchecked_Access
+ and then Position.Container /= Container'Unrestricted_Access
then
raise Program_Error with "Position cursor denotes wrong container";
end if;
@@ -2915,7 +2942,7 @@
for Indx in reverse Index_Type'First .. Last loop
if Container.Elements.EA (Indx) = Item then
- return (Container'Unchecked_Access, Indx);
+ return (Container'Unrestricted_Access, Indx);
end if;
end loop;
@@ -2960,7 +2987,7 @@
begin
for Indx in reverse Index_Type'First .. Container.Last loop
- Process (Cursor'(Container'Unchecked_Access, Indx));
+ Process (Cursor'(Container'Unrestricted_Access, Indx));
end loop;
exception
when others =>
@@ -3061,7 +3088,7 @@
if Index not in Index_Type'First .. Container.Last then
return No_Element;
else
- return (Container'Unchecked_Access, Index);
+ return (Container'Unrestricted_Access, Index);
end if;
end To_Cursor;
===================================================================
@@ -410,7 +410,7 @@
Lock : Natural := 0;
end record;
- type Vector_Access is access constant Vector;
+ type Vector_Access is access all Vector;
for Vector_Access'Storage_Size use 0;
type Cursor is record
===================================================================
@@ -27,16 +27,20 @@
-- This unit was originally developed by Matthew J Heaney. --
------------------------------------------------------------------------------
-with System; use type System.Address;
+with Ada.Finalization; use Ada.Finalization;
+with System; use type System.Address;
package body Ada.Containers.Bounded_Doubly_Linked_Lists is
- type Iterator is limited new
- List_Iterator_Interfaces.Reversible_Iterator with record
- Container : List_Access;
- Node : Count_Type;
+ type Iterator is new Limited_Controlled and
+ List_Iterator_Interfaces.Reversible_Iterator with
+ record
+ Container : List_Access;
+ Node : Count_Type;
end record;
+ overriding procedure Finalize (Object : in out Iterator);
+
overriding function First (Object : Iterator) return Cursor;
overriding function Last (Object : Iterator) return Cursor;
@@ -494,6 +498,22 @@
return Position.Container.Nodes (Position.Node).Element;
end Element;
+ --------------
+ -- Finalize --
+ --------------
+
+ procedure Finalize (Object : in out Iterator) is
+ begin
+ if Object.Container /= null then
+ declare
+ B : Natural renames Object.Container.all.Busy;
+
+ begin
+ B := B - 1;
+ end;
+ end if;
+ end Finalize;
+
----------
-- Find --
----------
@@ -1064,9 +1084,7 @@
(Container : List;
Process : not null access procedure (Position : Cursor))
is
- C : List renames Container'Unrestricted_Access.all;
- B : Natural renames C.Busy;
-
+ B : Natural renames Container'Unrestricted_Access.all.Busy;
Node : Count_Type := Container.First;
begin
@@ -1091,6 +1109,8 @@
(Container : List)
return List_Iterator_Interfaces.Reversible_Iterator'Class
is
+ B : Natural renames Container'Unrestricted_Access.all.Busy;
+
begin
-- The value of the Node component influences the behavior of the First
-- and Last selector functions of the iterator object. When the Node
@@ -1102,7 +1122,13 @@
-- Note: For a forward iterator, Container.First is the beginning, and
-- for a reverse iterator, Container.Last is the beginning.
- return Iterator'(Container'Unrestricted_Access, Node => 0);
+ return It : constant Iterator :=
+ Iterator'(Limited_Controlled with
+ Container => Container'Unrestricted_Access,
+ Node => 0)
+ do
+ B := B + 1;
+ end return;
end Iterate;
function Iterate
@@ -1110,6 +1136,8 @@
Start : Cursor)
return List_Iterator_Interfaces.Reversible_Iterator'class
is
+ B : Natural renames Container'Unrestricted_Access.all.Busy;
+
begin
-- It was formerly the case that when Start = No_Element, the partial
-- iterator was defined to behave the same as for a complete iterator,
@@ -1143,7 +1171,13 @@
-- the start position has the same value irrespective of whether this
-- is a forward or reverse iteration.
- return Iterator'(Container'Unrestricted_Access, Node => Start.Node);
+ return It : constant Iterator :=
+ Iterator'(Limited_Controlled with
+ Container => Container'Unrestricted_Access,
+ Node => Start.Node)
+ do
+ B := B + 1;
+ end return;
end Iterate;
----------
===================================================================
@@ -27,30 +27,38 @@
-- This unit was originally developed by Matthew J Heaney. --
------------------------------------------------------------------------------
-with System; use type System.Address;
+with Ada.Finalization; use Ada.Finalization;
+with System; use type System.Address;
+
package body Ada.Containers.Bounded_Multiway_Trees is
No_Node : constant Count_Type'Base := -1;
- type Iterator is new Tree_Iterator_Interfaces.Forward_Iterator with
+ type Iterator is new Limited_Controlled and
+ Tree_Iterator_Interfaces.Forward_Iterator with
record
Container : Tree_Access;
Position : Cursor;
From_Root : Boolean;
end record;
+ overriding procedure Finalize (Object : in out Iterator);
+
overriding function First (Object : Iterator) return Cursor;
overriding function Next
(Object : Iterator;
Position : Cursor) return Cursor;
- type Child_Iterator is new Tree_Iterator_Interfaces.Reversible_Iterator with
+ type Child_Iterator is new Limited_Controlled and
+ Tree_Iterator_Interfaces.Reversible_Iterator with
record
Container : Tree_Access;
Position : Cursor;
end record;
+ overriding procedure Finalize (Object : in out Child_Iterator);
+
overriding function First (Object : Child_Iterator) return Cursor;
overriding function Next
@@ -1229,6 +1237,34 @@
Right_Subtree => Right_Subtree);
end Equal_Subtree;
+ --------------
+ -- Finalize --
+ --------------
+
+ procedure Finalize (Object : in out Iterator) is
+ begin
+ if Object.Container /= null then
+ declare
+ B : Natural renames Object.Container.all.Busy;
+
+ begin
+ B := B - 1;
+ end;
+ end if;
+ end Finalize;
+
+ procedure Finalize (Object : in out Child_Iterator) is
+ begin
+ if Object.Container /= null then
+ declare
+ B : Natural renames Object.Container.all.Busy;
+
+ begin
+ B := B - 1;
+ end;
+ end if;
+ end Finalize;
+
----------
-- Find --
----------
@@ -1732,8 +1768,7 @@
(Container : Tree;
Process : not null access procedure (Position : Cursor))
is
- T : Tree renames Container'Unrestricted_Access.all;
- B : Integer renames T.Busy;
+ B : Natural renames Container'Unrestricted_Access.all.Busy;
begin
if Container.Count = 0 then
@@ -1758,13 +1793,19 @@
function Iterate (Container : Tree)
return Tree_Iterator_Interfaces.Forward_Iterator'Class
is
- Root_Cursor : constant Cursor :=
- (Container'Unrestricted_Access, Root_Node (Container));
+ B : Natural renames Container'Unrestricted_Access.all.Busy;
+ RC : constant Cursor :=
+ (Container'Unrestricted_Access, Root_Node (Container));
+
begin
- return
- Iterator'(Container'Unrestricted_Access,
- First_Child (Root_Cursor),
- From_Root => True);
+ return It : constant Iterator :=
+ Iterator'(Limited_Controlled with
+ Container => Container'Unrestricted_Access,
+ Position => First_Child (RC),
+ From_Root => True)
+ do
+ B := B + 1;
+ end return;
end Iterate;
----------------------
@@ -1786,9 +1827,9 @@
end if;
declare
+ B : Natural renames Parent.Container.Busy;
+ C : Count_Type;
NN : Tree_Node_Array renames Parent.Container.Nodes;
- B : Integer renames Parent.Container.Busy;
- C : Count_Type;
begin
B := B + 1;
@@ -1836,9 +1877,16 @@
Parent : Cursor)
return Tree_Iterator_Interfaces.Reversible_Iterator'Class
is
- pragma Unreferenced (Container);
+ B : Natural renames Container'Unrestricted_Access.all.Busy;
+
begin
- return Child_Iterator'(Parent.Container, Parent);
+ return It : constant Child_Iterator :=
+ Child_Iterator'(Limited_Controlled with
+ Container => Parent.Container,
+ Position => Parent)
+ do
+ B := B + 1;
+ end return;
end Iterate_Children;
---------------------
@@ -1849,8 +1897,17 @@
(Position : Cursor)
return Tree_Iterator_Interfaces.Forward_Iterator'Class
is
+ B : Natural renames Position.Container.all.Busy;
+
begin
- return Iterator'(Position.Container, Position, From_Root => False);
+ return It : constant Iterator :=
+ Iterator'(Limited_Controlled with
+ Container => Position.Container,
+ Position => Position,
+ From_Root => False)
+ do
+ B := B + 1;
+ end return;
end Iterate_Subtree;
procedure Iterate_Subtree
@@ -1869,7 +1926,7 @@
declare
T : Tree renames Position.Container.all;
- B : Integer renames T.Busy;
+ B : Natural renames T.Busy;
begin
B := B + 1;
@@ -2259,8 +2316,8 @@
declare
T : Tree renames Position.Container.all'Unrestricted_Access.all;
- B : Integer renames T.Busy;
- L : Integer renames T.Lock;
+ B : Natural renames T.Busy;
+ L : Natural renames T.Lock;
begin
B := B + 1;
@@ -2529,7 +2586,7 @@
declare
NN : Tree_Node_Array renames Parent.Container.Nodes;
- B : Integer renames Parent.Container.Busy;
+ B : Natural renames Parent.Container.Busy;
C : Count_Type;
begin
@@ -3209,8 +3266,8 @@
declare
T : Tree renames Position.Container.all'Unrestricted_Access.all;
- B : Integer renames T.Busy;
- L : Integer renames T.Lock;
+ B : Natural renames T.Busy;
+ L : Natural renames T.Lock;
begin
B := B + 1;
===================================================================
@@ -34,15 +34,20 @@
pragma Elaborate_All (Ada.Containers.Hash_Tables.Generic_Bounded_Keys);
with Ada.Containers.Prime_Numbers; use Ada.Containers.Prime_Numbers;
+with Ada.Finalization; use Ada.Finalization;
with System; use type System.Address;
package body Ada.Containers.Bounded_Hashed_Sets is
- type Iterator is new Set_Iterator_Interfaces.Forward_Iterator with record
+ type Iterator is new Limited_Controlled and
+ Set_Iterator_Interfaces.Forward_Iterator with
+ record
Container : Set_Access;
end record;
+ overriding procedure Finalize (Object : in out Iterator);
+
overriding function First (Object : Iterator) return Cursor;
overriding function Next
@@ -569,6 +574,22 @@
HT_Ops.Free (Container, X);
end Exclude;
+ --------------
+ -- Finalize --
+ --------------
+
+ procedure Finalize (Object : in out Iterator) is
+ begin
+ if Object.Container /= null then
+ declare
+ B : Natural renames Object.Container.all.Busy;
+
+ begin
+ B := B - 1;
+ end;
+ end if;
+ end Finalize;
+
----------
-- Find --
----------
@@ -887,7 +908,7 @@
Process (Cursor'(Container'Unrestricted_Access, Node));
end Process_Node;
- B : Natural renames Container'Unrestricted_Access.Busy;
+ B : Natural renames Container'Unrestricted_Access.all.Busy;
-- Start of processing for Iterate
@@ -906,9 +927,16 @@
end Iterate;
function Iterate (Container : Set)
- return Set_Iterator_Interfaces.Forward_Iterator'Class is
+ return Set_Iterator_Interfaces.Forward_Iterator'Class
+ is
+ B : Natural renames Container'Unrestricted_Access.all.Busy;
+
begin
- return Iterator'(Container => Container'Unrestricted_Access);
+ B := B + 1;
+
+ return It : constant Iterator :=
+ Iterator'(Limited_Controlled with
+ Container => Container'Unrestricted_Access);
end Iterate;
------------
@@ -1600,7 +1628,7 @@
begin
if Node = 0 then
- raise Constraint_Error with "key not in map"; -- ??? "set"
+ raise Constraint_Error with "key not in map"; -- ??? "set"
end if;
return Container.Nodes (Node).Element;