CVS difference for ai05s/ai05-0139-2.txt
--- ai05s/ai05-0139-2.txt 2010/06/14 01:07:39 1.8
+++ ai05s/ai05-0139-2.txt 2010/10/26 00:21:22 1.9
@@ -1,4 +1,4 @@
-!standard 4.1(2/2) 10-06-10 AI05-0139-2/06
+!standard 4.1(2/2) 10-10-25 AI05-0139-2/07
!standard 4.1.5(0)
!standard 4.1.6(0)
!standard 5.5(3)
@@ -41,38 +41,32 @@
!proposal
-Define a "magic" interface, a "magic" generic unit,
-and some additional "aspects" for the aspect_specification, all of
-which are linked to some appropriate syntactic sugar for accessors,
-containers, and iterators:
+Define a "magic" generic unit and some additional "aspects" for the
+aspect_specification, all of which are linked to some appropriate
+syntactic sugar for accessors, containers, and iterators:
1) SUPPORT FOR ACCESSORS/REFERENCES
-We propose to add a "magic" interface called Reference. Any type
-descended from Reference with exactly one access discriminant is
-considered a "reference" type, and provides implicit dereference in all
-contexts, with the "implicit dereference" of an object Ref of such a
-type being equivalent to "Ref.<discrim>.all," where "<discrim>" is the
-name of the access discriminant. If the access discriminant is an
-access constant, then of course this dereference is a constant view. If
-not, then it is a variable view, and can be used on the left-hand-side
-of an assignment, as the actual for an [in] out parameter, etc. These
-reference types are particularly useful because they can be controlled
-types or have a controlled part, so that when finalized, a user-defined
-finalization action will be invoked. This allows, for example, the
-"tampering" state of a container to be reset, a persistent object to be
-"unpinned," a reference count to be decremented, etc.
-
-The Reference interface is defined in its own package:
-
- package Ada.References is
- type Reference is limited interface;
- end Ada.References;
+We propose to add an aspect "Implicit_Dereference" which specifies an
+access discrminant of a discriminated type. Any type with an
+Implicit_Dereference aspect is considered a "reference" type, and
+provides implicit dereference in all contexts, with the "implicit
+dereference" of an object Ref of such a type being equivalent to
+"Ref.<discrim>.all," where "<discrim>" is the name of the specified access
+discriminant. If the access discriminant is an access constant, then of
+course this dereference is a constant view. If not, then it is a
+variable view, and can be used on the left-hand-side of an assignment,
+as the actual for an [in] out parameter, etc. These reference types are
+particularly useful because they can be controlled types or have a
+controlled part, so that when finalized, a user-defined finalization
+action will be invoked. This allows, for example, the "tampering" state
+of a container to be reset, a persistent object to be "unpinned," a
+reference count to be decremented, etc.
+
Here is an example of use. We imagine type T and a type T_Table which
is some kind of container with T elements in it, indexed by a string.
- with Ada.References;
with Ada.Finalization;
package Whatever is
type T is private;
@@ -82,8 +76,8 @@
type T_Table is tagged limited private;
type Ref_T(Data : access T) is
- new Ada.Finalization.Limited_Controlled
- and Ada.References.Reference with ...
+ new Ada.Finalization.Limited_Controlled with ...
+ with Implicit_Dereference => Data;
-- This type is now a "reference" type
procedure Enter(Tab : in out T_Table; Key : String; Value : T);
@@ -147,8 +141,8 @@
Constant_Indexing => Element_RO;
type Ref_Const_T(Data : access constant T) is
- new Ada.Finalization.Limited_Controlled
- and Ada.References.Reference with ...
+ new Ada.Finalization.Limited_Controlled with ...
+ with Implicit_Dereference => Data;
function Element_RO(Tab : access constant T_Table; Key : String)
return Ref_Const_T;
@@ -337,10 +331,10 @@
Default_Iterator => Iterate,
Iterator_Element => Element_Type;
- type Element_Ref(E : access Element_Type) is limited
- new Ada.References.Reference with private;
- type Element_CRef(E : access constant Element_Type) is limited
- new Ada.References.Reference with private;
+ type Element_Ref(E : access Element_Type) is tagged limited private
+ with Implicit_Dereference => E;
+ type Element_CRef(E : access constant Element_Type) is tagged limited private
+ with Implicit_Dereference => E;
type Iterator_Type is new Iterators.Reversible_Iterator with ...
function Iterate(Con : Container) return Iterator_Type;
@@ -433,19 +427,19 @@
Add a new section 4.1.5:
4.1.5 User-Defined References
+
+ Given a discriminated type T, the following aspect may be specified:
- The following language-defined library package exists:
+ Implicit_Dereference This aspect is specified by a name that denotes
+ an access discriminant declared for the type T.
- package Ada.References is
- type Reference is limited interface;
- end Ada.References;
-
- A /reference type/ is a user-defined tagged type which has exactly one
- access discriminant and is descended from the language-defined
- interface type Ada.References.Reference. A /reference object/ is an
- object of a reference type. [Redundant: A generalized_reference is a
- name that denotes the object or subprogram designated by the access
- discriminant of a reference object.]
+ A type with a specified Implicit_Dereference aspect is a /reference
+ type/. A /reference object/ is an object of a reference type. The
+ discriminant named by the Implicit_Dereference aspect is the
+ /reference discriminant/ of the reference type or reference object.
+ [Redundant: A generalized_reference is a name that identifies a
+ reference object, and denotes the object or subprogram designated by
+ the reference discriminant of the reference object.]
Syntax
@@ -459,25 +453,36 @@
Static Semantics
A generalized_reference denotes a view equivalent to that of a dereference
- of the access discriminant of the named reference object.
+ of the reference discriminant of the reference object.
+
+ Given a reference type T, the Implicit_Dereference aspect is inherited
+ by descendants of type T if not overridden. If a descendant type
+ constrains the value of the reference discriminant of T by a new
+ discriminant, that new discriminant is the reference discriminant of
+ the descendant. If the descendant type constrains the value of the
+ reference discriminant of T by an expression other than the name of a
+ new discriminant, a generalized_reference that identifies an object of
+ the descendant type denotes the object or subprogram designated by the
+ value of this constraining expression.
Dynamic Semantics
The evaluation of a generalized_reference consists of the evaluation
of the /reference_object_/name and a determination of the object or
- subprogram designated by the access discriminant of the named
- reference object. A check is made that the value of the access
+ subprogram designated by the reference discriminant of the named
+ reference object. A check is made that the value of the reference
discriminant is not the null access value. Constraint_Error is raised
if this check fails. The generalized_reference denotes the object or
- subprogram designated by the value of the access discriminant of the
+ subprogram designated by the value of the reference discriminant of the
named reference object.
Example
type Ref_Element(Data : access Element) is
- new Ada.Finalization.Limited_Controlled
- and Ada.References.Reference with null record;
- -- This type is now a "reference" type
+ new Ada.Finalization.Limited_Controlled with null record
+ with Implicit_Dereference => Data;
+ -- This Ref_Element type is a "reference" type.
+ -- "Data" is its reference discriminant.
function Find(C : access Container; Key : String) return Ref_Element;
-- Return a reference to an element of a container
@@ -579,7 +584,7 @@
Add a new section 5.5.1:
- 5.5.1 User-Defined Iterators
+ 5.5.1 User-Defined Iterator Types
The following language-defined generic library package exists:
@@ -603,10 +608,11 @@
An /iterator type/ is a type descended from the Forward_Iterator interface
from some instance of Ada.Iterator_Interfaces. A /reversible iterator type/
is a type descended from the Reversible_Iterator interface from some instance
- of Ada.Iterator_Interfaces. A /(reversible) iterator object/ is an object
- of a (reversible) iterator type. The formal subtype Cursor from the associated
- instance of Ada.Iterator_Interfaces is the /iteration cursor subtype/ for the
- iterator type.
+ of Ada.Iterator_Interfaces. An /iterator object/ is an object of an iterator
+ type. A /reversible iterator object/ is an object of a reversible iterator
+ type. The formal subtype Cursor from the associated instance of
+ Ada.Iterator_Interfaces is the /iteration cursor subtype/ for the iterator
+ type.
The following aspects may be specified for an indexable type T (see 4.1.6):
@@ -630,8 +636,9 @@
An /iteratable type/ is an indexable type with specified Default_iterator and
Iterator_Element aspects. A /reverse iteratable type/ is an
iteratable type with the default iterator type being a reversible
- iterator type. A /(reverse) iteratable object/ is an object of a
- (reverse) iteratable type.
+ iterator type. An /iteratable object/ is an object of an
+ iteratable type. A /reverse iteratable object/ is an object of a
+ reverse iteratable type.
Legality Rules
@@ -664,6 +671,10 @@
This function (if any) is the /default variable indexing function/
for T.
+ 5.5.2 Generalized Loop Iteration
+
+ Generalized forms of loop iteration are provided by an iterator_specification.
+
Syntax
iterator_specification ::=
@@ -673,51 +684,53 @@
Name Resolution
- In an iterator_specification, the expected type for the
- /iterator_/name is any iterator type; the expected type for the
- /array_/name is any array type; the expected type for the
+ The first form of iterator_specification is called a /generalized
+ iterator/; the expected type for the /iterator_/name is any iterator
+ type. The second form of iterator_specification is called an /array
+ component iterator/; the expected type for the /array_/name is any
+ array type. The third form of iterator_specification is called a
+ /container element iterator/; the expected type for the
/iteratable_/name is any iteratable type.
Legality Rules
- If the reserved word REVERSE appears in the first form of
- iterator_specification, then the /iterator_/name shall be of a
- reversible iterator type. The type of the /array_/name in the second
- form of iterator_specification shall be a one-dimensional array type.
- If the reserved word REVERSE appears in the third form of
- iterator_specification, the default iterator type for the type of the
- /iteratable_/name shall be a reversible iterator type.
-
- The type of the subtype_indication, if any, of the second form of
- iterator_specification shall cover the component type of the type of
- the /array_/name. The type of the subtype_indication, if any, of the
- third form of iterator_specification shall cover the default element
- type for the type of the /iteratable_/name.
-
- In the third form of iterator_specification, if the /iteratable_/name
- denotes a constant, then the Constant_Indexing aspect shall be specified
- for the type of the /iteratable_/name.
+ If the reserved word REVERSE appears, the iterator_specification is a
+ /reverse iterator/; otherwise it is a /forward iterator/. In a
+ reverse generalized iterator, the /iterator_/name shall be of a
+ reversible iterator type. In a reverse container element iterator,
+ the default iterator type for the type of the /iteratable_/name shall
+ be a reversible iterator type.
+
+ The type of the subtype_indication, if any, of an array component
+ iterator shall cover the component type of the type of the
+ /array_/name. The type of the subtype_indication, if any, of a
+ container element iterator shall cover the default element type for
+ the type of the /iteratable_/name.
+
+ In a container element iterator, if the /iteratable_/name denotes a
+ constant, then the Constant_Indexing aspect shall be specified for
+ the type of the /iteratable_/name.
Static Semantics
- An iterator_specification declares a /loop parameter/. In the first
- form of iterator_specification, the nominal subtype of the loop
- parameter is the iterator cursor subtype. In the second and third
- form of iterator_specification, if a subtype_indication is present,
- it determines the nominal subtype of the loop parameter. In the
- second form if a subtype_indication is not present, the nominal
- subtype of the loop parameter is the component subtype of the type of
- the /array_/name. In the third form if a subtype_indication is
- not present, the nominal subtype of the loop parameter is the default
- element subtype for the type of the /iteratable_/name.
-
- In the second form of iterator_specification, the loop parameter
- denotes a constant if the /array_/name denotes a constant; otherwise
- it denotes a variable. In the third form of iterator_specification,
- the loop parameter denotes a constant if the /iteratable_/name
- denotes a constant, or if the Variable_Indexing aspect is not
- specified for the type of the /iteratable_/name; otherwise it denotes
- a variable.
+ An iterator_specification declares a /loop parameter/. In a
+ generalized iterator, the nominal subtype of the loop parameter is
+ the iterator cursor subtype. In an array component iterator or a
+ container element iterator, if a subtype_indication is present, it
+ determines the nominal subtype of the loop parameter. In an array
+ component iterator if a subtype_indication is not present, the
+ nominal subtype of the loop parameter is the component subtype of the
+ type of the /array_/name. In a container element iterator if a
+ subtype_indication is not present, the nominal subtype of the loop
+ parameter is the default element subtype for the type of the
+ /iteratable_/name.
+
+ In an array component iterator, the loop parameter denotes a constant
+ if the /array_/name denotes a constant; otherwise it denotes a
+ variable. In a container element iterator, the loop parameter denotes
+ a constant if the /iteratable_/name denotes a constant, or if the
+ Variable_Indexing aspect is not specified for the type of the
+ /iteratable_/name; otherwise it denotes a variable.
Dynamic Semantics
@@ -725,62 +738,64 @@
the iterator_specification is first elaborated. This elaboration
elaborates the subtype_indication, if any.
- For the first form of iterator_specification, the loop parameter is
- created, and the /iterator_/name is evaluated and the denoted
- iterator object becomes the /loop iterator/. If the reserved word
- REVERSE does not appear (does appear), then the operation First
- (Last) of the (reversible) iterator type is called on the loop
- iterator, to produce the initial value for the loop parameter. If the
- initial value is equal to No_Element, then the execution of the
- loop_statement is complete. Otherwise, the sequence_of_statements is
- executed and then the Next (Previous) operation of the (reversible)
- iterator type is called with the loop iterator and the current value
- of the loop parameter to produce the next value to be assigned to the
- loop parameter. This repeats until the loop parameter is equal to
- No_Element, or the loop is left as a consequence of a transfer of
- control.
-
- For the second form of iterator_specification, the /array_/name is
- evaluated and the array object denoted by the name becomes the /array
- for the loop/. If the array for the loop is a null array, then the
- execution of the loop_statement is complete. Otherwise, if the
- reserved word REVERSE does not appear (does appear), then the
- sequence_of_statements is executed with the loop parameter denoting
- the first (last) element of the array for the loop. If the loop
- parameter now denotes the last (first) element of the array for the
- loop, then the execution of the loop_statement is complete.
- Otherwise, the sequence_of_statements is executed again with the loop
- parameter denoting the next (previous) element of the array for the
- loop. This repeats until the last (first) element is processed, or
- until the loop is left as a consequence of a transfer of control.
-
- For the third form of iterator_specification, the /iteratable_/name
- is evaluated and the iteratable object denoted by the name becomes
- the /iteratable object for the loop/. The default iterator function
- for the type of the iteratable object for the loop is called on the
- iteratable object and the result is the /loop iterator/. An object
- of the default cursor subtype is created (the /loop cursor/).
-
- If the reserved word REVERSE does not appear (does appear), then the
- operation First (Last) of the (reversible) iterator type is called on
- the loop iterator, to produce the initial value for the loop cursor.
- If the initial value is equal to No_Element, then the execution of
- the loop_statement is complete. Otherwise, the
+ For a generalized iterator, the loop parameter is created, and the
+ /iterator_/name is evaluated and the denoted iterator object becomes
+ the /loop iterator/. In a forward generalized iterator, the operation
+ First of the iterator type is called on the loop iterator, to produce
+ the initial value for the loop parameter. If the initial value is
+ equal to No_Element, then the execution of the loop_statement is
+ complete. Otherwise, the sequence_of_statements is executed and then
+ the Next operation of the iterator type is called with the loop
+ iterator and the current value of the loop parameter to produce the
+ next value to be assigned to the loop parameter. This repeats until
+ the loop parameter is equal to No_Element, or the loop is left as a
+ consequence of a transfer of control. For a reverse generalized
+ iterator, the operations Last and Previous are called rather than
+ First and Next.
+
+ For an array component iterator, the /array_/name is evaluated and
+ the array object denoted by the name becomes the /array for the
+ loop/. If the array for the loop is a null array, then the execution
+ of the loop_statement is complete. Otherwise, the
sequence_of_statements is executed with the loop parameter denoting
- an indexing (see 4.1.6) into the iteratable object for the loop, with
- the only parameter to the indexing being the current value of the
- loop cursor; then the Next (Previous) operation of the (reversible)
+ each component of the array for the loop, using a /canonical/ order
+ of components, which is last dimension varying fastest. For a
+ forward array component iterator, the iteration starts with the
+ component whose index values are each the first in their index range,
+ and continues in the canonical order. For a reverse array component
+ iterator, the iteration starts with the component whose index values
+ are each the last in their index range, and continues in the reverse
+ of the canonical order. The loop iteration proceeds until the
+ sequence_of_statements has been executed for each component of the
+ array for the loop, or until the loop is left as a consequence of a
+ transfer of control.
+
+ For a container element iterator, the /iteratable_/name is evaluated
+ and the iteratable object denoted by the name becomes the /iteratable
+ object for the loop/. The default iterator function for the type of
+ the iteratable object for the loop is called on the iteratable object
+ and the result is the /loop iterator/. An object of the default
+ cursor subtype is created (the /loop cursor/).
+
+ For a forward container element iterator, the operation First of the
+ iterator type is called on the loop iterator, to produce the initial
+ value for the loop cursor. If the initial value is equal to
+ No_Element, then the execution of the loop_statement is complete.
+ Otherwise, the sequence_of_statements is executed with the loop
+ parameter denoting an indexing (see 4.1.6) into the iteratable object
+ for the loop, with the only parameter to the indexing being the
+ current value of the loop cursor; then the Next operation of the
iterator type is called with the loop iterator and the loop cursor to
- produce the next value to be assigned to the loop cursor. This
+ produce the next value to be assigned to the loop cursor. This
repeats until the loop cursor is equal to No_Element, or until the
- loop is left as a consequence of a transfer of control. If the loop
- parameter is a constant (see above), then the indexing uses the
- default constant indexing function for the type of the iteratable
- object for the loop; otherwise it uses the default variable indexing
- function.
+ loop is left as a consequence of a transfer of control. For a
+ reverse container element iterator, the operations Last and Previous
+ are called rather than First and Next. If the loop parameter is a
+ constant (see above), then the indexing uses the default constant
+ indexing function for the type of the iteratable object for the loop;
+ otherwise it uses the default variable indexing function.
-
!discussion [NOT FULLY UPDATED -- SEE PROPOSAL FOR SOME NEWER DISCUSSION]
This is based on the earlier proposal and discussion recorded in AC-0112.TXT.
@@ -3949,3 +3964,15 @@
****************************************************************
+From: Tucker Taft
+Sent: Monday, October 25, 2010 10:17 AM
+
+Here is the update to AI05-0139, based on the minutes. [This is version /07
+of the AI - Editor.]
+Main changes are to use an Implicit_Dereference aspect rather than the
+"magic" interface Reference, and to try to make the wording more
+intelligible. Also, we now allow multi-dimensional arrays in an array
+component iterator, using the canonical ordering used for streams
+(last dimension varying fastest).
+
+****************************************************************
Questions? Ask the ACAA Technical Agent