Skip to main content

12.7 Formal Packages

danger

This Reference Manual output has not been verified, and may contain omissions or errors. Report any problems on the tracking issue

1

[ 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/3

formal_package_declaration ::=
with package defining_identifier is new generic_package_name formal_package_actual_part
[aspect_specification];

3/2

formal_package_actual_part ::=
([others =>] <>)
| [generic_actual_part]
| (formal_package_association {, formal_package_association} [, others => <>])

3.1/2

formal_package_association ::=
generic_association
| generic_formal_parameter_selector_name => <>

3.2/2

Any positional formal_package_associations shall precede any named formal_package_associations.

Legality Rules

4

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/3

The generic_formal_parameter_selector_name of a formal_package_association shall denote a generic_formal_parameter_declaration of the template. If two or more formal subprograms of the template have the same defining name, then named associations are not allowed for the corresponding actuals.

4.2/3

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.

4.3/3

The rules for matching between formal_package_associations and the generic formals of the template are as follows:

4.4/3
4.a/3
discussion

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.

5/2

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:

5.1/2
5.3/2

The rules for matching of actual parameters between the actual instance and the formal package are as follows:

6/2
  • 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.
  • 8
  • For other kinds of formals, the actuals match if they statically denote the same entity.
8.1/1

{8652/0039} 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

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.

10.a/2
ramification

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/3
reason

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.

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

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

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

Example of an instantiation of a package with formal packages:

18/2

with Ada.Containers.Ordered_Maps; package Symbol_Package is 19/5

subtype Key_String is String(1..5); type String_Id is ... 20/2 type Symbol_Info is ... 21/5

package String_Table is new Ada.Containers.Ordered_Maps (Key_Type => Key_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

Formal packages are new to Ada 95.

Extensions to Ada 95

25.b/2

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} 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

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

25.e/3
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

25.f/3

An optional aspect_specification can be used in a formal_package_declaration. This is described in 13.1.1.