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

Differences between 1.14 and version 1.15
Log of other versions for file ai12s/ai12-0111-1.txt

--- ai12s/ai12-0111-1.txt	2017/08/12 02:48:59	1.14
+++ ai12s/ai12-0111-1.txt	2017/10/12 03:13:15	1.15
@@ -1,11 +1,11 @@
-!standard A.18.2(97.1/3)                              17-06-12  AI12-0111-1/05
+!standard A.18.2(97.1/3)                              17-10-11  AI12-0111-1/06
 !class Amendment 16-06-06
 !status work item 14-05-15
 !status received 14-02-08
 !priority Medium
 !difficulty Hard
 !qualifier Omission
-!subject Tampering considered too expensive
+!subject Stable Containers to reduce tampering checks
 !summary
 
 Add a nested package Stable within each Container package, which
@@ -64,6 +64,37 @@
 
 !wording
 
+Add after A.18(2/5):
+
+  Some operations of the language-defined child units of Ada.Containers
+  have access-to-subprogram parameters. To ensure such operations are
+  well-defined, they guard against certain actions by the designated
+  subprogram.  An action on a container that might add or remove an
+  element is considered to /tamper with cursors/, and these are
+  prohibited during all such operations.  For a container with elements
+  of an indefinite type, an action on a container that might replace an
+  element with one of a different size is considered to
+  /tamper with elements/, and these are prohibited during certain of such
+  operations. The details of the specific actions that are considered to
+  tamper with cursors or elements are defined for each child unit of
+  Ada.Containers.
+
+  Several of the language-defined child units of Ada.Containers include
+  a nested package named Stable, which provides a view of a container
+  that prohibits any operations that would tamper with cursors. For
+  containers whose elements are of an indefinite type, the Stable view
+  also prohibits operations that would tamper with elements.  By
+  using a Stable view for manipulating a container, the number of
+  tampering checks performed while performing the operations can
+  be reduced.  The details of the Stable subpackage are defined separately
+  for each child unit of Ada.Containers that includes such a nested
+  package.
+
+Delete A.18.2(90/2) (introduction to tampering -- now in A.18)
+
+  (also delete similar paragraphs elsewhere: A.18.3(61/2), A.18.4(7/2),
+   A.18.7(7/2), A.18.10(80/3))
+
 Modify A.18.2(92/2) (and similar paragraphs elsewhere):
 
   * it inserts or deletes elements of V, that is, it calls the Insert,
@@ -71,7 +102,9 @@
     procedure of an instance of Generic_Sorting,} with V as a parameter;
     or
 
-Delete A.18.2(95/2-97/2) talking about tampering with elements.
+Delete A.18.2(95/2-97/2) talking about tampering with elements
+  (also delete similar paragraphs elsewhere: A.18.3(67/2-69/2),
+   A.18.4(13/2-15/2), A.18.7(13/2-14/2), A.18.10(87/3-89/3))
 
 Modify A.18.2(97.1/4) as follows:
 
@@ -102,39 +135,8 @@
   These checks are made before any other defined behavior of the body of
   the language-defined subprogram.
 
-Insert new section after A.18.2 (or in a separate area at the end of
-A.18 to avoid using 4-component numbers):
-
-  A.18.2.1 The Nested Package Containers.Vectors.Stable
-
-   The nested package Vectors.Stable
-   provides a type Stable.Vector that represents
-   a /stable/ vector, which is one that cannot grow and shrink.  Such a
-   vector can be created by calling the To_Vector or Copy functions, or
-   by establishing a /stabilized view/ of a regular Vector. While a
-   stabilized view exists, no operations that tamper with cursors are
-   permitted on the underlying regular Vector.
+Insert after A.18.2(79/2):
 
-   The operations of this package are equivalent to those for regular
-   Vectors, except that no tampering checks are performed.  If a stable
-   vector is declared with the Base discriminant designating a
-   pre-existing regular vector, the stable vector represents a
-   stabilized view of the underlying regular vector, and any operation
-   on the stable vector is reflected on the underlying regular vector.
-   While a stabilized view exists, any operation that tampers with
-   cursors performed on the underlying vector is prohibited.  The
-   finalization of a stable vector that provides such a view removes
-   this restriction on the underlying regular vector Redundant[(though
-   some other restriction might exist due to other concurrent iterations
-   or stabilized views)].
-
-   If a stable vector is declared without specifying Base, the object must
-   be initialized. The initializing expression of
-   the stable vector, Redundant[typically a call on To_Vector or
-   Copy], determines the Length of the vector. By default the Length
-   is zero. The Length of a stable vector never changes after
-   initialization.
-
 [Author's note: Below, we have left in the original paragraph numbers
 from the Vector container because we thought they might be useful, and
 mostly because we are too lazy to remove them.]
@@ -349,75 +351,41 @@
 
 82/2    end Stable;
 
-     private
-        ...  --  not specified by the language
-     end Ada.Containers.Vectors;
-
-  Upon creation, an object of type Stable.Vector marks the vector
-  designated by the Base discriminant (the /base/ vector) to disallow
-  tampering with cursors as long as the stable view of the base vector
-  exists.
-
-  The operations of the Stable subpackage correspond to the operations
-  of the enclosing generic package Vectors that do not tamper with
-  cursors. For functions that create a new vector, such as To_Vector or
-  Copy, the Stable versions of these first create a base object of the
-  Vectors.Vector type, and then create a stable vector designating that
-  base object. [Redundant: If one of these functions is used to
-  initialize a stable vector object, the return object is built in
-  place.]  The other operations of the Stable subpackage perform the
-  corresponding operation on the vector designated by the Base
-  discriminant.
-
---------
-
-Delete A.18.3(67/2-69/2).
 
-Modify A.18.3(69.1/4) as follows:
+Insert the following at the end of A.18.2:
 
-  When tampering with cursors is prohibited for a particular list object
-  L, Program_Error is propagated by a call of any language-defined
-  subprogram that is defined to tamper with the cursors of L, leaving L
-  unmodified. [Similarly, when tampering with elements is prohibited for
-  a particular list object L, Program_Error is propagated by a call of
-  any language-defined subprogram that is defined to tamper with the
-  elements of L (or tamper with the cursors of L), leaving L unmodified.]
-  These checks are made before any other defined behavior of the body of
-  the language-defined subprogram.
-
-Insert new section after A.18.3 (or in a separate area at the end of
-A.18 to avoid using 4-component numbers):
-
-  A.18.3.1 The Nested Package Containers.Doubly_Linked_Lists.Stable
-
-   The nested package Doubly_Linked_Lists.Stable
-   provides a type Stable.List that represents
-   a /stable/ list, which is one that cannot grow and shrink.  Such a
-   list can be created by calling the To_Vector or Copy functions, or
+   The nested package Vectors.Stable
+   provides a type Stable.Vector that represents
+   a /stable/ vector, which is one that cannot grow and shrink.  Such a
+   vector can be created by calling the To_Vector or Copy functions, or
    by establishing a /stabilized view/ of a regular Vector. While a
    stabilized view exists, no operations that tamper with cursors are
    permitted on the underlying regular Vector.
 
    The operations of this package are equivalent to those for regular
-   Doubly_Linked_Lists, except that no tampering checks are performed.  If a stable
-   list is declared with the Base discriminant designating a
-   pre-existing regular list, the stable list represents a
-   stabilized view of the underlying regular list, and any operation
-   on the stable list is reflected on the underlying regular list.
+   Vectors, except that no tampering checks are performed.  If a stable
+   vector is declared with the Base discriminant designating a
+   pre-existing regular vector, the stable vector represents a
+   stabilized view of the underlying regular vector, and any operation
+   on the stable vector is reflected on the underlying regular vector.
    While a stabilized view exists, any operation that tampers with
-   cursors performed on the underlying list is prohibited.  The
-   finalization of a stable list that provides such a view removes
-   this restriction on the underlying regular list Redundant[(though
+   cursors performed on the underlying vector is prohibited.  The
+   finalization of a stable vector that provides such a view removes
+   this restriction on the underlying regular vector Redundant[(though
    some other restriction might exist due to other concurrent iterations
    or stabilized views)].
 
-   If a stable list is declared without specifying Base, the object must
+   If a stable vector is declared without specifying Base, the object must
    be initialized. The initializing expression of
-   the stable list, Redundant[typically a call on To_Vector or
-   Copy], determines the Length of the list. By default the Length
-   is zero. The Length of a stable list never changes after
+   the stable vector, Redundant[typically a call on To_Vector or
+   Copy], determines the Length of the vector. By default the Length
+   is zero. The Length of a stable vector never changes after
    initialization.
 
+--------
+
+Insert after A.18.3(51/2):
+
 [Author's note: Below, we have left in the original paragraph numbers
 from the Vector container because we thought they might be useful, and
 mostly because we are too lazy to remove them.]
@@ -566,27 +534,60 @@
      private
         ...  --  not specified by the language
      end Ada.Containers.Doubly_Linked_Lists;
+
+
+Delete A.18.3(67/2-69/2).
 
-  Upon creation, an object of type Stable.List marks the list designated
-  by the Base discriminant (the /base/ list) to disallow tampering with
-  cursors as long as the stable view of the base list exists.
-
-  The operations of the Stable subpackage correspond to the operations
-  of the enclosing generic package Doubly_Linked_Lists that do not
-  tamper with cursors. For functions that create a new list, such as
-  Copy, the Stable versions of these first create a base object of the
-  Doubly_Linked_Lists.List type, and then create a stable list
-  designating that base object. [Redundant: If one of these functions is
-  used to initialize a stable list object, the return object is built in
-  place.]  The other operations of the Stable subpackage perform the
-  corresponding operation on the list designated by the Base
-  discriminant.
+Modify A.18.3(69.1/4) as follows:
 
+  When tampering with cursors is prohibited for a particular list object
+  L, Program_Error is propagated by a call of any language-defined
+  subprogram that is defined to tamper with the cursors of L, leaving L
+  unmodified. [Similarly, when tampering with elements is prohibited for
+  a particular list object L, Program_Error is propagated by a call of
+  any language-defined subprogram that is defined to tamper with the
+  elements of L (or tamper with the cursors of L), leaving L unmodified.]
+  These checks are made before any other defined behavior of the body of
+  the language-defined subprogram.
+
+Insert new section at the end of A.18.3:
+
+   The nested package Doubly_Linked_Lists.Stable
+   provides a type Stable.List that represents
+   a /stable/ list, which is one that cannot grow and shrink.  Such a
+   list can be created by calling the To_Vector or Copy functions, or
+   by establishing a /stabilized view/ of a regular Vector. While a
+   stabilized view exists, no operations that tamper with cursors are
+   permitted on the underlying regular Vector.
+
+   The operations of this package are equivalent to those for regular
+   Doubly_Linked_Lists, except that no tampering checks are performed.
+   If a stable list is declared with the Base discriminant designating a
+   pre-existing regular list, the stable list represents a
+   stabilized view of the underlying regular list, and any operation
+   on the stable list is reflected on the underlying regular list.
+   While a stabilized view exists, any operation that tampers with
+   cursors performed on the underlying list is prohibited.  The
+   finalization of a stable list that provides such a view removes
+   this restriction on the underlying regular list Redundant[(though
+   some other restriction might exist due to other concurrent iterations
+   or stabilized views)].
+
+   If a stable list is declared without specifying Base, the object must
+   be initialized. The initializing expression of
+   the stable list, Redundant[typically a call on To_Vector or
+   Copy], determines the Length of the list. By default the Length
+   is zero. The Length of a stable list never changes after
+   initialization.
+
 -----
 
 
 In the section on Indefinite_Doubly_Linked_Lists, A.18.12, add after para 8/4:
 
+  * The operations Replace_Element and Swap are omitted from the Stable
+    subpackage.
+
   * A subprogram is said to tamper with elements of an indefinite
     list object L if:
 
@@ -617,6 +618,9 @@
 
 In the section on Indefinite_Multiway_Trees, add after A.18.17(8/4):
 
+  * The operations Replace_Element and Swap are omitted from the Stable
+    subpackage.
+
   * A subprogram is said to tamper with elements of a tree object T if:
 
      - it tampers with cursors of T; or
@@ -636,12 +640,141 @@
 In section A.18.4 on Maps, modify A.18.4(13/2) as follows:
   * A subprogram is said to tamper with elements of a map object M if {the
     formal Element_Type is indefinite (see A.18.13 and A.18.14), and}:
+
+Insert after A.18.5(38/2):
+
+[Author's note: Below, we have left in the original paragraph numbers
+from the Hashed_Maps container because we thought they might be useful, and
+mostly because we are too lazy to remove them.]
 
-Insert new section after A.18.5 (or in a separate area at the end of
-A.18 to avoid using 4-component numbers):
+package Stable is
 
-  A.18.5.1 The Nested Package Containers.Hashed_Maps.Stable
+3/3
+   type Map (Base : not null access Hashed_Maps.Map) is
+      tagged limited private
+      with Constant_Indexing => Constant_Reference,
+           Variable_Indexing => Reference,
+           Default_Iterator  => Iterate,
+           Iterator_Element  => Element_Type;
+4/2
+   type Cursor is private;
+   pragma Preelaborable_Initialization(Cursor);
+5/2
+   Empty_Map : constant Map;
+6/2
+   No_Element : constant Cursor;
+6.1/3
+   function Has_Element (Position : Cursor) return Boolean;
+6.2/3
+   package Map_Iterator_Interfaces is new
+       Ada.Iterator_Interfaces (Cursor, Has_Element);
+7/2
+   function "=" (Left, Right : Map) return Boolean;
+8/2
+   function Capacity (Container : Map) return Count_Type;
+9/2
+   procedure Reserve_Capacity (Container : in out Map;
+                               Capacity  : in     Count_Type);
+10/2
+   function Length (Container : Map) return Count_Type;
+11/2
+   function Is_Empty (Container : Map) return Boolean;
+12/2
+   procedure Clear (Container : in out Map);
+13/2
+   function Key (Position : Cursor) return Key_Type;
+14/2
+   function Element (Position : Cursor) return Element_Type;
+15/2
+   procedure Replace_Element (Container : in out Map;
+                              Position  : in     Cursor;
+                              New_Item  : in     Element_Type);
+16/2
+   procedure Query_Element
+     (Position : in Cursor;
+      Process  : not null access procedure (Key     : in Key_Type;
+                                            Element : in Element_Type));
+17/2
+   procedure Update_Element
+     (Container : in out Map;
+      Position  : in     Cursor;
+      Process   : not null access procedure
+                      (Key     : in     Key_Type;
+                       Element : in out Element_Type));
+17.1/3
+   type Constant_Reference_Type
+         (Element : not null access constant Element_Type) is private
+      with Implicit_Dereference => Element;
+17.2/3
+   type Reference_Type (Element : not null access Element_Type) is private
+      with Implicit_Dereference => Element;
+17.3/3
+   function Constant_Reference (Container : aliased in Map;
+                                Position  : in Cursor)
+      return Constant_Reference_Type;
+17.4/3
+   function Reference (Container : aliased in out Map;
+                       Position  : in Cursor)
+      return Reference_Type;
+17.5/3
+   function Constant_Reference (Container : aliased in Map;
+                                Key       : in Key_Type)
+      return Constant_Reference_Type;
+17.6/3
+   function Reference (Container : aliased in out Map;
+                       Key       : in Key_Type)
+      return Reference_Type;
+17.8/3
+   function Copy (Source : Map; Capacity : Count_Type := 0) return Map;
+
+   procedure Replace (Container : in out Map;
+                      Key       : in     Key_Type;
+                      New_Item  : in     Element_Type);
+27/2
+   function First (Container : Map)
+      return Cursor;
+28/2
+   function Next (Position  : Cursor) return Cursor;
+29/2
+   procedure Next (Position  : in out Cursor);
+30/2
+   function Find (Container : Map;
+                  Key       : Key_Type)
+      return Cursor;
+31/2
+   function Element (Container : Map;
+                     Key       : Key_Type)
+      return Element_Type;
+32/2
+   function Contains (Container : Map;
+                      Key       : Key_Type) return Boolean;
+34/2
+   function Equivalent_Keys (Left, Right : Cursor)
+      return Boolean;
+35/2
+   function Equivalent_Keys (Left  : Cursor;
+                             Right : Key_Type)
+      return Boolean;
+36/2
+   function Equivalent_Keys (Left  : Key_Type;
+                             Right : Cursor)
+      return Boolean;
+37/2
+   procedure Iterate
+     (Container : in Map;
+      Process   : not null access procedure (Position : in Cursor));
+37.1/3
+   function Iterate (Container : in Map)
+      return Map_Iterator_Interfaces.Forward_Iterator'Class;
+38/2
+private
+39/2
+   ... -- not specified by the language
+40/2
+end Stable;
 
+Insert at end of A.18.5:
+
    The nested package Hashed_Maps.Stable
    provides a type Stable.Map that represents
    a /stable/ map, which is one that cannot grow and shrink.  Such a
@@ -669,44 +802,162 @@
    Copy], determines the Length of the map. By default the Length
    is zero. The Length of a stable map never changes after
    initialization.
-
-   The Containers.Hashed_Maps.Stable subpackage is based on the Hashed_Maps
-   package, but with the following changes:
 
-     Type Map is declared as follows:
+----
 
-           type Map (Base : not null access Hashed_Maps.Map) is
-              tagged limited private
-              with Constant_Indexing => Constant_Reference,
-                   Variable_Indexing => Reference,
-                   Default_Iterator  => Iterate,
-                   Iterator_Element  => Element_Type;
-           pragma Preelaborable_Initialization(Map);
+Insert after A.18.6(51.2/3):
 
-     The operations Clear, Assign, Move, Insert, Include, Exclude, and Delete
-     are omitted.
+[Author's note: Below, we have left in the original paragraph numbers
+from the Ordered_Maps container because we thought they might be useful, and
+mostly because we are too lazy to remove them.]
 
-     Upon creation, an object of type Stable.Map marks the map
-     designated by the Base discriminant (the /base/ map) to disallow
-     tampering with cursors as long as the stable view of the base map
-     exists.
-
-     The operations of the Stable subpackage correspond to the
-     operations of the enclosing generic package Hashed_Maps
-     that do not tamper with cursors. For functions that create a new
-     list, such as Copy, the Stable versions of these first create a
-     base object of the Hashed_Maps.Map type, and then create a
-     stable map designating that base object. [Redundant: If one of
-     these functions is used to initialize a stable map object, the
-     return object is built in place.]  The other operations of the
-     Stable subpackage perform the corresponding operation on the map
-     designated by the Base discriminant.
+package Stable is
 
-----
-Insert new section after A.18.6 (or in a separate area at the end of
-A.18 to avoid using 4-component numbers):
+   function Equivalent_Keys (Left, Right : Key_Type) return Boolean;
+4/3
+   type Map (Base : not null access Ordered_Maps.Map) is
+      is tagged limited private
+      with Constant_Indexing => Constant_Reference,
+           Variable_Indexing => Reference,
+           Default_Iterator  => Iterate,
+           Iterator_Element  => Element_Type;
+5/2
+   type Cursor is private;
+   pragma Preelaborable_Initialization(Cursor);
+6/2
+   Empty_Map : constant Map;
+7/2
+   No_Element : constant Cursor;
+7.1/3
+   function Has_Element (Position : Cursor) return Boolean;
+7.2/3
+   package Map_Iterator_Interfaces is new
+       Ada.Iterator_Interfaces (Cursor, Has_Element);
+8/2
+   function "=" (Left, Right : Map) return Boolean;
+9/2
+   function Length (Container : Map) return Count_Type;
+10/2
+   function Is_Empty (Container : Map) return Boolean;
+12/2
+   function Key (Position : Cursor) return Key_Type;
+13/2
+   function Element (Position : Cursor) return Element_Type;
+14/2
+   procedure Replace_Element (Container : in out Map;
+                              Position  : in     Cursor;
+                              New_Item  : in     Element_Type);
+15/2
+   procedure Query_Element
+     (Position : in Cursor;
+      Process  : not null access procedure (Key     : in Key_Type;
+                                            Element : in Element_Type));
+16/2
+   procedure Update_Element
+     (Container : in out Map;
+      Position  : in     Cursor;
+      Process   : not null access procedure
+                      (Key     : in     Key_Type;
+                       Element : in out Element_Type));
+16.1/3
+   type Constant_Reference_Type
+         (Element : not null access constant Element_Type) is private
+      with Implicit_Dereference => Element;
+16.2/3
+   type Reference_Type (Element : not null access Element_Type) is private
+      with Implicit_Dereference => Element;
+16.3/3
+   function Constant_Reference (Container : aliased in Map;
+                                Position  : in Cursor)
+      return Constant_Reference_Type;
+16.4/3
+   function Reference (Container : aliased in out Map;
+                       Position  : in Cursor)
+      return Reference_Type;
+16.5/3
+   function Constant_Reference (Container : aliased in Map;
+                                Key       : in Key_Type)
+      return Constant_Reference_Type;
+16.6/3
+   function Reference (Container : aliased in out Map;
+                       Key       : in Key_Type)
+      return Reference_Type;
+16.8/3
+   function Copy (Source : Map) return Map;
+22/2
+   procedure Replace (Container : in out Map;
+                      Key       : in     Key_Type;
+                      New_Item  : in     Element_Type);
+28/2
+   function First (Container : Map) return Cursor;
+29/2
+   function First_Element (Container : Map) return Element_Type;
+30/2
+   function First_Key (Container : Map) return Key_Type;
+31/2
+   function Last (Container : Map) return Cursor;
+32/2
+   function Last_Element (Container : Map) return Element_Type;
+33/2
+   function Last_Key (Container : Map) return Key_Type;
+34/2
+   function Next (Position : Cursor) return Cursor;
+35/2
+   procedure Next (Position : in out Cursor);
+36/2
+   function Previous (Position : Cursor) return Cursor;
+37/2
+   procedure Previous (Position : in out Cursor);
+38/2
+   function Find (Container : Map;
+                  Key       : Key_Type) return Cursor;
+39/2
+   function Element (Container : Map;
+                     Key       : Key_Type) return Element_Type;
+40/2
+   function Floor (Container : Map;
+                   Key       : Key_Type) return Cursor;
+41/2
+   function Ceiling (Container : Map;
+                     Key       : Key_Type) return Cursor;
+42/2
+   function Contains (Container : Map;
+                      Key       : Key_Type) return Boolean;
+44/2
+   function "<" (Left, Right : Cursor) return Boolean;
+45/2
+   function ">" (Left, Right : Cursor) return Boolean;
+46/2
+   function "<" (Left : Cursor; Right : Key_Type) return Boolean;
+47/2
+   function ">" (Left : Cursor; Right : Key_Type) return Boolean;
+48/2
+   function "<" (Left : Key_Type; Right : Cursor) return Boolean;
+49/2
+   function ">" (Left : Key_Type; Right : Cursor) return Boolean;
+50/2
+   procedure Iterate
+     (Container : in Map;
+      Process   : not null access procedure (Position : in Cursor));
+51/2
+   procedure Reverse_Iterate
+     (Container : in Map;
+      Process   : not null access procedure (Position : in Cursor));
+51.1/3
+   function Iterate (Container : in Map)
+      return Map_Iterator_Interfaces.Reversible_Iterator'Class;
+51.2/3
+   function Iterate (Container : in Map; Start : in Cursor)
+      return Map_Iterator_Interfaces.Reversible_Iterator'Class;
+52/2
+private
+53/2
+   ... -- not specified by the language
+54/2
+end Stable;
+55/2
 
-  A.18.6.1 The Nested Package Containers.Ordered_Maps.Stable
+Insert at end of A.18.6:
 
    The nested package Ordered_Maps.Stable
    provides a type Stable.Map that represents
@@ -736,38 +987,6 @@
    is zero. The Length of a stable map never changes after
    initialization.
 
-   The Containers.Ordered_Maps.Stable subpackage is based on the Ordered_Maps
-   package, but with the following changes:
-
-     Type Map is declared as follows:
-
-           type Map (Base : not null access Ordered_Maps.Map) is
-              tagged limited private
-              with Constant_Indexing => Constant_Reference,
-                   Variable_Indexing => Reference,
-                   Default_Iterator  => Iterate,
-                   Iterator_Element  => Element_Type;
-           pragma Preelaborable_Initialization(Map);
-
-     The operations Clear, Assign, Move, Insert, Include, Exclude, and Delete
-     are omitted.
-
-     Upon creation, an object of type Stable.Map marks the map
-     designated by the Base discriminant (the /base/ map) to disallow
-     tampering with cursors as long as the stable view of the base map
-     exists.
-
-     The operations of the Stable subpackage correspond to the
-     operations of the enclosing generic package Ordered_Maps
-     that do not tamper with cursors. For functions that create a new
-     list, such as Copy, the Stable versions of these first create a
-     base object of the Ordered_Maps.Map type, and then create a
-     stable map designating that base object. [Redundant: If one of
-     these functions is used to initialize a stable map object, the
-     return object is built in place.]  The other operations of the
-     Stable subpackage perform the corresponding operation on the map
-     designated by the Base discriminant.
-
 ----
 In section A.18.7 on Sets, delete A.18.7(13/2 and 13/3),
 and modify A.18.7(14.1/4) as follows:
@@ -782,22 +1001,18 @@
    of S), leaving S unmodified.] These checks are made before any other
    defined behavior of the body of the language-defined subprogram.
 
-Insert new section after A.18.8 (or in a separate area at the end of
-A.18 to avoid using 4-component numbers):
+Insert code for Hashed_Sets.Stable after A.18.8(59/2), and
+a new section at end of A.18.8:
 
-  A.18.8.1 The Nested Package Containers.Hashed_Sets.Stable
-
 ... analogous to Hashed_Maps.Stable, but list of omitted operations is instead:
 
   Procedures Reserve_Capacity, Clear, Replace_Element, Assign, Move, Insert,
   Include, Replace, Exclude, Delete, Union, Intersection, Difference, and
   Symmetric_Difference are omitted, as is the nested generic package
   Generic_Keys.
-
-Insert new section after A.18.9 (or in a separate area at the end of
-A.18 to avoid using 4-component numbers):
 
-  A.18.9.1 The Nested Package Containers.Ordered_Sets.Stable
+Insert code for Ordered_Sets.Stable after A.18.9(74/2), and
+a new section at end of A.18.9:
 
 ... analogous to Ordered_Maps.Stable, but list of omitted operations is instead:
 
@@ -806,9 +1021,55 @@
   Union, Intersection, Difference, and Symmetric_Difference are omitted,
   as is the nested generic package Generic_Keys.
 
+Insert code for Multiway_Trees.Stable after A.18.10(70/3), and
+a new section at end of A.18.10:
+
+... analogous to Vectors.Stable, but list of omitted operations is instead:
+
+  Procedures Clear, Assign, Move, Insert_Child, Append_Child,
+  Prepend_Child, Delete_Leaf, Delete_Subtree, Delerte_Children,
+  Copy_Subtree, Splice_Subtree, and Splice_Children are omitted
+
+Delete A.18.10(87/3-89/3)
+
+Modify A.18.10(90/4) as follows:
+  When tampering with cursors is prohibited for a particular tree object
+  T, Program_Error is propagated by a call of any language-defined
+  subprogram that is defined to tamper with the cursors of T, leaving T
+  unmodified. [Similarly, when tampering with elements is prohibited for
+  a particular tree object T, Program_Error is propagated by a call of
+  any language-defined subprogram that is defined to tamper with the
+  elements of T (or tamper with the cursors of T), leaving T
+  unmodified.  These checks are]{This check is} made before any other
+  defined behavior of the body of the language-defined subprogram.
+
+Add after A.18.17(8/4):
+  A subprogram is said to tamper with elements of a tree object T if:
+    * it tampers with cursors of T; or
+    * it replaces one or more elements of T, that is, it calls the
+      Replace_Element or Swap procedures with T as a parameter.
+
+  When tampering with elements is prohibited for a particular tree
+  object T, Program_Error is propagated by a call of any
+  language-defined subprogram that is defined to tamper with the
+  elements of T (or tamper with the cursors of T), leaving T unmodified.
+  This check is made before any other defined behavior of the body of
+  the language-defined subprogram.
+
+  * The operations Replace_Element and Swap are omitted from the Stable
+    subpackage.
+
 !discussion
 
-Tampering was primarily intended to prevent erroneous/unspecified behavior.
+As mentioned in the proposal, the intent is that a stable container can
+be manipulated more efficiently, and safely walked concurrently by
+multiple tasks, because tampering bits need not be updated as part of
+each operation.
+
+Tampering was primarily intended to prevent erroneous/unspecified
+behavior. As part of this AI we have also simplified the rules for
+tampering, by eliminating the tampering with elements checks when
+elements are of a definite subtype.
 
 More specifically, tampering with cursors was intended to prevent loops from
 going off the rails because an element was deleted (which might cause an
@@ -823,8 +1084,14 @@
 access types will work safely across assignment to their designated
 objects.
 
-We make the stable vector type a limited type because normal assignment
-would almost certainly fail due to a mismatch of the access discriminant.
+We make a stable container type a limited type because normal assignment
+would almost certainly fail due to a mismatch of the access
+discriminant.
+
+We considered using child (generic) packages rather than nested
+packages, but the complexity of using child generic packages, requiring
+a separate "with" clause and an appropriate parameterless instantiation,
+made that a less attractive option.
 
 !ASIS
 
@@ -3885,12 +4152,12 @@
 For Maps, I left the definition of tampering with elements in the same place,
 but said it only applied if the Element_Type was indefinite.
 
-> Secondly, while you have a nice definition of tampering with elements 
-> and prohibiting tampering with elements in the Indefinite_Vector, I 
-> didn't see any text that defines what operations prohibit tampering 
+> Secondly, while you have a nice definition of tampering with elements
+> and prohibiting tampering with elements in the Indefinite_Vector, I
+> didn't see any text that defines what operations prohibit tampering
 > with elements (since you changed the original definitions to "tampering with cursors").
-> Humm, actually, I can't find where you changed the original 
-> definitions. But you have to do that, as "tampering with elements" is 
+> Humm, actually, I can't find where you changed the original
+> definitions. But you have to do that, as "tampering with elements" is
 > no longer defined in A.18.2, so you can't use it in A.18.2.
 
 I left the wording about what disallows tampering with elements in A.18.2,
@@ -3904,8 +4171,8 @@
 
 ...
 > > I only saw one, which clause used a different method than Vectors?
-> 
-> For Maps, I left the definition of tampering with elements in the same 
+>
+> For Maps, I left the definition of tampering with elements in the same
 > place, but said it only applied if the Element_Type was indefinite.
 
 I see. That would work, if you added some wording somewhere to say that if
@@ -3914,17 +4181,17 @@
 no tampering check at all unless the element is indefinite. That's not what
 we agreed to.
 
-> > Secondly, while you have a nice definition of tampering with 
-> > elements and prohibiting tampering with elements in the 
-> > Indefinite_Vector, I didn't see any text that defines what 
-> > operations prohibit tampering with elements (since you changed the 
+> > Secondly, while you have a nice definition of tampering with
+> > elements and prohibiting tampering with elements in the
+> > Indefinite_Vector, I didn't see any text that defines what
+> > operations prohibit tampering with elements (since you changed the
 > > original definitions to "tampering with cursors").
-> > Humm, actually, I can't find where you changed the original 
-> > definitions. But you have to do that, as "tampering with elements" 
+> > Humm, actually, I can't find where you changed the original
+> > definitions. But you have to do that, as "tampering with elements"
 > > is no longer defined in A.18.2, so you can't use it in A.18.2.
-> 
-> I left the wording about what disallows tampering with elements in 
-> A.18.2, presuming a forward reference.  But I think the approach in 
+>
+> I left the wording about what disallows tampering with elements in
+> A.18.2, presuming a forward reference.  But I think the approach in
 > Maps is probably better.
 
 That doesn't make sense, IMHO. You have a use of a completely undefined term.
@@ -3943,5 +4210,47 @@
 That's the most work, but it's also crystal-clear what's going on, and it
 doesn't require defining terms in clauses where they aren't used (as in the
 Maps version), or any forward references.
+
+***************************************************************
+
+From: Tucker Taft
+Sent: Wednesday, October 11, 2017  2:18 PM
+
+Here is an update on AI12-0111 -- adding a Stable sub package to most
+containers, and removing tampering with elements from
+"definite"-element-type containers. [This is version /06 of this AI
+- Editor.]
+
+***************************************************************
+
+From: Randy Brukardt
+Sent: Wednesday, October 11, 2017  10:12 PM
+
+Comment: I don't think the Stable subpackage semantics can go at the end of
+A.18.2 (or any other clause), since that (depending on how literally you take
+"end") is a notes or Implementation Advice subsection. Perhaps you want it at
+the end of the "Static Semantics" subsection, or perhaps you want another
+"Static Semantics" header. (I'd go for the former.) This applies to all of the
+top-level items.
+
+Minor glitch: in A.18.12, the new paragraph dropping Replace_Element and Swap
+is not in the form of a bullet, which is the format of that subclause. I fixed
+this.
+
+Question: Why do we drop Replace_Element for Indefinite lists and Trees, but
+not Indefinite vectors, maps, or sets??
+
+Glitch: The change to A.18.17 (Indefinite Trees) appears twice, at around line
+620 and 1050. (Maybe you started to do the above for Maps and Sets and never
+finished it???) I deleted the extra copy.
+
+Comment: I think you need a sentence in the "regular" containers that says that
+tampering with elements is equivalent to tampering with cursors. You can sort
+of derive that from other rules, but it's a leap. Many of the operations of the
+regular containers prohibit tampering with elements, but there is no explicit
+definition of what that means there (only in the indefinite containers).
+Alternatively, you could have some sort of equivalence rule in the introduction
+"For containers with elements that aren't indefinite, tampering with elements is
+the same as tampering with cursors."
 
 ***************************************************************

Questions? Ask the ACAA Technical Agent