Version 1.5 of ai12s/ai12-0293-1.txt

Unformatted version of ai12s/ai12-0293-1.txt version 1.5
Other versions for file ai12s/ai12-0293-1.txt

!standard 13.13.1(1)          19-04-02 AI12-0293-1/03
!standard 13.13.1(9)
!standard 13.13.1(9.1/1)
!class Amendment 18-10-14
!status Amendment 1-2012 18-11-27
!status ARG Approved 8-0-0 18-10-22
!status work item 18-10-14
!status received 18-10-05
!priority Low
!difficulty Easy
!subject Add predefined FIFO_Streams packages
!summary
A group of 3 predefined child units of Ada.Streams are provided in order to provide capabilities which are useful on their own and, more specifically, in relation to AI12-0020-1.
!problem
With user-defined Image attributes as defined in AI12-0020-1, many users may have a common need for similar streaming-related functionality: a stream type which simply acts as a FIFO buffer and has operations for keeping track of the number of unread elements in the buffer and for efficiently emptying the buffer.
A similar need appears in many other cases. One common example is storing and retrieving Ada objects in an existing API (for example, the Windows Clipboard and the Windows Registry).
!proposal
Rather than having each user address these needs in their own way, a group of predefined child units of Ada.Streams are provided.
!wording
Add after 13.13.1(1):
The library package Ada.Streams has the following declaration:
Add after 13.13.1(9) (the end of the static semantics section):
Three additional packages provide stream implementations that do not make use of any file operations. These packages provide the same operations, with Streams.FIFO_Streams providing an abstract interface, and two child packages providing implementations of that interface. The difference is that for Streams.FIFO_Streams.Bounded, the maximum storage is bounded.
The library package Ada.Streams.FIFO_Streams has the following declaration:
package Ada.Streams.FIFO_Streams with Pure, Nonblocking is type FIFO_Stream is abstract new Root_Stream_Type with private;
function Element_Count (Stream : FIFO_Stream) return Stream_Element_Count is abstract;
procedure Clear (Stream : in out FIFO_Stream) is abstract; private ... -- not specified by the language end Ada.Streams.FIFO_Streams;
The library package Ada.Streams.FIFO_Streams.Unbounded has the following declaration:
package Ada.Streams.FIFO_Streams.Unbounded with Prelaborated, Nonblocking is type Stream_Type is new FIFO_Stream with private with Default_Initial_Condition => Element_Count (Stream_Type) = 0;
overriding procedure Read ( Stream : in out Stream_Type; Item : out Stream_Element_Array; Last : out Stream_Element_Offset) with Post => (declare Num_Read : constant Stream_Element_Count := Stream_Element_Count'Min (Element_Count(Stream)'Old, Item'Length); begin Last = Num_Read + Item'First - 1 and Element_Count (Stream) = Element_Count (Stream)'Old - Num_Read);
AARM Discussion: Num_Read is the number of elements read; this is the minimum of Item'Length and the number of available elements. Last then is determined by that, and the Element_Count decreases by the number of elements read.
overriding procedure Write ( Stream : in out Stream_Type; Item : in Stream_Element_Array) with Post => Element_Count (Stream) = Element_Count (Stream)'Old + Item'Length;
overriding function Element_Count (Stream : Stream_Type) return Stream_Element_Count;
overriding procedure Clear (Stream : in out Stream_Type) with Post => Element_Count (Stream) = 0;
private ... -- not specified by the language end Ada.Streams.FIFO_Streams.Unbounded;
The library package Ada.Streams.FIFO_Streams.Bounded has the following declaration:
package Ada.Streams.FIFO_Streams.Bounded with Pure, Nonblocking is
type Stream_Type (Max_Elements : Stream_Element_Count) is new FIFO_Stream with private with Default_Initial_Condition => Element_Count (Stream_Type) = 0;
overriding procedure Read ( Stream : in out Stream_Type; Item : out Stream_Element_Array; Last : out Stream_Element_Offset) with Post => (declare Num_Read : constant Stream_Element_Count := Stream_Element_Count'Min (Element_Count(Stream)'Old, Item'Length); begin Last = Num_Read + Item'First - 1 and Element_Count (Stream) = Element_Count (Stream)'Old - Num_Read);
overriding procedure Write ( Stream : in out Stream_Type; Item : in Stream_Element_Array) with Pre => Element_Count (Stream) + Item'Length <= Stream.Max_Elements or else (raise Constraint_Error), Post => Element_Count (Stream) = Element_Count (Stream)'Old + Item'Length;
overriding function Element_Count (Stream : Stream_Type) return Stream_Element_Count with Post => Element_Count'Result <= Stream.Max_Elements;
overriding procedure Clear (Stream : in out Stream_Type) with Post => Element_Count (Stream) = 0; private ... -- not specified by the language end Ada.Streams.FIFO_Streams.Bounded;
The Element_Count functions return the number of stream elements that are available for reading from the given stream.
The Read and Write procedures behave as described for package Ada.Streams above. Stream elements are read in FIFO (first-in, first-out) order; stream elements are available for reading immediately after they are written.
The Clear procedures remove any available stream elements from the given stream.
====
Add after 13.13.1(9.1/1):
Implementation Advice
Streams.FIFO_Streams.Bounded.Stream_Type objects should be implemented without implicit pointers or dynamic allocation.
AARM Reason: The Streams.FIFO_Streams.Bounded package is provided in orde to make available an alternative to the Streaams.FIFO_Streams.Unbounded package which gives more predictable memory usage.
!discussion
None yet.
!corrigendum 13.13.1(1)
Insert after the paragraph:
The abstract type Root_Stream_Type is the root type of the class of stream types. The types in this class represent different kinds of streams. A new stream type is defined by extending the root type (or some other stream type), overriding the Read and Write operations, and optionally defining additional primitive subprograms, according to the requirements of the particular kind of stream. The predefined stream-oriented attributes like T'Read and T'Write make dispatching calls on the Read and Write procedures of the Root_Stream_Type. (User-defined T'Read and T'Write attributes can also make such calls, or can call the Read and Write attributes of other types.)
the new paragraph:
The library package Ada.Streams has the following declaration:
!corrigendum 13.13.1(9)
Insert after the paragraph:
The Write operation appends Item to the specified stream.
the new paragraphs:
Three additional packages provide stream implementations that do not make use of any file operations. These packages provide the same operations, with Streams.FIFO_Streams providing an abstract interface, and two child packages providing implementations of that interface. The difference is that for Streams.FIFO_Streams.Bounded, the maximum storage is bounded.
The library package Ada.Streams.FIFO_Streams has the following declaration:
package Ada.Streams.FIFO_Streams with Pure, Nonblocking is
type FIFO_Stream is abstract new Root_Stream_Type with private;
function Element_Count (Stream : FIFO_Stream) return Stream_Element_Count is abstract;
procedure Clear (Stream : in out FIFO_Stream) is abstract;
private ... -- not specified by the language end Ada.Streams.FIFO_Streams;
The library package Ada.Streams.FIFO_Streams.Unbounded has the following declaration:
package Ada.Streams.FIFO_Streams.Unbounded with Prelaborated, Nonblocking is
type Stream_Type is new FIFO_Stream with private with Default_Initial_Condition => Element_Count (Stream_Type) = 0;
overriding procedure Read ( Stream : in out Stream_Type; Item : out Stream_Element_Array; Last : out Stream_Element_Offset) with Post => (declare Num_Read : constant Stream_Element_Count := Stream_Element_Count'Min (Element_Count(Stream)'Old, Item'Length); begin Last = Num_Read + Item'First - 1 and Element_Count (Stream) = Element_Count (Stream)'Old - Num_Read);
overriding procedure Write ( Stream : in out Stream_Type; Item : in Stream_Element_Array) with Post => Element_Count (Stream) = Element_Count (Stream)'Old + Item'Length;
overriding function Element_Count (Stream : Stream_Type) return Stream_Element_Count;
overriding procedure Clear (Stream : in out Stream_Type) with Post => Element_Count (Stream) = 0;
private ... -- not specified by the language end Ada.Streams.FIFO_Streams.Unbounded;
The library package Ada.Streams.FIFO_Streams.Bounded has the following declaration:
package Ada.Streams.FIFO_Streams.Bounded with Pure, Nonblocking is
type Stream_Type (Max_Elements : Stream_Element_Count) is new FIFO_Stream with private with Default_Initial_Condition => Element_Count (Stream_Type) = 0;
overriding procedure Read ( Stream : in out Stream_Type; Item : out Stream_Element_Array; Last : out Stream_Element_Offset) with Post => (declare Num_Read : constant Stream_Element_Count := Stream_Element_Count'Min (Element_Count(Stream)'Old, Item'Length); begin Last = Num_Read + Item'First - 1 and Element_Count (Stream) = Element_Count (Stream)'Old - Num_Read);
overriding procedure Write ( Stream : in out Stream_Type; Item : in Stream_Element_Array) with Pre => Element_Count (Stream) + Item'Length <= Stream.Max_Elements or else (raise Constraint_Error), Post => Element_Count (Stream) = Element_Count (Stream)'Old + Item'Length;
overriding function Element_Count (Stream : Stream_Type) return Stream_Element_Count with Post => Element_Count'Result <= Stream.Max_Elements;
overriding procedure Clear (Stream : in out Stream_Type) with Post => Element_Count (Stream) = 0;
private ... -- not specified by the language end Ada.Streams.FIFO_Streams.Bounded;
The Element_Count functions return the number of stream elements that are available for reading from the given stream.
The Read and Write procedures behave as described for package Ada.Streams above. Stream elements are read in FIFO (first-in, first-out) order; stream elements are available for reading immediately after they are written.
The Clear procedures remove any available stream elements from the given stream.
!corrigendum 13.13.1(9.1/1)
Insert after the paragraph:
If Stream_Element'Size is not a multiple of System.Storage_Unit, then the components of Stream_Element_Array need not be aliased.
the new paragraph:
Implementation Advice
Streams.FIFO_Streams.Bounded.Stream_Type objects should be implemented without implicit pointers or dynamic allocation.
!ASIS
No changed needed.
!ACATS test
ACATS C-Tests are needed to check that the new packages are supported.
!appendix

From: Steve Baird
Sent: Friday, October 5, 2018  5:02 PM

The attached is a new version of this AI, incorporating the feedback from the
Lisbon meeting.

It is actually 2 AIs (one of them hasn't been assigned a number yet) because
part of that Lisbon feedback was the suggestion that the AI should be split into
two parts. The other AI just defines some new predefined units,
Ada.Streams.FIFO_Streams and a couple of child units thereof.
[This is version /01 of that split AI - Editor.]

As usual, thanks to Randy for some helpful preliminary review. Also as usual,
don't blame him for any flaws.

****************************************************************

From: Randy Brukardt
Sent: Tuesday, December 4, 2018  11:52 PM

For the record:

I've made various editorial changes to this AI based on conversation with 
Tucker. To summarize:

(1) We usually start package definitions with "The library package 
Blah.Blah has the following definition:" This clause defines Ada.Streams 
and it doesn't include those words or any alternative (the RM does use several
other wordings, in particular that the package "exists"; this one seems more 
formal). So, fix that for all four of these packages (including the original 
one):

Add after 13.13.1(1):

The library package Ada.Streams has the following definition:


And introduce each new package separately:

The library package Ada.Streams.FIFO_Streams has the following definition:
The library package Ada.Streams.FIFO_Streams.Unbounded has the following 
  definition:
The library package Ada.Streams.FIFO_Streams.Bounded has the following 
  definition:

(2) The description of the difference between the Unbounded and Bounded 
packages is found in a comment (see next item). That's weird; we usually use
introductory text for that. So the introductory text for these units should 
discuss the differences between them.

   In addition, three packages provide stream implementations which do not 
   make use of any file operations. These three packages provide the same 
   operations, with Streams.FIFO_Streams providing an abstract interface, and 
   two child packages providing implementations of that interface. The 
   difference is that for Streams.FIFO_Streams.Bounded, the maximum storage is
   bounded.

(3) The large comment at the start of Ada.Streams.FIFO_Streams.Bounded is 
unnecessary. The part about the difference is covered above, and the part 
about not allowing dynamic allocation is given as Implementation Advice. 
Thus it is deleted.

(4) I noted that one of the comments in the Post condition as provided by 
Tucker was in the wrong place (the first comment belongs to the declaration
expression). Tucker replied that he thought that these comments belong in 
AARM notes, so I moved them there.

(5) "is" typically is on the same line as the aspects for a package, assuming 
those aspects are short (which is the case for Boolean aspects like Pure and 
Nonblocking).

****************************************************************

From: Randy Brukardt
Sent: Wednesday, December 5, 2018  1:01 AM

Got one more:

(6) "The Read and Write procedures behave as described in section 13.13.1."

But we put these packages into 13.13.1! This could be interpreted as a 
recursive reference.

It would be better to say "The Read and Write procedures behave as described 
for package Ada.Streams above."


P.S. It's not a "section", itís a "subclause". Grumble.

****************************************************************

Questions? Ask the ACAA Technical Agent