A.18.32 The Generic Package Containers.Bounded_Indefinite_Holders
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.
The declaration of the generic library package
Containers.Bounded_Indefinite_Holders has the same contents and semantics
as Containers.Indefinite_Holders except:
The following is added to
the context clause:
with System.Storage_Elements; use System.Storage_Elements;
additional generic parameter follows Element_Type:
Max_Element_Size_in_Storage_Elements : Storage_Count;
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.
to the precondition of To_Holder and Replace_Element:
and then (New_Item'Size <=
Max_Element_Size_in_Storage_Elements * System.Storage_Unit
or else raise Program_Error)
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 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.
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,
the Element_Type parameters
of the two instances are statically matching subtypes of the same type;
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
Bounded holder objects should be implemented without
dynamic allocation and any finalization should be trivial unless Element_Type
Bounded holder objects should be implemented
without dynamic allocation.
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.
If the implementation supports discontiguous objects that require
multiple calls to Allocate in a storage pool, the storage pool will need
to support such allocations. The storage pool implementation can assume
that all Allocate calls occur together, and similarly for Deallocate
calls, thus simplifying the pool implementation so that allocation only
occurs at a high-water mark location.
The Implementation Advice about the Move and Swap
operations is deleted for bounded holders; these operations can copy
elements as needed.
Reason: The memory
of a bounded indefinite holder belongs directly to the container, so
it cannot be moved with the element. If the element type contains any
internal pointers, moving it without calling Adjust would leave such
pointers pointing to the wrong holder object. Thus, a full copy is needed,
including any associated finalization and adjustments.
Extensions to Ada 2012
The generic package Containers.Bounded_Indefinite_Holders
Ada 2005 and 2012 Editions sponsored in part by Ada-Europe