CVS difference for ai05s/ai05-0139-2.txt
--- ai05s/ai05-0139-2.txt 2009/12/09 00:40:29 1.1
+++ ai05s/ai05-0139-2.txt 2009/12/29 05:55:40 1.2
@@ -1,4 +1,4 @@
-!standard 5.5 09-12-08 AI05-0139-2/01
+!standard 5.5 09-12-28 AI05-0139-2/02
!class Amendment 09-02-13
!status work item 09-02-13
!status received 09-01-19
@@ -217,111 +217,6 @@
as an element *of* the array/container rather than as an index or cursor
*in* the sequence defined by the discrete range or iterator.
-USER DEFINED DEREFERENCE (AI05-141)
-
-The generic package Element_References might also be relevant to the
-notion of a user-defined "dereference" operation suggested in AI05-141.
-One of the significant problems with AI05-141 as it stands is that there
-is no operation called when the dereference is "completed." If we
-presume that the purpose of a user-defined dereference might be to
-implement some kind of software paging or persistence, then the page on
-which the designated object resides needs to be "pinned" in memory until
-the dereference is complete. But there is no user-defined cleanup
-routine provided in AI05-141. The Element_Reference and
-Element_Constant_Reference could provide for that, because they are
-derived from Limited_Controlled.
-
-So the suggestion is that, at least conceptually, there is an element
-reference object created, where the access discriminant comes from the
-result of the user-defined dereference, and when the resulting element
-reference object goes away, a user-defined cleanup routine would be
-called, perhaps to "unpin" the page on which the designated object
-resides.
-
-For practical reasons, rather than having the implementor of the storage
-pool provide extensions of Element_Reference and
-Element_Constant_Reference, they would instead just provide dereference
-operations similar to what is suggested in AI05-141, which takes in an
-"address" that might in fact not really be a machine address but rather
-an address-sized "locator" for the object that was returned by Allocate,
-and produces as a result a true machine address, suitable for use as the
-access discriminant of an element reference object. There would be two
-of these operations, one for dereferencing an access-to-variable value,
-and one for dereferencing an access-to-constant value, and the work to
-be done might be quite different in the two cases (presuming, for
-instance, that the underlying storage pool is doing software paging).
-In addition to the dereference operations, the implementor of the
-storage pool would provide two "cleanup" routines, which would be called
-when the hypothetical element reference object goes out of scope, again
-one for access-to-variable and one for access-to-constant.
-
-The import and export operations suggested in AI05-141 might still be
-provided for conversion to/from longer-lived access values.
-
-AI05-141 suggested that the dereference operation be accomplished
-through an IN-OUT parameter of type System.Address, allowing it to be
-the null procedure by default. Given the number of operations we
-are now talking about, we would suggest defining a distinct
-("magic") descendant of Root_Storage_Pool that had these extra
-operations, two of which would more naturally be functions than procedures. The
-cleanup operations would ideally take three parameters, the storage
-pool, the original access value (which might not be a real machine
-address), and the "real" machine address produced by the dereference
-operation. Having both the original and the dereferenced value should
-simplify the cleanup operation.
-
-Here is a possible package System.Managed_Storage_Pools:
-
- with System.Storage_Pools;
- package System.Managed_Storage_Pools is
- type Root_Managed_Storage_Pool is abstract new
- Storage_Pools.Root_Storage_Pool with private;
-
- -- usual Allocate/Deallocate/Storage_Size routines,
- -- inherited as abstract
-
- function Dereference(Pool : access Root_Managed_Storage_Pool;
- Access_Value : System.Address) return System.Address is abstract;
-
- function Constant_Dereference(Pool : access Root_Managed_Storage_Pool;
- Access_Constant_Value : System.Address) return System.Address is abstract;
-
- procedure Cleanup_Dereference(Pool : access Root_Managed_Storage_Pool;
- Access_Value : System.Address; Address_Value : System.Address) is null;
-
- procedure Cleanup_Constant_Dereference(Pool : access Root_Managed_Storage_Pool;
- Access_Value : System.Address; Address_Value : System.Address) is null;
-
- function Export(Pool : access Root_Managed_Storage_Pool;
- Access_Value : System.Address) return System.Address is abstract;
-
- function Import(Pool : access Root_Managed_Storage_Pool;
- Address_Value : System.Address) return System.Address is abstract;
-
- private
- -- not specified
- end System.Managed_Storage_Pools;
-
-Note that the use of element references is completely behind the scenes with
-this approach. These access values work just like "regular" access values,
-but behind the scenes:
-
- * on each dereference or conversion to an access parameter or
- access discriminant they get temporarily made available as "true"
- addresses via the user-defined dereference routines, and then get
- cleaned up.
-
- * on conversion to an access type that is not for an access parameter
- or access discriminant, if the storage pool of the new access type
- is different, they get permanently converted into a "normal"
- address value via the Export function (which might raise PROGRAM_ERROR).
-
- * on conversion from an access type of a different storage pool, the
- new access values are produced by calling the Import function, which might
- raise PROGRAM_ERROR if importing from another storage pool is not
- supported.
-
-
!wording [REMOVED FOR NOW]
!discussion [NOT UPDATED -- SEE PROPOSAL FOR SOME NEWER DISCUSSION]
@@ -615,8 +510,176 @@
!appendix
From: Tucker Taft
-Sent: Tuesday, December 8, 2009 5:01 PM
+Thoughts on Iterators, 8-Nov-2009, for ARG meeting in St. Pete
+
+Relevant players in the game:
+
+ Container, Cursor, Iterator, Element.
+
+-------------
+
+ for Element in [reverse] Container loop
+ ... -- body of loop
+ end loop;
+
+is equiv to:
+
+ declare
+ Iterator : Iterator_Type := Iterate(Container);
+ Cursor : Cursor_Type := First(Iterator);
+ begin
+ while Has_Element(Cursor) loop
+ declare
+ Element : Element_Type renames Container(Cursor);
+ begin
+ ... -- body of loop
+ Cursor := Next(Iterator, Cursor);
+ end;
+ end loop;
+ end;
+
+or...
+
+ declare
+ Iterator : Iterator_Type := Iterate(Container);
+ begin
+ while More(Iterator) loop
+ declare
+ Cursor : Cursor_Type := Get_Next(Iterator'Access);
+ Element : Element_Type renames Container(Cursor);
+ begin
+ ... -- body of loop
+ end;
+ end loop;
+ end;
+
+---------
+
+ Container(Cursor)
+
+ is equiv to:
+
+ Element_{Ref,CRef}(Container, Cursor).Data.all
+
+ for Cursor in Special_Iterator(Container) loop
+ Put(Container(Cursor));
+ end loop;
+
+---------
+
+ for Element in Container loop
+ Put(Element);
+ end loop;
+
+ is equiv to:
+
+ for Cursor in Default_Iterator(Container) loop
+ declare
+ Element : Element_Type renames Container(Cursor);
+ begin
+ Put(Element);
+ end;
+ end loop;
+
+ similarly:
+
+ for Element in Array_Obj loop
+ Put(Element);
+ end loop;
+
+ is equiv to:
+
+ for I in Array_Obj'Range(1) loop
+ for J in Array_Obj'Range(2) loop
+ ...
+ declare
+ Element : Array_Obj_Component_Type renames Array_Obj(I, J, ...);
+ begin
+ Put(Element);
+ end;
+ ...
+ end loop;
+ end loop;
+
+
+---------
+
+ package Iterators is new Ada.Iterator_Interfaces(Cursor_Type, No_Element);
+ type Iterator_Type is new Iterators.Reversible_Iterator with ...
+
+ package Containers is new
+ Ada.Container_Interfaces(Iterators, Iterator_Type, Element_Type, Element_Reference);
+ type Container_Type is new Containers.Container with ...
+
+ generic
+ with package Iterators is new Ada.Iterator_Interfaces(<>);
+ type Iterator_Type is new Iterators.Reversible_Iterator with private;
+ type Element_Type(<>) is limited private;
+ type Element_Reference(Data : access Element_Type) is limited private;
+ type Element_Constant_Reference(Data : access constant Element_Type) is limited private;
+ package Ada.Container_Interfaces is
+ type Container is limited interface;
+ function Default_Iterator(C : Container) return Iterator_Type is abstract;
+ function Element_Ref(C : aliased in out Container; Cursor : Iterators.Cursor)
+ return Element_Reference is abstract;
+ function Element_CRef(C : aliased in Container; Cursor : Iterators.Cursor)
+ return Element_Constant_Reference is abstract;
+ end Ada.Container_Interfaces;
+
+----------
+
+ generic
+ type Cursor is private;
+ No_Element : in Cursor;
+ package Ada.Iterator_Interfaces is
+
+ type Basic_Iterator is limited interface;
+ function First (Object : Basic_Iterator) return Cursor;
+ function Next (Object : Basic_Iterator; Position : Cursor) return Cursor;
+
+ type Reversible_Iterator is limited interface and Basic_Iterator;
+ function Last (Object : Reversible_Iterator) return Cursor;
+ function Previous (Object : Reversible_Iterator; Position : Cursor) return Cursor;
+
+ end Ada.Iterator_Interfaces;
+
+****************************************************************
+
+From: Robert Dewar
+Sent: Sunday, November 8, 2009 10:26 AM
+
+Equivalent always makes me nervous. Are we sure we can make this strong a statement?
+
+****************************************************************
+
+From: Tucker Taft
+Sent: Sunday, November 8, 2009 11:40 AM
+
+This is more like the definition of "new T" when T has a user-defined storage pool.
+It is equivalent to a call on Allocate because its semantics are defined as calling
+Allocate.
+
+For the proposed syntax for iterators and indexing, their semantics will be defined
+in terms of calls on certain subprograms, etc.
+
+****************************************************************
+
+From: Robert Dewar
+Sent: Sunday, December 8, 2009 1:14 PM
+
+> This is more like the definition of "new T" when T has a user-defined
+> storage pool. It is equivalent to a call on Allocate because its
+> semantics are defined as calling Allocate.
+
+I think it is fine to say "the behavior is as though xyz was called bla bla".
+I just think we often get ourselves in trouble if the formal definition uses the
+word equivalent, it's such a strong word from a formal point of view.
+
+****************************************************************
+
+From: Tucker Taft
+Sent: Tuesday, December 8, 2009 5:01 PM
Here is a new variant for AI05-139 on user-defined iterators, etc. [This is
version /01 of this AI - ED.] It is based on all the earlier proposals,
Questions? Ask the ACAA Technical Agent