12.7 Formal Packages
1
[
{generic formal
package} {formal
package, generic} 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
2
formal_package_declaration ::=
with package defining_identifier is new generic_package_name formal_package_actual_part;
3/2
{
AI95-00317-01}
formal_package_actual_part ::=
([others =>] <>)
| [generic_actual_part]
| (formal_package_association {, formal_package_association} [, others => <>])(<>) | [generic_actual_part]
3.1/2
{
AI95-00317-01}
formal_package_association ::=
generic_association
| generic_formal_parameter_selector_name => <>
3.2/2
{
AI95-00317-01}
Any positional formal_package_associations
shall precede any named formal_package_associations.
Legality Rules
4
{template (for a
formal package)} The
generic_package_name
shall denote a generic package (the
template for the formal package);
the formal package is an instance of the template.
4.1/2
{
AI95-00398-01}
A formal_package_actual_part
shall contain at most one formal_package_association
for each formal parameter. If the formal_package_actual_part
does not include “others => <>”, each formal
parameter without an association shall have a default_expression
or subprogram_default.
5/2
{
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 each actual parameter
of the actual instance shall match the corresponding actual
parameters parameter
of the formal package
, determined [(whether the actual parameter is given explicitly or by default)],
as follows:
5.1/2
- {AI95-00317-01}
If the formal_package_actual_part
includes generic_associations as well as associations
with <>, then only the actual parameters specified explicitly with
generic_associations are required to match;
5.2/2
- {AI95-00317-01}
Otherwise, all actual parameters shall match[,
whether any actual parameter is given explicitly or by default].
5.3/2
{
AI95-00317-01}
The rules for matching of actual parameters between
the actual instance and the formal package are as follows:
6/2
- {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.
6.a
Reason: We can't simply require full
conformance between the two actual parameter expressions, because the
two expressions are being evaluated at different times.
7
- For a formal subtype, the actuals
match if they denote statically matching subtypes. {statically
matching (required) [partial]}
8
- For other kinds of formals, the actuals
match if they statically denote the same entity.
8.1/1
{
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
9
A formal_package_declaration
declares a generic formal package.
10/2
{
AI95-00317-01}
{visible part (of a formal package)
[partial]} 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 if the formal_package_actual_part
is (<>), it also includes the generic_formal_part
of the template for the formal package.
10.a/2
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.
10.b
Reason: We always want either the actuals
or the formals of an instance to be namable from outside, but never both.
If both were namable, 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.
10.c
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.
11/2
{
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
12/2
{
AI95-00433-01}
Example of a generic package with formal package
parameters:
13/2
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
14/2
subtype Key_Type is Mapping_1.Key_Type;
subtype Element_Type is Mapping_2.Element_Type;
15/2
function Lookup(Key : Key_Type) return Element_Type;
16/2
...
end Ordered_Join;
17/2
{
AI95-00433-01}
Example of an instantiation of a package with
formal packages:
18/2
with Ada.Containers.Ordered_Maps;
package Symbol_Package is
19/2
type String_Id is ...
20/2
type Symbol_Info is ...
21/2
package String_Table is new Ada.Containers.Ordered_Maps
(Key_Type => String,
Element_Type => String_Id);
22/2
package Symbol_Table is new Ada.Containers.Ordered_Maps
(Key_Type => String_Id,
Element_Type => Symbol_Info);
23/2
package String_Info is new Ordered_Join(Mapping_1 => String_Table,
Mapping_2 => Symbol_Table);
24/2
Apple_Info : constant Symbol_Info := String_Info.Lookup("Apple");
25/2
end Symbol_Package;
Extensions to Ada 83
25.a
{
extensions to Ada 83}
Formal
packages are new to Ada 95.
Extensions to Ada 95
25.b/2
{
AI95-00317-01}
{
AI95-00398-01}
{extensions to Ada 95} 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
25.c/2
{
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.
25.d/2
{
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.