12.7 Formal Packages
[
Formal
packages can be used to pass packages to a generic unit. The
formal_package_declaration
declares that the formal package is an instance of a given generic package.
Upon instantiation, the actual package has to be an instance of that
generic package.]
Syntax
Legality Rules
The
generic_package_name
shall denote a generic package (the
template for the formal package);
the formal package is an instance of the template.
Discussion: {
AI05-0200-1}
The above rule is simple to state, though it does not reflect the fact
that the formal package functions like an instantiation of a special
kind, where each box association for a
generic_formal_parameter_declaration
F is replaced with a new entity
F' that has the same characteristics
as
F: if
F is a formal discrete type then
F' is
a discrete type, if
F is a formal subprogram then
F' is
a subprogram with a similar signature, etc. In practice this is achieved
by making the association into a copy of the declaration of the generic
formal.
{
AI95-00317-01}
The actual shall be an instance of the template. If the
formal_package_actual_part
is (<>) or (
others => <>), [then the actual may
be any instance of the template]; otherwise, certain of the actual parameters
of the actual instance shall match the corresponding actual parameters
of the formal package, determined as follows:
{
AI95-00317-01}
Otherwise, all actual parameters shall match[, whether any actual parameter
is given explicitly or by default].
{
AI95-00317-01}
The rules for matching of actual parameters between the actual instance
and the formal package are as follows:
{
AI95-00317-01}
For a formal object of mode
in, the actuals match if they are
static expressions with the same value, or if they statically denote
the same constant, or if they are both the literal
null.
Reason: We can't simply require full
conformance between the two actual parameter expressions, because the
two expressions are being evaluated at different times.
For a formal subtype, the actuals match if they
denote statically matching subtypes.
For other kinds of formals, the actuals match if
they statically denote the same entity.
{
8652/0039}
{
AI95-00213-01}
For the purposes of matching, any actual parameter that is the name of
a formal object of mode
in is replaced by the formal object's
actual expression (recursively).
Static Semantics
{
AI95-00317-01}
The visible part of a formal package includes the
first list of
basic_declarative_items
of the
package_specification.
In addition, for each actual parameter that is not required to match,
a copy of the declaration of the corresponding formal parameter of the
template is included in the visible part of the formal package. If the
copied declaration is for a formal type, copies of the implicit declarations
of the primitive subprograms of the formal type are also included in
the visible part of the formal package.
Ramification: {
AI95-00317-01}
If the
formal_package_actual_part
is (<>), then the declarations that occur immediately within the
generic_formal_part
of the template for the formal package are visible outside the formal
package, and can be denoted by expanded names outside the formal package.
If only some of the actual parameters are given by <>, then the
declaration corresponding to those parameters (but not the others) are
made visible.
Reason: {
AI05-0005-1}
We always want either the actuals or the formals of an instance to be
nameable from outside, but never both. If both were nameable, one would
get some funny anomalies since they denote the same entity, but, in the
case of types at least, they might have different and inconsistent sets
of primitive operators due to predefined operator “reemergence”,
Formal derived types exacerbate the difference. We want the implicit
declarations of the
generic_formal_part
as well as the explicit declarations, so we get operations on the formal
types.
Ramification: A generic formal package
is a package, and is an instance. Hence, it is possible to pass a generic
formal package as an actual to another generic formal package.
{
AI95-00317-01}
For the purposes of matching, if the actual instance
A is itself
a formal package, then the actual parameters of
A are those specified
explicitly or implicitly in the
formal_package_actual_part
for
A, plus, for those not specified, the copies of the formal
parameters of the template included in the visible part of
A.
Examples
{
AI95-00433-01}
Example of a generic package with formal package parameters:
with Ada.Containers.Ordered_Maps; --
see A.18.6
generic
with package Mapping_1
is new Ada.Containers.Ordered_Maps(<>);
with package Mapping_2
is new Ada.Containers.Ordered_Maps
(Key_Type => Mapping_1.Element_Type,
others => <>);
package Ordered_Join
is
--
Provide a "join" between two mappings
subtype Key_Type is Mapping_1.Key_Type;
subtype Element_Type is Mapping_2.Element_Type;
function Lookup(Key : Key_Type) return Element_Type;
...
end Ordered_Join;
{
AI95-00433-01}
Example of an instantiation of a package with formal packages:
with Ada.Containers.Ordered_Maps;
package Symbol_Package is
{
AI12-0178-1}
subtype Key_String
is String(1..5);
type String_Id
is ...
type Symbol_Info is ...
{
AI12-0178-1}
package String_Table
is new Ada.Containers.Ordered_Maps
(Key_Type => Key_String,
Element_Type => String_Id);
package Symbol_Table is new Ada.Containers.Ordered_Maps
(Key_Type => String_Id,
Element_Type => Symbol_Info);
package String_Info is new Ordered_Join(Mapping_1 => String_Table,
Mapping_2 => Symbol_Table);
Apple_Info : constant Symbol_Info := String_Info.Lookup("Apple");
end Symbol_Package;
Extensions to Ada 83
Formal packages are new
to Ada 95.
Extensions to Ada 95
{
AI95-00317-01}
{
AI95-00398-01}
It's now allowed to mix actuals of a formal package
that are specified with those that are not specified.
Wording Changes from Ada 95
{
8652/0039}
{
AI95-00213-01}
Corrigendum: Corrected the description of formal package matching
to say that formal parameters are always replaced by their actual parameters
(recursively). This matches the actual practice of compilers, as the
ACATS has always required this behavior.
{
AI95-00317-01}
The description of which operations are visible in a formal package has
been clarified. We also specify how matching is done when the actual
is a formal package.
Incompatibilities With Ada 2005
{
AI05-0025-1}
{
AI05-0200-1}
Correction: Added missing rules for parameters
of generic formal package that parallel those in
12.3,
as well as some specific to <> parameters. These are technically
incompatibilities because generic formal package parameters that Ada
95 and Ada 2005 would have considered legal now have to be rejected.
But this should not be an issue in practice as such formal parameters
could not have matched any actual generics. And it is quite likely that
implementations already enforce some of these rules.
Extensions to Ada 2005
Ada 2005 and 2012 Editions sponsored in part by Ada-Europe