4.8 Allocators
The evaluation of an
allocator
creates an object and yields an access value that designates the object.
Syntax
subpool_specification ::= (
subpool_handle_name)
Name Resolution Rules
The expected type for an
allocator
shall be a single access-to-object type with designated type
D
such that either
D covers the type determined by the
subtype_mark
of the
subtype_indication
or
qualified_expression,
or the expected type is anonymous and the determined type is
D'Class.
A
subpool_handle_name
is expected to be of any type descended from Subpool_Handle, which is
the type used to identify a subpool, declared in package System.Storage_Pools.Subpools
(see
13.11.4).
Legality Rules
If the type of the
allocator
is an access-to-constant type, the
allocator
shall be an initialized allocator.
If a
subpool_specification
is given, the type of the storage pool of the access type shall be a
descendant of Root_Storage_Pool_With_Subpools.
An
allocator
shall not be of an access type for which the Storage_Size has been specified
by a static expression with value zero or is defined by the language
to be zero.
If the designated type of the type of the
allocator
is limited, then the
allocator
shall not be used to define the value of an access discriminant, unless
the discriminated type is immutably limited (see
7.5).
In addition to the places where
Legality Rules normally apply (see
12.3),
these rules apply also in the private part of an instance of a generic
unit.
Static Semantics
If the designated type of the type of the
allocator
is elementary, then the subtype of the created object is the designated
subtype. If the designated type is composite, then the subtype of the
created object is the designated subtype when the designated subtype
is constrained or there is an ancestor of the designated type that has
a constrained partial view; otherwise, the created object is constrained
by its initial value (even if the designated subtype is unconstrained
with defaults).
Dynamic Semantics
For the evaluation of an initialized
allocator, the evaluation of the
qualified_expression
is performed first.
An object
of the designated type is created and the value of the
qualified_expression
is converted to the designated subtype and assigned to the object.
For the evaluation of an uninitialized
allocator, the elaboration of the
subtype_indication
is performed first. Then:
If
the designated type is elementary, an object of the designated subtype
is created and any implicit initial value is assigned;
If the designated type is composite, an object
of the designated type is created with tag, if any, determined by the
subtype_mark
of the
subtype_indication.
This object is then initialized by default (see
3.3.1)
using the
subtype_indication
to determine its nominal subtype.
A
check is made that the value of the object belongs to the designated
subtype.
Constraint_Error is raised if this check
fails. This check and the initialization of the object are performed
in an arbitrary order.
For any
allocator,
if the designated type of the type of the
allocator
is class-wide, then a check is made that the master of the type determined
by the
subtype_indication,
or by the tag of the value of the
qualified_expression,
includes the elaboration of the type of the
allocator.
If any part of the subtype determined by the
subtype_indication
or
qualified_expression
of the
allocator
(or by the tag of the value if the type of the
qualified_expression
is class-wide) has one or more access discriminants, then a check is
made that the accessibility level of the anonymous access type of each
access discriminant is not deeper than that of the type of the
allocator.
Program_Error is raised if either such check fails.
If the object to be created by an
allocator
has a controlled or protected part, and the finalization of the collection
of the type of the
allocator
(see
7.6.1) has started, Program_Error is
raised.
If the object to be created by an
allocator
contains any tasks, and the master of the type of the
allocator
is completed, and all of the dependent tasks of the master are terminated
(see
9.3), then Program_Error is raised.
If the
allocator
includes a
subpool_handle_name,
Constraint_Error is raised if the subpool handle is
null. Program_Error
is raised if the subpool does not
belong (see
13.11.4)
to the storage pool of the access type of the
allocator.
If the created object contains any tasks, they are
activated (see
9.2). Finally, an access value
that designates the created object is returned.
Bounded (Run-Time) Errors
It is a bounded error if the
finalization of the collection of the type (see
7.6.1)
of the
allocator
has started. If the error is detected, Program_Error is raised. Otherwise,
the allocation proceeds normally.
NOTE 1 Allocators cannot create objects
of an abstract type. See
3.9.3.
NOTE 2 If any part of the created
object is controlled, the initialization includes calls on corresponding
Initialize or Adjust procedures. See
7.6.
NOTE 3 As explained in
13.11,
“
Storage Management”, the storage
for an object allocated by an
allocator
comes from a storage pool (possibly user defined). The exception Storage_Error
is raised by an
allocator
if there is not enough storage. Instances of Unchecked_Deallocation can
be used to explicitly reclaim storage.
NOTE 4 Implementations can, if desired,
provide garbage collection.
Examples
Examples of allocators:
new Cell'(0,
null,
null) --
initialized explicitly, see 3.10.1
new Cell'(Value => 0, Succ =>
null, Pred =>
null)
--
initialized explicitly
new Cell --
not initialized
new Matrix(1 .. 10, 1 .. 20) -- the bounds only are given
new Matrix'(1 .. 10 => (1 .. 20 => 0.0)) -- initialized explicitly
new Buffer(100) -- the discriminant only is given
new Buffer'(Size => 80, Pos => 0, Value => (1 .. 80 => 'A'))
-- initialized explicitly
Expr_Ptr'(
new Literal)
--
allocator for access-to-class-wide type, see 3.9.1
Expr_Ptr'(
new Literal'(Expression
with 3.5)) --
initialized explicitly
Ada 2005 and 2012 Editions sponsored in part by Ada-Europe