Contents   Index   Search   Related Documents   Previous   Next


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. 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 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 Generic_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;

Contents   Index   Search   Related Documents   Previous   Next   Legal