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.
2
formal_package_declaration::=
with package defining_identifier is new generic_package_name formal_package_actual_part;
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.
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/2
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
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.2/2
5.3/2
The rules for matching of actual parameters between the actual instance and the formal package are as follows:
6/2
7
8
8.1/1
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).
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 (see 7.1). 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.
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.
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/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;