CVS difference for ais/ai-30302.txt

Differences between 1.4 and version 1.5
Log of other versions for file ais/ai-30302.txt

--- ais/ai-30302.txt	2004/05/29 00:38:42	1.4
+++ ais/ai-30302.txt	2004/06/10 05:39:58	1.5
@@ -12020,12 +12020,895 @@
 ****************************************************************
 
 From: Matthew Heaney
-Sent: Saturday, May 13, 2004  9:31 AM
+Sent: Wednesday, June 9, 2004  9:40 AM
 
+I have a few comments on the Phoenix release of AI-302 (2004-04-29
+AI95-00302-03/03).   Each comment is bracketed with "MJH:" and "ENDMJH."
+pairs, and immediately follows the item to which it refers.
+
+-Matt
+
+
+A.17.2 The Package Containers.Vectors
+
+generic
+...
+package Ada.Containers.Vectors is
+...
+    function To_Vector (Count : Size_Type) return Vector;
+
+MJH:
+I wasn't absolutely sure whether the formal param should be named
+"Count" or "Length".   The term "count" is used elsewhere in this spec,
+but here it actually specifies the length of the vector object returned
+by the function.
+ENDMJH.
+
+
+    function To_Vector
+      (New_Item : Element_Type;
+       Count    : Size_Type) return Vector;
+
+MJH:
+This is formatted inconsistently.  It should be:
+
+    function To_Vector (New_Item : Element_Type;
+                        Count    : Size_Type)
+      return Vector;
+ENDMJH.
+
+
+
+
+    procedure Set_Length (Container : in out Vector;
+                          Length    : in     Size_Type);
+
+MJH:
+Should we include following operation too?
+
+    procedure Set_Length (Container : in out Container_Type;
+                          Length    : in     Size_Type;
+                          New_Item  : in     Element_Type);
+
+This would allow the user to specify an actual value for the new
+elements, if the length of the vector is increased.
+ENDMJH.
+
+
+    procedure Swap (Container : in out Vector;
+                    I, J      : in     Cursor);
+
+MJH:
+Should be weaken the precondition, allowing the case in which both I and
+J have the value No_Element?  In that case Swap would be a no-op.
+(Right now I think it's an error.)
+ENDMJH.
+
+
+function To_Index (Position  : Cursor) return Index_Type'Base;
+
+If Position is No_Element, Constraint_Error is propagated. Otherwise, the
+index (within its containing vector) of the element designated by Cursor is
+returned.
+
+MJH:
+Should this be reworded to say "If Has_Element (Position) is False..."?
+ENDMJH.
+
+MJH:
+Also, note that if Position may only designate an active element in the
+container, then we don't need to return Index_Type'Base.  We can
+strengthen the post-condition by returning Index_Type.
+ENDMJH.
+
+AARM Note: This implies that the index is determinable from a bare cursor
+alone. The basic model is that a vector cursor is implemented as a record
+containing an access to the vector container and a index value. This does
+constrain implementations, but it also allows all of the cursor operations
+to be defined in terms of the corresponding index operation (which should be
+primary for a vector).
+
+MJH:
+It's not clear if CE is supposed to be propagated if Position does not
+specify a value within the range of currently active elements of
+Container.  For example:
+
+declare
+    V : Vector;
+    C : Cursor;
+    I : Index_Type'Base;
+begin
+    Append (V, E);
+    C := First (V);
+    Delete_First (V);
+    I := To_Index (C); --valid?
+end;
+ENDMJH.
+
+
+generic
+    with procedure Process (Element : in out Element_Type) is <>;
+procedure Generic_Update_by_Index (Container : in Vector;
+                                    Index     : in Index_Type'Base);
+
+If Index is not in the range First_Index (Container) .. Last_Index
+(Container),
+then Constraint_Error is propagated. Otherwise, it calls the generic actual
+bound to Process with the element at position Index as the parameter. Any
+exceptions raised by Process are propagated.
+
+If Element_Type is unconstrained and definite, then the Element parameter
+shall be unconstrained.
+
+AARM Note: This means that the elements cannot be aliased nor directly
+allocated from the heap; it must be possible to change the discriminants
+of the element in place.
+
+The element at position Index is not an empty element after successful
+completion of this operation.
+
+AARM Note: Since reading an empty element is a bounded error, attempting to
+use this procedure to replace empty elements may fail. Use Replace_Element
+to do that reliably.
+
+MJH:
+What did we conclude about this?  I thought using Generic_Update to
+initialize a space element was ok?  (Or was that only for a list?)
+
+Is this AARM Note in conflict with the note below?
+ENDMJH.
+
+
+
+procedure Replace_Element (Position : in Cursor;
+                            By       : in Element_Type);
+
+This function assigns the value By to the element designated by Position.
+If Position equals No_Element, then Constraint_Error is propagated.
+Any exceptions raised during the assignment are propagated. The element
+designated by Position is not an empty element after successful
+completion of
+this operation.
+
+AARM Note: Replace_Element, Generic_Update, and Generic_Update_by_Index are
+only ways that an element can change from empty to non-empty.
+
+MJH:
+Is this AARM Note in conflict with the note above?
+ENDMJH.
+
+
+
+procedure Insert (Container : in out Vector;
+                   Before    : in     Cursor;
+                   New_Item  : in     Vector);
+
+If Before is No_Element, then is equivalent to Insert (Container,
+Index_Type'Succ (Last_Index (Container)), New_Item); otherwise is
+equivalent to Insert (Container, To_Index (Before), New_Item);
+
+MJH:
+Should this be reworded to say "Has_Element (Before) = False..." instead?
+ENDMJH.
+
+MJH:
+We probably need to say here that if New_Item is empty, then then
+operation has no effect.  Otherwise there's a constraint check if
+Before=No_Element (IT'Succ (Cont.Last)) can fail, when Cont.Last=IT'Last).
+ENDMJH.
+
+MJH:
+Here and elsewhere the equivalence is in terms of To_Index, but this
+might be too restrictive.  Before is allowed to be IT'Succ (Cont.Last),
+but I think To_Index raises an exception if it has that value.
+ENDMJH.
+
+
+procedure Insert (Container : in out Vector;
+                   Before    : in     Cursor;
+                   New_Item  : in     Vector;
+                   Position  :    out Cursor);
+
+Create a temporary (call it Temp_Index) and set it to Index_Type'Succ
+(Last_Index (Container)) if Before equals No_Element, and To_Index (Before)
+otherwise. Then Insert (Container, Before, New_Item) is called, and finally
+Position is set to To_Cursor (Container, Temp_Index).
+
+AARM Note: The messy wording because Before is invalidated by Insert, and we
+don't want Position to be invalid after this call. An implementation
+probably
+only needs to copy Before to Position.
+
+MJH:
+See note above.
+ENDMJH.
+
+
+
+procedure Insert (Container : in out Vector;
+                   Before    : in     Cursor;
+                   New_Item  : in     Element_Type;
+                   Count     : in     Size_Type := 1);
+
+Equivalent to Insert (Container, Before, To_Vector (New_Item, Count));
+
+MJH:
+See note above when Count = 0.  (We should state explicitly that if
+Count=0, then the operation is a no-op, and there are no constraint
+checks or any other exceptions.  The value or state of cursor Before is
+not checked or otherwise considered, when Count=0.)
+ENDMJH.
+
+
+procedure Insert (Container : in out Vector;
+                   Before    : in     Cursor;
+                   New_Item  : in     Element_Type;
+                   Position  :    out Cursor;
+                   Count     : in     Size_Type := 1);
+
+Equivalent to Insert (Container, Before, To_Vector (New_Item, Count),
+Position);
+
+MJH:
+See not above re count=0.
+ENDMJH.
+
+
+procedure Prepend (Container : in out Vector;
+                    New_Item  : in     Vector;
+                    Count     : in     Size_Type := 1);
+
+Equivalent to Insert (Container, Index_Type'First, New_Item).
+
+MJH:
+Typo: this declaration should look like this:
+
+procedure Prepend (Container : in out Vector;
+                    New_Item  : in     Vector);
+ENDMJH.
+
+
+
+
+procedure Insert_Space (Container : in out Vector;
+                         Before    : in     Cursor;
+                         Position  :    out Cursor;
+                         Count     : in     Size_Type := 1);
+
+Create a temporary (call it Temp_Index) and set it to
+Index_Type'Succ (Last_Index (Container)) if Before equals No_Element, and
+To_Index (Before) otherwise. Then Insert_Space (Container, Temp_Index,
+Count) is called, and finally Position is set to To_Cursor (Container,
+Temp_Index).
+
+MJH:
+See note above re count=0.
+ENDMJH.
+
+
+
+procedure Delete (Container : in out Vector;
+                   Position  : in out Cursor;
+                   Count     : in     Size_Type := 1);
+
+If Count is 0, the operation has no effect. Otherwise is equivalent to
+Delete (Container, To_Index (Position), Count).
+
+MJH:
+Here and elsewhere when Count is 0, I think we need to specify what
+value for Position is returned.
+ENDMJH.
+
+MJH:
+If Count is non-zero, then how should we handle a Position that does
+not designate an active element.  Above, we raise CE.  Is this correct?
+ENDMJH.
+
+MJH:
+We probably need to say here that Position is set to Position.Index if
+Index continues to designate an element in the container, or No_Element
+if Position was part of the entire tail that was deleted.
+ENDMJH.
+
+
+
+procedure Delete_Last (Container : in out Vector;
+                        Count     : in     Size_Type := 1);
+
+If Length (Container) < Count then is equivalent to
+Delete (Container, Index_Type'First, Count); otherwise
+is equivalent to Delete (Container,
+Index_Type'Val(Index_Type'Pos(Last_Index(Container)) - Count + 1), Count).
+
+MJH:
+If Length (C) >= Count, then isn't it easier to simply say that it's
+the same as Clear (C)?
+ENDMJH.
+
+
+Returns the value Index_Type'First.
+
+MJH:
+What operation does this description refer to?  I assume it's First_Index.
+ENDMJH.
+
+
+procedure Swap (Container : in Vector;
+                 I, J      : in Cursor);
+
+Equivalent to Swap (Container, To_Index (I), To_Index (J)).
+
+MJH:
+I mentioned this above.  We might want to weaken the precondition of
+Swap, to allow cursors both of which Has_Element returns False to be
+swapped; that is, if both are No_Element, then Swap should be a no-op.
+ENDMJH.
+
+
+
+
+function Find (Container : Vector;
+                Item      : Element_Type;
+                Index     : Index_Type'Base := Index_Type'First)
+    return Index_Type'Base;
+
+Searches the elements of Container for an element equal to Item,
+starting at position Index. If Index is less than Index_Type'First,
+then Constraint_Error is propagated. If there are no elements in the
+range Index .. Last_Index (Container) equal to Item, then Find returns
+Index_Type'Succ (Last_Index (Container)). Otherwise, it returns the index of
+he matching element.
+
+MJH:
+Here and in the other find ops we should probably weaken the precondition,
+such that if the container is empty, we return failure status
+immediately, without vetting or otherwise interrogating the value of Index.
+ENDMJH.
+
+function Find (Container : Vector;
+                Item      : Element_Type;
+                Position  : Cursor := No_Element)
+    return Cursor;
+
+Searches the elements of Container for an element equal to Item,
+starting at the first element if Cursor equals No_Element, and at
+the element designated by Cursor otherwise, and searching to the last
+element in Container. If an item equal to Item is found, Find returns a
+cursor designating the first element found equal to Item. If no such item is
+found, it returns No_Element.
+
+MJH:
+Suppose Has_ELement (Position) = False, is this an error (raise CE), or
+does it count as No_ELement (start from IT'First)?
+NDMJH.
+
+
+
+A.17.3 The Package Containers.Doubly_Linked_Lists
+
+
+procedure Delete (Container : in out List;
+                   Position  : in out Cursor;
+                   Count     : in     Size_Type := 1);
+
+If Position equals No_Element, the operation has no effect. Otherwise
+Delete removes Count nodes starting at the node designated by Position
+from Container (or all of the nodes if there are less than Count nodes
+starting at Position). Any exceptions raised during deallocation of internal
+storage are propagated.
+
+MJH:
+Is this inconsistent with vector?  I think we made it an error if
+Size > 0 and Position = No_Element.   (I don't know which way we should
+go, I just wanted to bring it up.)
+ENDMJH.
+
+
+
+procedure Swap (Container : in out List;
+                 I, J      : in     Cursor);
+
+Swap exchanges the nodes designated by I and J.
+
+MJH:
+Allow I and J to both assume the value No_Element?
+ENDMJH.
+
+MJH:
+Does this swap nodes (by exchanging pointers, or does it
+eave the nodes in their relative positions, and merely
+exchange the values of the elements on those nodes?
+ENDMJH.
+
+
+
+A.17.5 The Package Containers.Ordered_Sets
+
+generic
+...
+package Ada.Containers.Ordered_Sets is
+...
+    procedure Insert (Container : in out Set;
+                      New_Item  : in     Element_Type;
+                      Position  :    out Cursor;
+                      Success   :    out Boolean);
+
+    --MJH:
+    --A nice function might be:
+    --procedure Insert (Container : in out Set;
+    --                  New_Item  : in     Element_Type);
+    --This is a convenience function that omits the last two params.
+    --ENDMJH.
+
+
+    function Is_Subset (Item      : Set;
+                        Container : Set)
+       return Boolean;
+
+MJH:
+Clarify the results when one or both of the params are empty sets.  (I
+assume that in set theory, the subset operation is defined on a pair
+ull sets, but I don't remember offhand what the value is.)
+ENDMJH.
+
+
+    function Is_Disjoint (Item      : Set;
+                          Container : Set)
+       return Boolean;
+
+MJH:
+As above, clarify the results when one or both of the params are empty sets.
+ENDMJH.
+
+****************************************************************
+
+From: Randy Brukardt
+Sent: Wednesday, June 9, 2004  11:59 PM
+
+A couple of comments on Matt's comments (I'm not going to comment on typos
+and the like, it's too late to fix them before the meeting, and they're
+recorded).
+
+> function To_Index (Position  : Cursor) return Index_Type'Base;
+>
+> If Position is No_Element, Constraint_Error is propagated. Otherwise, the
+> index (within its containing vector) of the element designated by
+> Cursor is
+> returned.
+>
+> MJH:
+> Should this be reworded to say "If Has_Element (Position) is False..."?
+> ENDMJH.
+
+I don't think so. It's usually a bounded error to use a cursor that doesn't
+point at an active element. That allows either raising Constraint_Error or
+doing something else. You explain why below...
+
+...
+> MJH:
+> It's not clear if CE is supposed to be propagated if Position does not
+> specify a value within the range of currently active elements of
+> Container.  For example:
+>
+> declare
+>     V : Vector;
+>     C : Cursor;
+>     I : Index_Type'Base;
+> begin
+>     Append (V, E);
+>     C := First (V);
+>     Delete_First (V);
+>     I := To_Index (C); --valid?
+> end;
+> ENDMJH.
+
+It's very clear that this is a bounded error, and we're *not* requiring
+implementations to detect this case (in this specific example, because
+Delete is called on an element to the left). But we *allow* it to be
+detected. I thought we had agreed that we didn't want the overhead of
+detecting these kinds of errors.
+
+The organization of the standard requires us to put the bounded error text
+far away from this subprogram (which is unfortunate), but since it is a
+general rule, that isn't too bad.
+
+The bounded error rules apply to *all* uses of cursors except Has_Element,
+so the answer is the same for all other routines.
+
+> generic
+>     with procedure Process (Element : in out Element_Type) is <>;
+> procedure Generic_Update_by_Index (Container : in Vector;
+>                                     Index     : in Index_Type'Base);
+...
+> MJH:
+> What did we conclude about this?  I thought using Generic_Update to
+> initialize a space element was ok?  (Or was that only for a list?)
+
+It's also in the bounded error section. I think we concluded that we
+couldn't allow Generic_Update, because it implies a read of the element. I
+tried to find a way to avoid that, but if we did, then it wouldn't be
+"Update" any more.
+
+...
+> AARM Note: Replace_Element, Generic_Update, and
+> Generic_Update_by_Index are
+> only ways that an element can change from empty to non-empty.
+>
+> MJH:
+> Is this AARM Note in conflict with the note above?
+> ENDMJH.
+
+Someone asked that in April. Sheesh. Generic_Update is in the list because
+it's a bounded error to call it, and *if* it doesn't raise an exception,
+*then* it changes the element to non-empty. But you can't depend that it
+doesn't raise an exception.
+
+...
+> procedure Delete (Container : in out List;
+>                    Position  : in out Cursor;
+>                    Count     : in     Size_Type := 1);
+>
+> If Position equals No_Element, the operation has no effect. Otherwise
+> Delete removes Count nodes starting at the node designated by Position
+> from Container (or all of the nodes if there are less than Count nodes
+> starting at Position). Any exceptions raised during deallocation
+> of internal storage are propagated.
+>
+> MJH:
+> Is this inconsistent with vector?  I think we made it an error if
+> Size > 0 and Position = No_Element.   (I don't know which way we should
+> go, I just wanted to bring it up.)
+> ENDMJH.
+
+Yes, it seems to be inconsistent with Vector. Vector raises C_E for indexes
+out of range (of course), and the cursor version mimics that behavior,
+because it really can't do anything else. So I'd say this probably out to
+raise C_E as well.
+
+****************************************************************
+
+From: Pascal Obry
+Sent: Wednesday, June 9, 2004  10:43 AM
+
+One feedback after migrating AWS to the AI302 reference implementation. The
+procedure Size and Length are really too confusing. I have at least 2 times
+used the wrong one (using Size instead of Length). Length is ok, maybe Size
+should be renamed Hash_Size or something like that.
+
+For the record:
+
+   function Size (Container : Vector) return Size_Type;
+   -> returns the size of the hash table (number of buckets)
+
+   function Length (Container : Vector) return Size_Type;
+   -> returns the number of item in the vector
+
+Also, as Size and Resize are low-level stuff I would put those routines at the
+end of the package. Another solution would be to put such routines into a
+child package. Thoughts ?
+
+****************************************************************
+
+From: Matthew Heaney
+Sent: Wednesday, June 9, 2004  2:55 PM
+
+Pascal Obry wrote:
+
+> One feedback after migrating AWS to the AI302 reference implementation. The
+> procedure Size and Length are really too confusing. I have at least 2 times
+> used the wrong one (using Size instead of Length). Length is ok, maybe Size
+> should be renamed Hash_Size or something like that.
+
+It's not unlike for an array, which has both 'Length and 'Size attributes.
+
+
+> For the record:
+> 
+>    function Size (Container : Vector) return Size_Type;
+>    -> returns the size of the hash table (number of buckets)
+
+No.  The Size of a hashed map container specifies the maximum length 
+(number of items) before which automatic expansion of the internal hash 
+table occurs.  It does *not* specify the number of buckets in the hash 
+table.
+
+(It is indeed the case that in the AI-302 reference implementation, 
+function Size happens to return the number of hash table buckets, but 
+that is a characteristic of that particular implementation.  It is not 
+guaranteed to be the case for all implementations.)
+
+
+>    function Length (Container : Vector) return Size_Type;
+>    -> returns the number of items in the vector
+
+Technically it's the "number of active elements," but let's not quibble.
+
+
+> Also, as Size and Resize are low-level stuff I would put those routines at the
+> end of the package. Another solution would be to put such routines into a
+> child package. Thoughts ?
+
+It's a bad idea.
+
+****************************************************************
+
+From: Pascal Obry
+Sent: Wednesday, June 9, 2004  3:26 PM
+
+What is a bad idea ? I have proposed 3 things :
+
+- rename Size and keep Length
+
+- move the Size and Resize to the end of the API
+
+- move the Size and Resize routines into a child package
+
+I hope that you at least see that Size/Length having the same prototype
+is dangerous. It is even more dangerous that using Size instead of Length
+can stay undetected for some time...
+
+****************************************************************
+
+From: Matthew Heaney
+Sent: Wednesday, June 9, 2004  3:44 PM
+
+I was referring to the suggestion in your last paragraph to make Size 
+and Resize child subprograms.
+
+****************************************************************
+
+From: Pascal Obry
+Sent: Wednesday, June 9, 2004  3:53 PM
+
+Ok, I also think it is bad idea, was there for completeness :)
+
+****************************************************************
+
+From: Tucker Taft
+Sent: Wednesday, June 9, 2004  3:34 PM
+
+How about "Maximum_Length" and "Set_Maximum_Length" in place
+of Size and Resize?
+
+****************************************************************
+
+From: Pascal Obry
+Sent: Wednesday, June 9, 2004  3:42 PM
+
+Fine with me.
+
+****************************************************************
+
+From: Robert A Duff
+Sent: Wednesday, June 9, 2004  7:23 PM
+
+> What is a bad idea ? I have proposed 3 things :
+
+I don't know Matt's opinion, but here's mine:
+
+> - rename Size and keep Length
+
+Good idea.  I think this is fairly important.
+
+> - move the Size and Resize to the end of the API
+
+Good idea.  Not important.
+
+> - move the Size and Resize routines into a child package
+
+Bad idea.
+
+> I hope that you at least see that Size/Length having the same prototype
+> is dangerous. It is even more dangerous that using Size instead of Length
+> can stay undetected for some time...
+
+Yes, I agree.  The name Size should be changed to something else,
+something nobody would mistake for Length.
+
+****************************************************************
+
+From: Nick Roberts
+Sent: Wednesday, June 9, 2004  9:06 PM
+
+> How about "Maximum_Length" and "Set_Maximum_Length" in place
+> of Size and Resize?
+
+I endorse this suggestion. Specifically, I suggest:
+
+(1) In package Ada.Containers, change:
+
+   type Size_Type is range 0 .. <implementation-defined>;
+
+to:
+
+   type Count_Type is range 0 .. <implementation-defined>;
+
+and all subsequent uses of Size_Type be renamed to Count_Type.
+
+(2) In packages Ada.Containers.Vectors, Ada.Containers.Hashed_Maps, (and
+Ada.Containers.Indefinite_Hashed_Maps,) change:
+
+   function Size (Container : Vector|Map) return Size_Type;
+
+to:
+
+   function Maximum_Length (Container : Vector|Map) return Count_Type;
+
+and change:
+
+   procedure Resize (Container : in out Vector|Map;
+                     Size      : in     Size_Type);
+
+to:
+
+   procedure Set_Maximum_Length (Container : in out Vector|Map;
+                                 To        : in     Count_Type);
+
+(3) Change all references to the term 'size' to 'maximum length'. For
+example, change the second paragraph of the proposed A.17.2 from:
+
+   A vector container object manages an unconstrained internal array, which
+   expands as necessary as items are inserted. The *size* of a vector
+   corresponds to the total length of the internal array, and the *length*
+   of a vector corresponds to the number of active elements in the internal
+   array.
+
+to:
+
+   A vector container object conceptually manages an unconstrained internal
+   array, which expands as necessary as items are inserted. The *maximum
+   length* of a vector corresponds to the total length of this conceptual
+   internal array, and the *length* of a vector corresponds to the number
+   of active elements within this array.
+
+An alternative to 'maximum length' and [Set_]Maximum_Length throughout all
+the above could be 'allocated length' and [Set_]Allocated_Length.
+
+This issue has been argued about before. Some said that the term 'size'
+clashed with the predominant existing usage of the term in connection with
+the number of storage units used up by objects and program units. Others
+said that many terms are 'overloaded' in the RM, and the term 'size' is
+already used to mean other things in some places.
+
+However, I quite strongly feel that an alternative term could easily be
+chosen, and it would be very desirable to do so, to avoid just the kind of
+confusion Pascal reported.
+
+I must also add that I still think it is unjustified that the size/maximum
+length of a vector or map is not permitted to be reduced by any
+implementation. Specifically, I advocate that Resize/Set_Maximum_Length be
+allowed (by the standard) to reduce the size/maximum length of a vector or
+map, but that implementations are permitted to ignore such reductions if
+they wish. In fact, I would suggest that the current wording (forbidding
+such reductions) is silly in a way, because I doubt very much that there
+will
+ever be an ACATS test for it. On that basis, I also question the wording
+"Resize sets the size of Container to a value which is at least the value
+Size", which could more sensibly be changed to "Resize sets the size of
+Container to approximately the value Size".
+
+(4) I suggest the paragraph:
+
+ If Size (Container) is equal to or greater than Size, the operation does
+ nothing. Otherwise Resize sets the size of Container to a value which is
+ at least the value Size, expanding the internal array to hold Size
+ elements. Expansion will require allocation, and possibly copying and
+ deallocation of elements. Any exceptions raised by these operations
+ are propagated, leaving the container with at least the original Size,
+ Length, and elements.
+
+be changed to:
+
+ Set_Maximum_Length sets the maximum length of Container to approximately
+ the value To, expanding or contracting the internal array as required.
+ Expansion or contraction may require allocation, and possibly copying and
+ deallocation of elements. Any exceptions raised by these operations are
+ propagated, leaving the length and active elements of the container
+ unchanged.
+
+and that the following AARM notes be changed appropriately, and that this
+implementation permission is added:
+
+ Implementations are not required to support the [changing|reduction] of the
+ maximum size of a container by Set_Maximum_Length, in which case calls
+ of this procedure should do nothing.
+
+I favour the word 'changing', on the basis that Set_Maximum_Length is
+probably never going to be ACATS tested for its effect on the size (maximum
+length) of a vector or map.
+
+(4) I also suggest that the concept of an 'expansion factor' is added to
+vectors and maps. Each vector or map has its own expansion
+factor associated with it, which is a value of the subtype
+Ada.Containers.Expansion_Factor_Type, declared as follows:
+
+   subtype Expansion_Factor_Type is Float range 1.0 .. [impl def];
+
+Whenever a vector or map is expanded automatically, the value of its
+expansion factor at the time may be used (but does not have to be) by the
+implementation to determine the new maximum length of the container,
+nominally by multiplying the current maximum length by the current expansion
+factor.
+
+The initial (default) value of the expansion factor of a container is
+implementation defined, but its value may be retrieved and set by the
+following subprograms:
+
+   function Expansion_Factor (Container : Vector|Map)
+         return Expansion_Factor_Type;
+
+   procedure Set_Expansion_Factor
+         (Container : in out Vector|Map;
+          To        : in Expansion_Factor_Type);
+
+****************************************************************
+
+From: Matthew Heaney
+Sent: Wednesday, June 9, 2004  9:31 AM
+
+****************************************************************
+
+From: Matthew Heaney
+Sent: Wednesday, June 9, 2004  9:31 AM
+
+****************************************************************
+
+From: Matthew Heaney
+Sent: Wednesday, June 9, 2004  9:31 AM
+
+****************************************************************
+
+From: Matthew Heaney
+Sent: Wednesday, June 9, 2004  9:31 AM
+
+****************************************************************
+
+From: Matthew Heaney
+Sent: Wednesday, June 9, 2004  9:31 AM
+
+****************************************************************
+
+From: Matthew Heaney
+Sent: Wednesday, June 9, 2004  9:31 AM
+
 ****************************************************************
 
 From: Matthew Heaney
-Sent: Saturday, May 13, 2004  9:31 AM
+Sent: Wednesday, June 9, 2004  9:31 AM
 
 ****************************************************************
 
+From: Matthew Heaney
+Sent: Wednesday, June 9, 2004  9:31 AM
+
+****************************************************************
+
+From: Matthew Heaney
+Sent: Wednesday, June 9, 2004  9:31 AM
+
+****************************************************************
+
+From: Matthew Heaney
+Sent: Wednesday, June 9, 2004  9:31 AM
+
+****************************************************************
+
+From: Matthew Heaney
+Sent: Wednesday, June 9, 2004  9:31 AM
+
+****************************************************************
+
+From: Matthew Heaney
+Sent: Wednesday, June 9, 2004  9:31 AM
+
+****************************************************************
+
+From: Matthew Heaney
+Sent: Wednesday, June 9, 2004  9:31 AM
+
+****************************************************************
+
+From: Matthew Heaney
+Sent: Wednesday, June 9, 2004  9:31 AM
+
+****************************************************************

Questions? Ask the ACAA Technical Agent