Next: , Previous: 12.6, Up: 12


12.7 Formal Packages

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

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.
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/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).

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 (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.

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 "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;