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

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

--- ai12s/ai12-0111-1.txt	2017/10/12 03:13:15	1.15
+++ ai12s/ai12-0111-1.txt	2018/10/19 05:03:36	1.16
@@ -1,4 +1,4 @@
-!standard A.18.2(97.1/3)                              17-10-11  AI12-0111-1/06
+!standard A.18.2(97.1/3)                             18-10-18  AI12-0111-1/07
 !class Amendment 16-06-06
 !status work item 14-05-15
 !status received 14-02-08
@@ -15,10 +15,13 @@
 be set once when the view is created, and released when the view goes
 away.
 
-Replace any prohibition of "tampering with elements" checks with a prohibition
-of "tampering with cursors" checks for containers of elements of a definite
-type. For containers of an indefinite type, any prohibition of tampering with
-elements remains.
+Simplfy "tampering with elements" to be equivalent to "tampering with
+elements" for containers of elements of a definite type. For containers 
+of an indefinite type, the original definition remains.
+
+Add an aspect Iterator_View to be used by "of" form iterators to determine
+the view of the container used. Add this to all containers to use the
+stable view of the container.
 
 !problem
 
@@ -58,22 +61,61 @@
 Two essential properties of stable containers are that they have no tampering
 checks, and can be iterated by multiple tasks in parallel.
 
+We also define an aspect Iterator_View which defines the container view to 
+use for an "of" form iterator (formally, a "container element iterator").
+We use this to have all such iterators for the language-defined containers
+to use the stable view of the container (meaning that there are not tampering
+checks on the individual calls to Reference).
+
 Note that we propose to reclassify Merge as tampering with cursors,
-and to restrict "tampering with elements" to apply only to containers with
-indefinite elements.
+and to define "tampering with elements" to be the same as tampering with 
+cursors for all containers other than those with indefinite elements.
 
 !wording
 
+[Note: The below text will appear under an existing heading of:
+The following type-related operational aspects may be specified for an indexable container type T:]
+
+Add after 5.5.1(9/3):
+
+Iterator_View
+    This aspect is specified by a name that denotes a type T2 with the 
+    following properties:
+       * T2 is declared in the same compilation unit as T;
+       * T2 is an indexable container type;
+       * T2 has a single discriminant which is an access discriminant 
+         designating T; and
+       * The default iterator subtypes for T and T2 statically match.
+
+Add to the end of 5.5.2(12/3):
+
+  If the container type has Iterator_View specified, a object of the 
+  Iterator_View type is created with the discriminant referencing the 
+  denoted iterable container object. This is the *iterated container 
+  object* for this loop. Otherwise, the denoted iterable container 
+  object is the *iterated container object* for this loop.
+
+AARM Reason: If Iterator_View is specified, we add an extra object and use
+that object. This allows these iterators to use the stable view (defined
+in each of the language-defined containers) to do the iteration. That 
+eliminates the need to set and clear the tampering with elements indication
+each time Reference is called; that eliminates substantial overhead as
+finalization is typically used to do this.
+
+In 5.5.2(13/3), replace each use of "iterable container object" with
+"iterated container object". [Author's note: Not showing this wording here,
+as it is heavily modified by the parallel iterator proposal, AI12-0266-1.]
+
+
 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
+  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
+  prohibited during all such operations. 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
@@ -81,17 +123,27 @@
 
   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
+  that prohibits any 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)
 
+Replace A.18.2(8/3) with:
+   type Vector is tagged private
+      with Constant_Indexing => Constant_Reference,
+           Variable_Indexing => Reference,
+           Default_Iterator  => Iterate,
+           Iterator_Element  => Element_Type,
+           Iterator_View     => Stable.Vector;
+   pragma Preelaborable_Initialization(Vector);
+(make a similar change for each container type, in A.18.3(6/3), A.18.5(3/3),
+A.18.6(4/3), A.18.8(3/3), A.18.9(4/3), A.18.10(8/3).
+
+
+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))
 
@@ -101,40 +153,18 @@
     Insert_Space, Clear, Delete, or Set_Length procedures{,or Merge
     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
-  (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:
-
-  When tampering with cursors is prohibited for a particular vector
-  object V, Program_Error is propagated by a call of any
-  language-defined subprogram that is defined to tamper with the cursors
-  of V, leaving V unmodified. [Similarly, when tampering with elements is
-  prohibited for a particular vector object V, Program_Error is
-  propagated by a call of any language-defined subprogram that is
-  defined to tamper with the elements of V (or tamper with the cursors
-  of V), leaving V unmodified.] These checks are made before any other
-  defined behavior of the body of the language-defined subprogram.
-
-Add in the Indefinite_Vectors section, after A.18.11(9/4):
-* A subprogram is said to /tamper with elements/ of an indefinite
-  vector object V if:
 
-    - it tampers with cursors of V; or
+Replace A.18.2(95/2-97/2) (also do the same with 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)) with:
+   A subprogram is said to tamper with elements of a vector object V if it
+   tampers with cursors of V.
+
+   AARM Reason: A definite element cannot change size, so there are no other
+   operations that tamper with elements. That's not true for the indefinite
+   containers, which is why we leave this separate definition.
 
-    - it replaces one or more elements of V, that is, it calls the
-      Replace_Element, Reverse_Elements, or Swap procedures, or the Sort
-      procedures of an instance of Generic_Sorting, with V as a parameter.
 
-  When tampering with elements is prohibited for a particular indefinite
-  vector object V, Program_Error is propagated by a call of any
-  language-defined subprogram that is defined to tamper with the
-  elements or cursors of V, leaving V unmodified.
-  These checks are made before any other defined behavior of the body of
-  the language-defined subprogram.
-
 Insert after A.18.2(79/2):
 
 [Author's note: Below, we have left in the original paragraph numbers
@@ -254,11 +284,7 @@
                                Position  : in Cursor)
               return Reference_Type;
 
-34.7/3     procedure Assign (Target : in out Vector;
-                             Source : in Vector)
-             with Pre => Length (Target) = Length (Source);
-
-           procedure Assign (Target : in out Vectors.Vector;
+34.7/3     procedure Assign (Target : in out Vectors.Vector;
                              Source : in Vector);
 
 34.8/3     function Copy (Source : Vector)
@@ -358,18 +384,17 @@
    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.
+   by establishing a /stabilized view/ of a regular Vector.
 
    The operations of this package are equivalent to those for regular
-   Vectors, except that no tampering checks are performed.  If a stable
+   Vectors, except that no tampering checks are performed on stable 
+   Vectors. 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
+   elements 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
@@ -382,6 +407,21 @@
    is zero. The Length of a stable vector never changes after
    initialization.
 
+Add in the Indefinite_Vectors section, after A.18.11(9/4):
+* A subprogram is said to /tamper with elements/ of an indefinite
+  vector object V if:
+
+    - it tampers with cursors of V; or
+
+    - it replaces one or more elements of V, that is, it calls the
+      Replace_Element, Reverse_Elements, or Swap procedures, or the Sort
+      procedures of an instance of Generic_Sorting, with V as a parameter.
+
+     AARM Reason: Complete replacement of an element can cause its memory to 
+     be deallocated while another operation is holding onto a reference to it.
+     That can't be allowed. However, a simple modification of (part of) an 
+     element is not a problem, so Update_Element does not cause a problem. 
+
 --------
 
 Insert after A.18.3(51/2):
@@ -451,11 +491,8 @@
 34.6/3     function Reference (Container : aliased in out List;
                                Position  : in Cursor)
               return Reference_Type;
-
-34.7/3     procedure Assign (Target : in out List;
-                             Source : in List)
 
-           procedure Assign (Target : in out Doubly_Linked_Lists.List;
+34.7/3     procedure Assign (Target : in out Doubly_Linked_Lists.List;
                              Source : in List);
 
 34.8/3     function Copy (Source : List)
@@ -556,18 +593,17 @@
    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.
+   by establishing a /stabilized view/ of a regular Vector.
 
    The operations of this package are equivalent to those for regular
-   Doubly_Linked_Lists, except that no tampering checks are performed.
+   Doubly_Linked_Lists, except that no tampering checks are performed 
+   on stable lists.
    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
+   elements 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
@@ -596,51 +632,45 @@
     - it replaces one or more elements of L, that is, it calls the
       Replace_Element or Swap procedures with L as a parameter.
 
-  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 or cursors of L, leaving L unmodified. These checks are
-  made before any other defined behavior of the body of the
-  language-defined subprogram.
-
-Delete A.18.10(87/3-89/3) in section on Multiway_Trees
-Modify A.18.10(90/4):
-
-  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 made before any other defined behavior
-  of the body of the language-defined subprogram.
-
-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.
+     AARM Reason: Complete replacement of an element can cause its memory to 
+     be deallocated while another operation is holding onto a reference to it.
+     That can't be allowed. However, a simple modification of (part of) an 
+     element is not a problem, so Update_Element does not cause a problem. 
 
-  * 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 indefinite tree
-  object T, Program_Error is propagated by a call of any
-  language-defined subprogram that is defined to tamper with the
-  elements or cursors of T, leaving T unmodified.
-  These checks are made before any other defined behavior of the body of
-  the language-defined subprogram.
-
 ---
 
 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 at end of A.18.4:
+
+   The nested package Stable provides a type Stable.Map that represents
+   a /stable/ map, which is one that cannot grow and shrink.  Such a
+   map can be created by calling the Copy functions, or
+   by establishing a /stabilized view/ of a regular Map.
+
+   The operations of this package are equivalent to those for regular
+   Hashed_Maps, except that no tampering checks are performed on 
+   stable maps. If a stable
+   map is declared with the Base discriminant designating a
+   pre-existing regular map, the stable map represents a
+   stabilized view of the underlying regular map, and any operation
+   on the stable map is reflected on the underlying regular map.
+   While a stabilized view exists, any operation that tampers with
+   elements performed on the underlying map is prohibited.  The
+   finalization of a stable map that provides such a view removes
+   this restriction on the underlying regular map Redundant[(though
+   some other restriction might exist due to other concurrent iterations
+   or stabilized views)].
+
+   If a stable map is declared without specifying Base, the object must
+   be initialized. The initializing expression of
+   the stable map, Redundant[typically a call on
+   Copy], determines the Length of the map. By default the Length
+   is zero. The Length of a stable map never changes after
+   initialization.
+
 Insert after A.18.5(38/2):
 
 [Author's note: Below, we have left in the original paragraph numbers
@@ -724,6 +754,11 @@
    function Reference (Container : aliased in out Map;
                        Key       : in Key_Type)
       return Reference_Type;
+
+17.7/3
+   procedure Assign (Target : in out Hashed_Map.Map;
+                     Source : in Map);
+
 17.8/3
    function Copy (Source : Map; Capacity : Count_Type := 0) return Map;
 
@@ -773,36 +808,6 @@
 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
-   map can be created by calling the Copy functions, or
-   by establishing a /stabilized view/ of a regular Map. While a
-   stabilized view exists, no operations that tamper with cursors are
-   permitted on the underlying regular Map.
-
-   The operations of this package are equivalent to those for regular
-   Hashed_Maps, except that no tampering checks are performed.  If a stable
-   map is declared with the Base discriminant designating a
-   pre-existing regular map, the stable map represents a
-   stabilized view of the underlying regular map, and any operation
-   on the stable map is reflected on the underlying regular map.
-   While a stabilized view exists, any operation that tampers with
-   cursors performed on the underlying map is prohibited.  The
-   finalization of a stable map that provides such a view removes
-   this restriction on the underlying regular map Redundant[(though
-   some other restriction might exist due to other concurrent iterations
-   or stabilized views)].
-
-   If a stable map is declared without specifying Base, the object must
-   be initialized. The initializing expression of
-   the stable map, Redundant[typically a call on
-   Copy], determines the Length of the map. By default the Length
-   is zero. The Length of a stable map never changes after
-   initialization.
-
 ----
 
 Insert after A.18.6(51.2/3):
@@ -882,6 +887,9 @@
    function Reference (Container : aliased in out Map;
                        Key       : in Key_Type)
       return Reference_Type;
+16.7/3
+   procedure Assign (Target : in out Ordered_Map.Map;
+                     Source : in Map);
 16.8/3
    function Copy (Source : Map) return Map;
 22/2
@@ -957,105 +965,134 @@
 end Stable;
 55/2
 
-Insert at end of A.18.6:
+In the section on Indefinite_Hashed_Maps, A.18.13, add after para 9/4:
 
-   The nested package Ordered_Maps.Stable
-   provides a type Stable.Map that represents
-   a /stable/ map, which is one that cannot grow and shrink.  Such a
-   map can be created by calling the Copy functions, or
-   by establishing a /stabilized view/ of a regular Map. While a
-   stabilized view exists, no operations that tamper with cursors are
-   permitted on the underlying regular Map.
+   * The operations Replace and Replace_Element are omitted from the Stable 
+     subpackage.
+
+   * A subprogram is said to tamper with elements of a map object M if:
+     - it tampers with cursors of M; or
+     - it replaces one or more elements of M, that is, it calls the Replace 
+       or Replace_Element procedures with M as a parameter.
+
+     AARM Reason: Complete replacement of an element can cause its memory to 
+     be deallocated while another operation is holding onto a reference to it.
+     That can't be allowed. However, a simple modification of (part of) an 
+     element is not a problem, so Update_Element does not cause a problem. 
+
+In the section on Indefinite_Ordered_Maps, A.18.14, add after para 9/4:
+
+   * The operations Replace and Replace_Element are omitted from the Stable 
+     subpackage.
+
+   * A subprogram is said to tamper with elements of a map object M if:
+     - it tampers with cursors of M; or
+     - it replaces one or more elements of M, that is, it calls the Replace 
+       or Replace_Element procedures with M as a parameter.
+
+     AARM Reason: Complete replacement of an element can cause its memory to 
+     be deallocated while another operation is holding onto a reference to it.
+     That can't be allowed. However, a simple modification of (part of) an 
+     element is not a problem, so Update_Element does not cause a problem. 
+
+----
+
+Insert at end of A.18.7:
 
+   The nested package Stable provides a type Stable.Set that represents
+   a /stable/ set, which is one that cannot grow and shrink. Such a
+   set can be created by calling the Copy functions, or
+   by establishing a /stabilized view/ of a regular Set.
+
    The operations of this package are equivalent to those for regular
-   Ordered_Maps, except that no tampering checks are performed.  If a stable
-   map is declared with the Base discriminant designating a
-   pre-existing regular map, the stable map represents a
-   stabilized view of the underlying regular map, and any operation
-   on the stable map is reflected on the underlying regular map.
+   maps, except that no tampering checks are performed on 
+   stable sets. If a stable
+   set is declared with the Base discriminant designating a
+   pre-existing regular set, the stable set represents a
+   stabilized view of the underlying regular set, and any operation
+   on the stable set is reflected on the underlying regular set.
    While a stabilized view exists, any operation that tampers with
-   cursors performed on the underlying map is prohibited.  The
-   finalization of a stable map that provides such a view removes
-   this restriction on the underlying regular map Redundant[(though
+   elements performed on the underlying set is prohibited.  The
+   finalization of a stable set that provides such a view removes
+   this restriction on the underlying regular set Redundant[(though
    some other restriction might exist due to other concurrent iterations
    or stabilized views)].
 
-   If a stable map is declared without specifying Base, the object must
+   If a stable set is declared without specifying Base, the object must
    be initialized. The initializing expression of
-   the stable map, Redundant[typically a call on
-   Copy], determines the Length of the map. By default the Length
-   is zero. The Length of a stable map never changes after
+   the stable set, Redundant[typically a call on
+   Copy], determines the Length of the set. By default the Length
+   is zero. The Length of a stable set never changes after
    initialization.
-
-----
-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:
 
-   When tampering with cursors {or tampering with elements} is prohibited
-   for a particular set object S, Program_Error is propagated by a call
-   of any language-defined subprogram that is defined to tamper with the
-   cursors of S, leaving S unmodified. [Similarly, when tampering with
-   elements is prohibited for a particular set object S, Program_Error
-   is propagated by a call of any language-defined subprogram that is
-   defined to tamper with the elements of S (or tamper with the cursors
-   of S), leaving S unmodified.] These checks are made before any other
-   defined behavior of the body of the language-defined subprogram.
+Insert code for Hashed_Sets.Stable after A.18.8(59/2):
 
-Insert code for Hashed_Sets.Stable after A.18.8(59/2), and
-a new section at end of A.18.8:
-
 ... analogous to Hashed_Maps.Stable, but list of omitted operations is instead:
 
-  Procedures Reserve_Capacity, Clear, Replace_Element, Assign, Move, Insert,
+  Procedures Reserve_Capacity, Clear, Replace_Element, Move, Insert,
   Include, Replace, Exclude, Delete, Union, Intersection, Difference, and
   Symmetric_Difference are omitted, as is the nested generic package
-  Generic_Keys.
+  Generic_Keys. Assign is included, but the Target parameter is a normal 
+  (not stable) Hashed_Set.
 
-Insert code for Ordered_Sets.Stable after A.18.9(74/2), and
-a new section at end of A.18.9:
+Insert code for Ordered_Sets.Stable after A.18.9(74/2):
 
 ... analogous to Ordered_Maps.Stable, but list of omitted operations is instead:
 
-  Procedures Reserve_Capacity, Clear, Replace_Element, Assign, Move,
+  Procedures Reserve_Capacity, Clear, Replace_Element, Move,
   Insert, Include, Replace, Exclude, Delete, Delete_First, Delete_Last,
   Union, Intersection, Difference, and Symmetric_Difference are omitted,
-  as is the nested generic package Generic_Keys.
+  as is the nested generic package Generic_Keys. Assign is included, but the 
+  Target parameter is a normal (not stable) Ordered_Set.
+
+[Author's note: For a Set, there is no additional operations that tamper 
+with elements. We should move AARM A.18.7(14.a-b/2) into A.18.15 and A.18.16
+to explain why there is no "tampering with elements" definition in those
+packages.]
 
-Insert code for Multiway_Trees.Stable after A.18.10(70/3), and
-a new section at end of A.18.10:
+Insert code for Multiway_Trees.Stable after A.18.10(70/3):
 
 ... analogous to Vectors.Stable, but list of omitted operations is instead:
 
-  Procedures Clear, Assign, Move, Insert_Child, Append_Child,
+  Procedures Clear, Move, Insert_Child, Append_Child,
   Prepend_Child, Delete_Leaf, Delete_Subtree, Delerte_Children,
-  Copy_Subtree, Splice_Subtree, and Splice_Children are omitted
+  Copy_Subtree, Splice_Subtree, and Splice_Children are omitted.
+  Assign is included, but the 
+  Target parameter is a normal (not stable) Multiway_Tree.
+
+Insert at end of A.18.10:
+
+   The nested package Stable provides a type Stable.Tree that represents
+   a /stable/ tree, which is one that cannot grow and shrink. Such a
+   tree can be created by calling the Copy functions, or
+   by establishing a /stabilized view/ of a regular Tree.
 
-Delete A.18.10(87/3-89/3)
+   The operations of this package are equivalent to those for regular
+   maps, except that no tampering checks are performed on 
+   stable trees. If a stable tree is declared with the Base discriminant
+   designating a pre-existing regular tree, the stable tree represents a
+   stabilized view of the underlying regular tree, and any operation
+   on the stable tree is reflected on the underlying regular tree.
+   While a stabilized view exists, any operation that tampers with
+   elements performed on the underlying tree is prohibited. The
+   finalization of a stable tree that provides such a view removes
+   this restriction on the underlying regular tree Redundant[(though
+   some other restriction might exist due to other concurrent iterations
+   or stabilized views)].
 
-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.
+   If a stable tree is declared without specifying Base, the object must
+   be initialized. The initializing expression of
+   the stable tree, Redundant[typically a call on
+   Copy], determines the Length of the tree. By default the Length
+   is zero. The Length of a stable tree never changes after
+   initialization.
 
-Add after A.18.17(8/4):
+Add after A.18.17(8/4): [Indefinite_Multiway_Trees]
   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.
 
@@ -4252,5 +4289,131 @@
 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."
+
+***************************************************************
+
+From: Randy Brukardt
+Sent: Thursday, October 18, 2018  11:53 PM
+
+Posting this [this is version /07 of the AI - Editor.] here as much so I can 
+remember what is changed when we discuss this next week as any other reason. 
+So attached is a new version of this AI.
+
+(1) Added an aspect Iterator_View to specify the view of a container to use 
+for an "of" iterator (formally, a "container element iterator"). We specify 
+this on each language-defined container to require the use of the stable view
+in such an iterator. This reduces the number of times that "tampering with 
+cursors" is set and cleared from N to 1.
+
+We used an aspect since compiler authors would need to use some similar 
+mechanism to tie the iterator to the stable view in any case, and it might be
+useful for users to use a similar mechanism in their own containers. For 
+instance, a task-safe container might use an analog of a stable view to 
+provide a view that is locked against writing while the iterator is executing.
+
+(2) Redid the text to leave all of the uses and definitions of "tampering with
+elements". What was changed was for all of the normal containers to change the
+definition of "tampering with elements" to be exactly the same as "tampering 
+with cursors". (All of the indefinite containers already had the previous 
+definition of "tampering with elements" - but see the next item.)
+
+(3) The text defining "tampering with elements" for the indefinite maps (two 
+containers) was missing completely. Also added an AARM note to the indefinite
+sets (two containers) to explain why there is no such definition in them. (So
+future readers won't think that we made a mistake!)
+
+(4) For Maps and Sets, moved the definition of the Stable package to the 
+shared part (it's the same for both kinds).
+
+(5) The definition of stablized views had sentences in two different 
+paragraphs saying that tampering is prohibited. Once is enough, I eliminated
+the extra one. (They even both started with "While a stabilized view 
+exists...")
+
+(6) I modified the wording "except that no tampering checks are performed{ on 
+stable <<container kind>>}" so that there is a tampering check on the 
+(non-stable) target of the stable Assign operation (also see the next item). 
+We wouldn't want the tampering check to be skipped for some container just 
+because the assignment source was a stable view.
+
+(7) Tucker had an item to "define Assign". The version of Assign in Stable 
+that has a non-stable target is exactly as Assign is defined for the 
+underlying container, so no special definition is needed. Tucker also had a
+version of assign whose target is a stable view. This operation is 
+problematical, so I saved myself a bunch of work and deleted it everywhere. 
+Specifically:
+(A) Changing the entire contents of a "stable" view seems pretty 
+unstable. :-) This doesn't feel like a stable operation, which mostly would
+be reading and possibly simple modifications of a small part of an element.
+(B) Certainly, changing a stable view can't be allowed in an indefinite 
+container, as the individual elements might change size. Excluding it is 
+annoying as it is overloaded so just giving the name is not enough.
+(C) Assign is a tampering with cursors operation, and those are generally the
+operations excluded from Stable in the first place.
+(D) It is only allowed when the lengths match already. That would generally 
+require creating an object with the right length -- but if one is going to 
+do that, one could have used Copy to create the object and Assign is not 
+needed.
+(E) Worst case if it is omitted, one can assign into a normal vector and 
+then immediately create a stable view of it. That doesn't seem difficult for
+most code.
+(F) To avoid problems with (C), this Assign needs a special definition. It 
+has to copy elements without doing any memory allocation/deallocation, 
+reordering of elements, or any other operations that could cause trouble.
+Such a definition sounds reasonably complicated and could require a special
+implementation compared to other similar operations.
+(G) Tucker only defined this operation for Vectors and Lists, and omitted 
+assign from the other kinds of containers. That's presumably because of 
+issues with the structure associated. But the version with a normal container
+would work for all; so I added that to all of the Stable subpackages.
+
+All-in-all, this operation doesn't seem worth the trouble (especially as it
+only makes sense for two containers). If it turns out in practice to be an 
+issue, we can define it in the Corrigendum that is almost certainly coming in 
+2023.
+
+---
+
+(10) One thought that I did not pursue would be to define "tampering with 
+elements" for bounded containers to be associated with *no* operations. Since
+the bounded containers do not (if the implementation advice is followed) ever
+allocate or deallocate memory when an object inserted or deleted, the problem
+that requires us to keep "tampering with cursors" for all unbounded container
+operations does not exist for bounded operations. (If we didn't check 
+"tampering with cursors" for an unbounded definite container, a "tampering 
+with cursors" scenario would have to be erronous for operations like 
+Reference, which is a worse situation than would occur when writing the code
+explicitly.) For a bounded container, the worst thing that could happen would
+be that some mutable discriminant would change value, which is a situation 
+that can happen for regular subprogram calls (and is declared erroneous).
+There'd be no new problem.
+
+We could do that fairly simply by adding something like the following to each 
+bounded container:
+
+   * A subprogram is never said to tamper with elements of a bounded vector 
+     object V.
+
+   AARM Reason: The memory for a bounded container is not allocated or 
+   deallocated during normal operations. Therefore, an Update_Element routine 
+   (for example) can never be holding deallocated memory even if a tampering 
+   with cursors operation is called on the container. A discriminant might 
+   change, but that is already possible for any parameter of a mutable record 
+   type, and that case is covered by an erroneous execution rule in 3.7.2.
+
+We'd also have to add a rule for stablized views to the same bounded 
+containers:
+
+   * While a stabilized view exists, any operation that tampers with cursors 
+     performed on the underlying tree is prohibited. 
+
+since the prinary goal is to make stable views safe for all operations without
+checks, and tampering checks are still needed for bounded containers to 
+prevent iteration from going off into the weeds.
+
+I didn't do this as we haven't discussed it previously (it's possible that 
+this was Tucker's original intent, but I don't know for sure), and it was a
+bunch more work (I've have to look up the paragraph numbers in each clause).
+I'm already way behind...
 
 ***************************************************************

Questions? Ask the ACAA Technical Agent