CVS difference for ai12s/ai12-0112-1.txt

Differences between 1.4 and version 1.5
Log of other versions for file ai12s/ai12-0112-1.txt

--- ai12s/ai12-0112-1.txt	2018/03/02 02:14:10	1.4
+++ ai12s/ai12-0112-1.txt	2018/03/30 05:52:07	1.5
@@ -1,4 +1,4 @@
-!standard A.18.2(99/3)                                18-03-01    AI12-0112-1/02
+!standard A.18.2(99/3)                                18-03-29    AI12-0112-1/03
 !class Amendment 14-05-15
 !status work item 14-05-15
 !status received 15-02-11
@@ -83,8 +83,9 @@
 (4) I've overridden the usual Nonblocking and Global status for the various
 predicate routines, to essentially mark these as Pure. If Nonblocking => True
 is used, this would prevent calling the formal subprograms in the associated
-routines. Can anyone think of a reason NOT to require these routines to be
-pure (in general or specifically)?
+routines. But that shouldn't be necessary to implement these (they usually
+are direct queries on the container state). Can anyone think of a reason NOT
+to require these routines to be pure (in general or specifically)?
 
 (5) The global setting "Access subtype_mark" says that it applies to all of
 the "(aliased)" objects of subtype_mark. For a tagged type (like Vector), it
@@ -149,8 +150,9 @@
    with Preelaborate, Remote_Types,
         Nonblocking => Equal_Element'Nonblocking,
         Global => Equal_Element'Global &
-                  in out Ada.Containers.Vectors &
-                  <<some impl-defed helper packages>> is
+                  Element_Type'Global &
+                  in out synchronized Ada.Containers.Vectors &
+                  in out synchronized <<some impl-defed helper packages>> is
 
 [These are the default Nonblocking and Global settings; they're used unless
 otherwise  specified. Note that these depend on the formal parameters of the
@@ -169,8 +171,11 @@
            Variable_Indexing => Reference,
            Default_Iterator  => Iterate,
            Iterator_Element  => Element_Type,
-           Stable_Properties => Length, Capacity, Tampering_With_Cursors_Prohibited,
-                                Tampering_With_Elements_Prohibited;
+           Stable_Properties => (Length, Capacity, Tampering_With_Cursors_Prohibited,
+                                 Tampering_With_Elements_Prohibited),
+           Default_Initial_Condition => Length(Vector) = 0 and then
+                                        (not Tampering_With_Cursors_Prohibited(Vector)) and then
+                                        (not Tampering_With_Elements_Prohibited(Vector));
    pragma Preelaborable_Initialization(Vector);
 
    type Cursor is private;
@@ -204,7 +209,7 @@
 New
 function Has_Element (Container : Vector; Position : Cursor) return Boolean
    with Nonblocking => True,
-        Global => in out null;
+        Global => null;
 New
 Returns True if Position designates an element in Container, and returns False
 otherwise.
@@ -228,7 +233,7 @@
 New
 function Tampering_With_Cursors_Prohibited (Container : Vector) return Boolean
    with Nonblocking => True,
-        Global => in out null;
+        Global => null;
 New
 Returns True if tampering with cursors or tampering with elements is currently
 prohibited for Container, and returns False otherwise.
@@ -238,7 +243,7 @@
 New
 function Tampering_With_Elements_Prohibited (Container : Vector) return Boolean
    with Nonblocking => True,
-        Global => in out null;
+        Global => null;
 New
 Returns True if tampering with elements is currently prohibited for Container,
 and returns False otherwise.
@@ -307,7 +312,7 @@
 112/2
 function Capacity (Container : Vector) return Count_Type
    with Nonblocking => True,
-        Global => in out null;
+        Global => null;
 113/2
 Returns the capacity of Container.
 
@@ -328,7 +333,7 @@
 116/2
 function Length (Container : Vector) return Count_Type
    with Nonblocking => True,
-        Global => in out null;
+        Global => null;
 117/2
 Returns the number of elements in Container.
 
@@ -348,7 +353,7 @@
 120/2
 function Is_Empty (Container : Vector) return Boolean
    with Nonblocking => True,
-        Global => in out null;
+        Global => null;
 121/2
 Equivalent to Length (Container) = 0.
 
@@ -404,7 +409,8 @@
    return Element_Type
    with Pre  => (if Index not in First_Index (Container) .. Last_Index (Container)
                        then raise Constraint_Error),
-        Nonblocking => True;
+        Nonblocking => True,
+        Global => Element_Type'Global;
 
 129/2+
 Element returns the element at position Index.
@@ -413,7 +419,7 @@
 function Element (Position  : Cursor) return Element_Type
    with Pre  => (if Position = No_Element then raise Constraint_Error),
         Nonblocking => True,
-        Global => Vectors'Global & in access Vector;
+        Global => Element_Type'Global & in access Vector;
 131/2+
 Element returns the element designated by Position.
 
@@ -422,7 +428,8 @@
    with Pre => (if Position = No_Element then raise Constraint_Error) and then
                (if not Has_Element (Container, Position)
                 then raise Program_Error),
-        Nonblocking => True;
+        Nonblocking => True,
+        Global => Element_Type'Global;
 New
 Element returns the element designated by Position.
 
@@ -467,7 +474,8 @@
    Index     : in Index_Type;
    Process   : not null access procedure (Element : in Element_Type))
    with Pre  => (if Index not in First_Index (Container) .. Last_Index (Container)
-                 then raise Constraint_Error);
+                 then raise Constraint_Error).
+        Global => Element_Type'Global;
 
 [Tampering ought to be indicated for the access procedure here, but we don't
 have a mechanism to do that. See the questions above.]
@@ -482,12 +490,28 @@
   (Position : in Cursor;
    Process  : not null access procedure (Element : in Element_Type))
    with Pre  => (if Position = No_Element then raise Constraint_Error);
+        Global => Element_Type'Global & in access Vector; 
 139/3+
 Query_Element calls Process.all with the element designated by Position as the
 argument. Tampering with the elements of the vector that contains the element
 designated by Position is prohibited during the execution of the call on
 Process.all. Any exception raised by Process.all is propagated.
 
+New
+procedure Query_Element
+  (Container : in Vector;
+   Position  : in Cursor;
+   Process   : not null access procedure (Element : in Element_Type))
+   with Pre  => (if Position = No_Element then raise Constraint_Error) or else
+                (not Has_Element (Container, Position) then raise Program_Error)
+        Global => Element_Type'Global;
+
+New
+Query_Element calls Process.all with the element designated by Position as the
+argument. Tampering with the elements of the vector that contains the element
+designated by Position is prohibited during the execution of the call on
+Process.all. Any exception raised by Process.all is propagated.
+
 140/2+
 procedure Update_Element
   (Container : in out Vector;
@@ -530,25 +554,27 @@
 The element designated by Position is not an empty element after successful
 completion of this operation.
 
-147.1/3
+147.1/3+
 type Constant_Reference_Type
       (Element : not null access constant Element_Type) is private
-   with Implicit_Dereference => Element;
+   with Implicit_Dereference => Element,
+        Default_Initial_Condition => (raise Program_Error);
 147.2/3
 type Reference_Type (Element : not null access Element_Type) is private
-   with Implicit_Dereference => Element;
+   with Implicit_Dereference => Element,
+        Default_Initial_Condition => (raise Program_Error);
 147.3/3
 The types Constant_Reference_Type and Reference_Type need finalization.
-147.4/3
-The default initialization of an object of type Constant_Reference_Type or
-Reference_Type propagates Program_Error.
+147.4/3+
+<<This paragraph is deleted>>
 
 147.5/3+
 function Constant_Reference (Container : aliased in Vector;
                              Index     : in Index_Type)
    return Constant_Reference_Type
    with Pre  => (if Index not in First_Index (Container) .. Last_Index (Container)
-                       then raise Constraint_Error);
+                       then raise Constraint_Error),
+        Global => null;
 147.6/3
 This function (combined with the Constant_Indexing and Implicit_Dereference
 aspects) provides a convenient way to gain read access to an individual element
@@ -584,7 +610,8 @@
    return Constant_Reference_Type
    with Pre => (if Position = No_Element then raise Constraint_Error) and then
                (if not Has_Element (Container, Position)
-                then raise Program_Error);
+                then raise Program_Error),
+        Global => null;
 147.13/3
 This function (combined with the Constant_Indexing and Implicit_Dereference
 aspects) provides a convenient way to gain read access to an individual element
@@ -988,7 +1015,7 @@
 195/2
 function First_Index (Container : Vector) return Index_Type is
    with Nonblocking => True,
-        Global => in out null,
+        Global => null,
         Post => First_Index'Result = Index_Type'First;
 196/2
 Returns the value Index_Type'First.
@@ -1011,7 +1038,7 @@
 201/2
 function Last_Index (Container : Vector) return Extended_Index
    with Nonblocking => True,
-        Global => in out null,
+        Global => null,
         Post => (if Length (Container) = 0 then Last_Index'Result = No_Index
                  else Last_Index'Result = Length (Container) - 1 + Index_Type'First);
 202/2
@@ -1054,7 +1081,7 @@
                  elsif Has_Element (Container, Next'Result) then True
                  else Next'Result = No_Element and then
                       Position'Old = Last (Container)),
-        Global => in out null,
+        Global => null,
         Nonblocking => True;
 New
 If Position equals No_Element or designates the last element of Container,
@@ -1076,7 +1103,7 @@
                  then raise Program_Error),
         Post => (if Position /= No_Element
                  then Has_Element (Container, Position)),
-        Global => in out null,
+        Global => null,
         Nonblocking => True;
 New
 Equivalent to Position := Next (Position).
@@ -1102,7 +1129,7 @@
                  elsif Has_Element (Container, Previous'Result) then True
                  else Previous'Result = No_Element and then
                       Position'Old = First (Container)),
-        Global => in out null,
+        Global => null,
         Nonblocking => True;
 New
 If Position equals No_Element or designates the first element of the container,
@@ -1124,7 +1151,7 @@
                  then raise Program_Error),
         Post => (if Position /= No_Element
                  then Has_Element (Container, Position)),
-        Global => in out null,
+        Global => null,
         Nonblocking => True;
 New
 Equivalent to Position := Previous (Position).
@@ -1312,10 +1339,12 @@
 Add after A.18.19(3/3):
 
 * The Global aspect of the package is replaced by 
-      Global => in out null,
+      Global => Equal_Element'Global &
+                Element_Type'Global,
 
 AARM Reason: This package is pure, and thus it cannot have or depend upon any
-other packages that have state. Thus we require no global uses whatsoever.
+other packages that have state. Thus we require no global uses whatsoever
+other than those of the formals.
 
 Add after A.18.19(6/3):
 
@@ -1364,6 +1393,183 @@
 
 -----------------------------------------
 
+A.18.18 The Generic Package Containers.Indefinite_Holders
+
+The generic library package Containers.Indefinite_Holders has the following declaration: 
+
+5/3+ generic
+   type Element_Type (<>) is private;
+   with function "=" (Left, Right : Element_Type) return Boolean is <>;
+package Ada.Containers.Indefinite_Holders
+   with Preelaborate, Remote_Types,
+        Nonblocking => Equal_Element'Nonblocking,
+        Global => Equal_Element'Global &
+                  Element_Type'Global &
+                  in out synchronized Ada.Containers.Indefinite_Holders &
+                  in out synchronized <<some impl-defed helper packages>> is
+
+6/3+
+   type Holder is tagged private
+      with Stable_Properties => (Is_Empty, Tampering_With_The_Element_Prohibited),
+           Default_Initial_Condition => Is_Empty (Holder);
+
+   pragma Preelaborable_Initialization (Holder);
+
+7/3Empty_Holder : constant Holder;
+   
+New
+   function Equal_Element (Left, Right : Element_Type) return Boolean
+      renames "=";
+
+[Same from here to start of specifications.
+
+36/3 function "=" (Left, Right : Holder) return Boolean;
+37/3
+   If Left and Right denote the same holder object, then the function returns True.
+   Otherwise, it compares the element contained in Left to the element contained in
+   Right using the generic formal equality operator, returning the result of that
+   operation. Any exception raised during the evaluation of element equality is
+   propagated.
+
+New
+function Tampering_With_The_Element_Prohibited (Container : Holder) return Boolean
+   with Nonblocking => True,
+        Global => null;
+New
+Returns True if tampering with the element is currently prohibited for Container,
+and returns False otherwise.
+
+38/3+
+function To_Holder (New_Item : Element_Type) return Holder
+    with Post => not Is_Empty (To_Holder'Result);
+39/4
+   Returns a nonempty holder containing an element initialized to New_Item.
+   To_Holder performs indefinite insertion (see A.18).
+
+40/3+
+function Is_Empty (Container : Holder) return Boolean
+    with Global => null;
+41/3
+    Returns True if Container is empty, and False if it contains an element.
+
+42/3+
+procedure Clear (Container : in out Holder)
+   with Pre  => (if Tampering_With_The_Element_Prohibited (Container)
+                 then raise Program_Error),
+        Post => Is_Empty (Container);
+43/3+
+   Removes the element from Container.
+
+44/3+
+function Element (Container : Holder) return Element_Type
+   with Pre => (if Is_Empty(Container) then raise Constraint_Error),
+        Global => Element_Type'Global;
+45/3+
+    Returns the element stored in Container.
+
+46/3+
+procedure Replace_Element (Container : in out Holder;
+                           New_Item  : in     Element_Type)
+   with Pre  => (if Tampering_With_The_Element_Prohibited (Container)
+                 then raise Program_Error),
+        Post => not Is_Empty (Container);
+47/4+
+    Replace_Element assigns the value New_Item into Container, replacing any
+    preexisting content of Container; Replace_Element performs indefinite
+    insertion (see A.18).
+
+48/3+
+procedure Query_Element
+  (Container : in Holder;
+   Process   : not null access procedure (Element : in Element_Type))
+   with Pre => (if Is_Empty (Container) then raise Constraint_Error),
+        Global => null;
+49/3+
+   Query_Element calls Process.all with the contained element as the argument.
+   Tampering with the element of Container is prohibited during the execution
+   of the call on Process.all. Any exception raised by Process.all is
+   propagated.
+
+50/3+
+procedure Update_Element
+  (Container : in out Holder;
+   Process   : not null access procedure (Element : in out Element_Type))
+   with Pre => (if Is_Empty (Container) then raise Constraint_Error);
+51/3+
+    Update_Element calls Process.all with the contained element as the
+    argument. Tampering with the element of Container is prohibited during
+    the execution of the call on Process.all. Any exception raised by
+    Process.all is propagated.
+
+52/3+
+type Constant_Reference_Type
+      (Element : not null access constant Element_Type) is private
+   with Implicit_Dereference => Element,
+        Default_Initial_Condition => (raise Program_Error);
+53/3+
+type Reference_Type (Element : not null access Element_Type) is private
+   with Implicit_Dereference => Element,
+        Default_Initial_Condition => (raise Program_Error);
+54/3
+   The types Constant_Reference_Type and Reference_Type need finalization.
+55/3+
+   <<This paragraph is deleted>>
+
+56/3+
+function Constant_Reference (Container : aliased in Holder)
+   return Constant_Reference_Type
+   with Pre => (if Is_Empty (Container) then raise Constraint_Error);
+57/3
+   This function (combined with the Implicit_Dereference aspect) provides a
+   convenient way to gain read access to the contained element of a holder
+   container.
+58/3+
+   Constant_Reference returns an object whose discriminant is an access value
+   that designates the contained element. Tampering with the elements of
+   Container is prohibited while the object returned by Constant_Reference
+   exists and has not been finalized.
+
+59/3+
+function Reference (Container : aliased in out Holder) return Reference_Type
+   with Pre => (if Is_Empty (Container) then raise Constraint_Error);
+60/3
+   This function (combined with the Implicit_Dereference aspects) provides
+   a convenient way to gain read and write access to the contained element
+   of a holder container.
+61/3+
+   Reference returns an object whose discriminant is an access value that 
+   designates the contained element. Tampering with the elements of Container
+   is prohibited while the object returned by Reference exists and has not
+   been finalized.
+
+62/3+
+procedure Assign (Target : in out Holder; Source : in Holder)
+   with Post => (Is_Empty (Source) = Is_Empty (Target));
+63/3
+   If Target denotes the same object as Source, the operation has no effect.
+   If Source is empty, Clear (Target) is called. Otherwise, Replace_Element
+   (Target, Element (Source)) is called. 
+
+64/3+
+function Copy (Source : Holder) return Holder
+    with Post => Is_Empty (Source) = Is_Empty (Copy'Result);
+65/3
+    If Source is empty, returns an empty holder container; otherwise, returns
+    To_Holder (Element (Source)).
+
+66/3+
+procedure Move (Target : in out Holder; Source : in out Holder)
+   with Pre  => (if Tampering_With_The_Element_Prohibited (Container)
+                 then raise Program_Error),
+        Post => (if Target /= Source then
+                    Is_Empty (Source) and then (not Is_Empty (Target));
+
+67/3+
+    If Target denotes the same object as Source, then the operation has no
+    effect. Otherwise, the element contained by Source (if any) is removed
+    from Source and inserted into Target, replacing any preexisting content.
+
+-----------------------------------------
 
 Add after 11.5(23):
 
@@ -1402,10 +1608,10 @@
 !discussion
 
 For this version, we've prototyped the changes needed for a single
-package (Ada.Containers.Vectors) and the bounded and indefinite versions thereof.
-Additional changes will be needed if AI12-0111-1 is approved. [Editor's note:
-I would want to apply both of these AIs together, since the changes needed are
-interrelated.]
+container (Ada.Containers.Vectors) and the bounded and indefinite versions
+thereof, along with the indefinite holders. Additional changes will be needed
+if AI12-0111-1 is approved. [Editor's note: I would want to apply both of
+these AIs together, since the changes needed are interrelated.]
 
 This version only shows the wording for the main body of the definition
 of Ada.Containers.Vectors and the start of the package specification. The rest
@@ -1425,7 +1631,8 @@
 were dropped, especially "otherwise", which should improve readability.)
 
 There are a few cases where I was able to drop wording when it was specified
-by the postcondition (mostly where the length or capacity was specified). This
+by the postcondition (mostly where the length or capacity was specified) or
+the default initial conditions (for the various reference types). This
 follows the policy we adopted earlier when working on the random number
 package.
 
@@ -1449,20 +1656,20 @@
 evaluated to False or raised an exception. (It would be nice to say this is
 just unspecified, with the intent of allowing anything Ada-related to happen,
 but not allow overwriting memory or the like, but that's a hard concept to
-define.)
+define - and it's unclear how that would apply to a non-Ada implementation.)
 
 I would have preferred to have this as a global setting for the entire Ada
 library, but Precondition_Check seems to imply this covers *any* precondition
 (which it doesn't). The "correct" name is
 Language_Defined_Unit_Precondition_Check, which I think the Ada community
-would clobber us for using.
+would clobber us for using (and probably me for even proposing it ;-).
 
 Therefore, I hit on the idea of naming the check for the first level
 "grouping" package. Thus, the check names would be Container_Check (as used
 here), Numerics_Check (for Ada.Numerics), Strings_Check (for Ada.Strings),
-IO_Check (for the missing Ada.IO package; the packages would have to be
-listed), and so on. This provides a bit more granularity (although that only
-matters if we define many more routines with preconditions).
+IO_Check (for the missing Ada.IO package; the packages involved would have to
+be listed), and so on. This provides a bit more granularity (although that
+only matters if we define many more routines with preconditions).
 
 !ASIS
 

Questions? Ask the ACAA Technical Agent