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

Differences between 1.1 and version 1.2
Log of other versions for file ai12s/ai12-0254-1.txt

--- ai12s/ai12-0254-1.txt	2018/01/27 01:21:48	1.1
+++ ai12s/ai12-0254-1.txt	2018/02/01 07:01:15	1.2
@@ -1,4 +1,4 @@
-!standard A.18.32(0)                                  18-01-26  AI12-0254-1/01
+!standard A.18.32(0)                                  18-01-31  AI12-0254-1/02
 !class Amendment 18-01-26
 !status work item 18-01-26
 !status received 18-01-15
@@ -7,8 +7,8 @@
 !subject Bounded_Indefinite_Holders
-Add Bounded_Indefinite_Holder containers to allow the use of class-wide objects
-in safety critical environments where dynamic allocation and finalization
+The Bounded_Indefinite_Holder container is added to allow the use of
+class-wide objects in safety critical environments where dynamic allocation
 are not allowed.
@@ -52,68 +52,105 @@
-Introduce a package Bounded_Indefinite_Holders. This would have a similar
-specification to that of Indefinite_Holders, except:
+(See Summary.)
-* the addition of a generic formal parameter Max_Size_in_Storage_Elements
-  [note: this could be a discriminant instead, but it seems that this
-  value would usually be global to the entire program for a particular
-  element type so one would want it at the highest level possible.
-  note2: This value has to be in storage units as Ada does not allow
-  formulas on discriminants in discriminant-dependent components, and
-  this value may be used in a discriminant of a storage pool to allocate
-  an array of storage elements to store the object.]
-* the addition of preconditions to all of the ways to insert objects:
+Add subclause A.18.32:
-    procedure Replace_Element (Container : in out Holder;
-                               New_Item  : in     Element_Type)
-        with Pre => New_Item'Size/System.Storage_Unit <= Max_Size_in_Storage_Elements;
+The Generic Package Containers.Bounded_Indefinite_Holders
-* the addition of Implementation Advice that all memory allocation be static
-  and any finalization needed be trivial.
-  [note: We want to allow a storage pool (which needs finalization) to be used
-  to implement this container, but we want any such finalization to be trivial
-  so the compiler can implement it as if the type is not controlled.]
-* the addition of a permission for the implementation to raise Program_Error
-  if objects of the type are not stored contiguously. (Such objects probably
-  can only be allocated using a storage pool that supports arbitrary sized
-  allocations, which would defeat the purpose of this container for
-  analyzability.) It would be implementation-defined which objects are stored
-  this way (so that in theory it would have to be documented).
-This package can be used to store class-wide objects so long as the object
-is not larger than Max_Size_in_Storage_Elements (and it is contiguous).
-(1) We could define Bounded_Indefinite_xxx versions of all of the containers
-in a similar manner. This could allow objects of pretty much any contiguously
-allocated type to be stored in a container. (A possible implementation is
-found in the discussion section.)
-(2) A No_Controlled_Subcomponents aspect that ould be applied to any type.
-The type and any extensions of it is illegal if any component is controlled.
-[What about inside of a generic body? This property is not always known
-at compile-time - RLB] The purpose is to allow the compiler to not generate
-finalization overhead for class-wide objects of a tagged type with this
-aspect. (Otherwise, some future added object could have such an extension,
-so class-wide objects always have to be assumed to need finalization.)
-(3) A Maximum_Size aspect could be defined to apply to any tagged type. Such
-a type would not allow any extensions whose size would exceed the Maximum_Size.
-This would allow checking all instances of Bounded_Indefinite_Holders at
-compile time. (See the discussion for more on this idea.)
+The language-defined generic package Containers.Bounded_Indefinite_Holders
+provides a private type Holder and a set of operations for that type. It
+provides the same operations as the package Containers.Indefinite_Holders
+(see A.18.18), with the difference that the maximum storage is bounded.
+Static Semantics
+The declaration of the generic library package
+Containers.Bounded_Indefinite_Holders has the same contents and semantics as
+Containers.Indefinite_Holders except:
+* "with System.Storage_Elements; use System.Storage_Elements;" is added to
+   the context clause;
+* An additional generic parameter follows Element_Type:
+     Max_Element_Size_in_Storage_Elements : Storage_Elements.Storage_Count;
+  AARM Reason: This value is in Storage_Elements so that it can be used as a
+  discriminant on a storage pool object in the implementation of the object;
+  Ada doesn't allow discriminant dependent components to use formulas.
+  This is a generic parameter as it is a property of the Element_Type; the 
+  largest possible object of Element_Type is unlikely to be different for
+  different containers, so making it a discriminant (as Capacity is) provides
+  no useful capability.
+  End AARM Reason.
+* Add to the precondition of To_Holder and Replace_Element:
+     and (if New_Item'Size <=
+             Max_Element_Size_in_Storage_Elements * System.Storage_Unit
+          then (raise Program_Error))
+  AARM Reason: This ensures that an object that won't fit is not inserted into
+  the container.
+Bounded (Run-time) Errors
+It is a bounded error call To_Holder or Replace_Element on a bounded holder if
+the New_Item object would require more than one call to Allocate of a storage
+pool (see 13.11). Either Program_Error is raised by the operation, or execution
+proceeds normally. 
+  AARM Reason: Implementation of this container in Ada will probably
+  require the use of a special storage pool which only allows a single
+  allocation. If putting the New_Item object into the holder requires multiple
+  calls to Allocate, we allow raising Program_Error rather than requiring a
+  complex storage pool implementation that would effectively be the same as the
+  dynamic allocation that we are trying to avoid.
+  AARM Discussion: Whether this happens for a particular type depends on the
+  implementation. Formally, how many calls to Allocate are required is
+  unspecified; hopefully the implementation will document this anyway.
+It is a bounded error to assign from a bounded holder object while tampering
+with elements of that object is prohibited. Either Program_Error is raised by
+the assignment, execution proceeds with the target object prohibiting tampering
+with elements, or execution proceeds normally. 
+Implementation Requirements
+For each instance of Containers.Indefinite__Holders and each instance of
+Containers.Bounded_Indefinite_Holders, if the two instances meet the following
+conditions, then the output generated by the Holder'Output or Holder'Write
+subprograms of either instance shall be readable by the Holder'Input or
+Holder'Read of the other instance, respectively:
+  * the Element_Type parameters of the two instances are statically matching
+    subtypes of the same type; and
+  * the output generated by Element_Type'Output or Element_Type'Write is
+    readable by Element_Type'Input or Element_Type'Read, respectively
+    (where Element_Type denotes the type of the two actual Element_Type
+    parameters).
+Implementation Advice
+Bounded holder objects should be implemented without dynamic allocation and any
+finalization should be trivial unless Element_Type needs finalization. 
+AARM To Be Honest: Implementation of this container in Ada will probably
+require the use of a special storage pool. When we say "without dynamic
+allocation", we mean that this pool does not use heap memory and has a
+trivial finalization routine (that is, procedures Adjust and Finalize are null
+procedures). All storage pools are controlled, so we can't reasonably say
+that a bounded holder will not need finalization.
-** TBD.
+This container can be used to solve the Problem by putting the class-wide
+objects into holders. Assuming that they fit and are allocated contiguously,
+the holder can be used like any other fixed-size object.
 [1] The Bounded_Indefinite_Holder could be implemented in Ada using a storage
@@ -146,12 +183,14 @@
 regular bounded containers, sans the storage pool). No fragmentation could
 occur and the memory use is completely predictable.
-[3] Having a Maximum_Size aspect would allow checking the instances
-for problems at compile-time (although that would require some sort of
-different size check that the one proposed above).
+We've decided not to do this at this time, although such containers would help
+give predictable finalization in environments where memory usage has to be
+[3] Many users of Bounded_Indefinite_Holders would not want any runtime
+overhead to check that an object will fit into the container. A special
+language-defined mechanism is not needed to ensure this, because:
-However, in most circumstances, that isn't really necessary.
 (1) Most objects put into a container will have a known specific type. That
 means that they also have a known, compile-time size. Therefore, the
 precondition check includes all compile-time known values, and thus should be
@@ -175,12 +214,9 @@
 not appear in the generated code. If the correctness has been verified some
 other way, this will not cause any safety issues.
-No changes needed for package Bounded_Indefinite_Holders. If any of the
-optional new aspects
+No changes needed for package Bounded_Indefinite_Holders.
 !ACATS test
@@ -1117,6 +1153,59 @@
 I was just writing up the AI for this thread, it will be AI12-0254-1 (should be
 posted sometime today, Wisconsin time -- thus the next 6 hours).
+From: Niklas Holsti
+Sent: Sunday, January 28, 2018  5:50 AM [privately]
+Thanks for creating this AI from our ada-comment discussions.
+I have a very minor comment on the formulation of the precondition regarding the
+size of the elements. The AI gives this example:
+procedure Replace_Element (Container : in out Holder;
+                            New_Item  : in     Element_Type)
+     with Pre => New_Item'Size/System.Storage_Unit <= Max_Size_in_Storage_Elements;
+Is it certain that New_Item'Size is always a multiple of System.Storage_Unit at
+this point?
+If not, it seems to me that the precondition should be written as
+    New_Item'Size <= System.Storage_Unit * Max_Size_in_Storage_Elements;
+I also noticed that the ""!ASIS" section of the AI ends with an interrupted
+conditional sentence, perhaps from an editing glitch.
+From: Randy Brukardt
+Sent: Sunday, January 28, 2018  9:28 PM [privately]
+It's highly unlikely that the Size would not be an even number of units, but 
+since inverting the condition doesn't change much (other than introducing an
+overflow possibility), it probably is better written as you have it.
+Can I put your message into the public record? (That is, filed in the AI?)
+From: Niklas Holsti
+Sent: Monday, January 29, 2018 12:46 AM [privately]
+> It's highly unlikely that the Size would not be an even number of 
+> units, but since inverting the condition doesn't change much (other 
+> than introducing an overflow possibility), it probably is better written as
+> you have it.
+Good, thanks.
+> Can I put your message into the public record? (That is, filed in the 
+> AI?)
+Yes, of course. Apologies if this direct e-mail caused extra editing trouble
+for you.

Questions? Ask the ACAA Technical Agent