CVS difference for 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