Lady Ada

Ada '83 Language Reference Manual

Copyright 1980, 1982, 1983 owned by the United States Government. Direct reproduction and usage requests to the Ada Information Clearinghouse.


12.3. Generic Instantiation

[PREVIOUS][UP][NEXT]

An instance of a generic unit is declared by a generic instantiation.

    generic_instantiation ::=
         package identifier is
             new generic_package_name [generic_actual_part];
       | procedure identifier is
             new generic_procedure_name [generic_actual_part];
       | function designator is
             new generic_function_name [generic_actual_part]; 

    generic_actual_part ::=
       (generic_association {, generic_association}) 

    generic_association ::=
       [generic_formal_parameter =>] generic_actual_parameter 

    generic_formal_parameter ::= parameter_simple_name | operator_symbol 

    generic_actual_parameter ::= expression | variable_name
       | subprogram_name | entry_name | type_mark 

An explicit generic actual parameter must be supplied for each generic formal parameter, unless the corresponding generic parameter declaration specifies that a default can be used. Generic associations can be either positional or named in the same manner as parameter associations of subprogram calls (see 6.4). If two or more formal subprograms have the same designator, then named associations are not allowed for the corresponding generic parameters.

Each generic actual parameter must match the corresponding generic formal parameter. An expression can match a formal object of mode in; a variable name can match a formal object of mode in out; a subprogram name or an entry name can match a formal subprogram; a type mark can match a formal type. The detailed rules defining the allowed matches are given in sections 12.3.1 to 12.3.6; these are the only allowed matches.

The instance is a copy of the generic unit, apart from the generic formal part; thus the instance of a generic package is a package, that of a generic procedure is a procedure, and that of a generic function is a function. For each occurrence, within the generic unit, of a name that denotes a given entity, the following list defines which entity is denoted by the corresponding occurrence within the instance.

  1. For a name that denotes the generic unit: The corresponding occurrence denotes the instance.

  2. For a name that denotes a generic formal object of mode in: The corresponding name denotes a constant whose value is a copy of the value of the associated generic actual parameter.

  3. For a name that denotes a generic formal object of mode in out: The corresponding name denotes the variable named by the associated generic actual parameter.

  4. For a name that denotes a generic formal type: The corresponding name denotes the subtype named by the associated generic actual parameter (the actual subtype).

  5. For a name that denotes a discriminant of a generic formal type: The corresponding name denotes the corresponding discriminant (there must be one) of the actual type associated with the generic formal type.

  6. For a name that denotes a generic formal subprogram: The corresponding name denotes the subprogram, enumeration literal, or entry named by the associated generic actual parameter (the actual subprogram).

  7. For a name that denotes a formal parameter of a generic formal subprogram: The corresponding name denotes the corresponding formal parameter of the actual subprogram associated with the formal subprogram.

  8. For a name that denotes a local entity declared within the generic unit: The corresponding name denotes the entity declared by the corresponding local declaration within the instance.

  9. For a name that denotes a global entity declared outside of the generic unit: The corresponding name denotes the same global entity.
Similar rules apply to operators and basic operations: in particular, formal operators follow a rule similar to rule (f), local operations follow a rule similar to rule (h), and operations for global types follow a rule similar to rule (i). In addition, if within the generic unit a predefined operator or basic operation of a formal type is used, then within the instance the corresponding occurrence refers to the corresponding predefined operation of the actual type associated with the formal type.

The above rules apply also to any type mark or (default) expression given within the generic formal part of the generic unit.

For the elaboration of a generic instantiation, each expression supplied as an explicit generic actual parameter is first evaluated, as well as each expression that appears as a constituent of a variable name or entry name supplied as an explicit generic actual parameter; these evaluations proceed in some order that is not defined by the language. Then, for each omitted generic association (if any), the corresponding default expression or default name is evaluated; such evaluations are performed in the order of the generic parameter declarations. Finally, the implicitly generated instance is elaborated. The elaboration of a generic instantiation may also involve certain constraint checks as described in later subsections.

Recursive generic instantiation is not allowed in the following sense: if a given generic unit includes an instantiation of a second generic unit, then the instance generated by this instantiation must not include an instance of the first generic unit (whether this instance is generated directly, or indirectly by intermediate instantiations).

Examples of generic instantiations (see 12.1):

    procedure SWAP is new EXCHANGE(ELEM => INTEGER);
    procedure SWAP is new EXCHANGE(CHARACTER);  --  SWAP is overloaded 

    function SQUARE is new SQUARING(INTEGER);  --  "*" of INTEGER used by default
    function SQUARE is new SQUARING(ITEM => MATRIX, "*" => MATRIX_PRODUCT);
    function SQUARE is new SQUARING(MATRIX, MATRIX_PRODUCT); -- same as previous    

    package INT_VECTORS is new ON_VECTORS(INTEGER, TABLE, "+"); 

Examples of uses of instantiated units:

    SWAP(A, B);
    A := SQUARE(A); 

    T : TABLE(1 .. 5) := (10, 20, 30, 40, 50);
    N : INTEGER := INT_VECTORS.SIGMA(T);  --  150 (see 12.2 for the body of
                                              SIGMA)
    use INT_VECTORS;
    M : INTEGER := SIGMA(T);  --  150                                            

Notes:

Omission of a generic actual parameter is only allowed if a corresponding default exists. If default expressions or default names (other than simple names) are used, they are evaluated in the order in which the corresponding generic formal parameters are declared.

If two overloaded subprograms declared in a generic package specification differ only by the (formal) type of their parameters and results, then there exist legal instantiations for which all calls of these subprograms from outside the instance are ambiguous. For example:

    generic
       type A is (<>);
       type B is private;
    package G is
       function NEXT(X : A) return A;
       function NEXT(X : B) return B;
    end; 

    package P is new G(A => BOOLEAN, B => BOOLEAN);
    -- calls of P.NEXT are ambiguous 

References: declaration, designator, discriminant, elaboration, and 3.9, entity, entry name, evaluation, expression, generic formal object, generic formal parameter, generic formal subprogram, generic formal type, generic parameter declaration, global declaration, identifier, implicit declaration, local declaration, mode in, mode in out, name, operation, operator symbol, overloading, and 8.7, package, simple name, subprogram, subprogram call, subprogram name, subtype declaration, type mark, variable, visibility.

Rationale references: 12.2.2 Generic Instantiations

Style Guide references: 2.1.2 Indentation, 3.2.4 Program Unit Names, 5.2.2 Named Association, 8.1.1 Application-Independent Naming, 8.2.4 Subtypes in Generic Specifications, 8.2.5 Overloading in Generic Units, 8.3.2 Generic Units, 8.3.6 Private and Limited Private Types, 8.4.4 Conditional Compilation

Sub-topics:

12.3.1. Matching Rules for Formal Objects

[UP][NEXT]

A generic formal parameter of mode in of a given type is matched by an expression of the same type. If a generic unit has a generic formal object of mode in, a check is made that the value of the expression belongs to the subtype denoted by the type mark, as for an explicit constant declaration (see 3.2.1). The exception CONSTRAINT_ERROR is raised if this check fails.

A generic formal parameter of mode in out of a given type is matched by the name of a variable of the same type. The variable must not be a formal parameter of mode out or a subcomponent thereof. The name must denote a variable for which renaming is allowed (see 8.5).

Notes:

The type of a generic actual parameter of mode in must not be a limited type. The constraints that apply to a generic formal parameter of mode in out are those of the corresponding generic actual parameter (see 12.1.1).

References: constraint, constraint_error exception, expression, formal parameter, generic actual parameter, generic formal object, generic formal parameter, generic instantiation, generic unit, limited type, matching generic actual parameter, mode in, mode in out, mode out, name, raising of exceptions, satisfy, subcomponent, type, type mark, variable.

12.3.2. Matching Rules for Formal Private Types

[PREVIOUS][UP][NEXT]

A generic formal private type is matched by any type or subtype (the actual subtype) that satisfies the following conditions:

Furthermore, consider any occurrence of the name of the formal type at a place where this name is used as an unconstrained subtype indication. The actual subtype must not be an unconstrained array type or an unconstrained type with discriminants, if any of these occurrences is at a place where either a constraint or default discriminants would be required for an array type or for a type with discriminants (see 3.6.1 and 3.7.2). The same restriction applies to occurrences of the name of a subtype of the formal type, and to occurrences of the name of any type or subtype derived, directly or indirectly, from the formal type.

If a generic unit has a formal private type with discriminants, the elaboration of a corresponding generic instantiation checks that the subtype of each discriminant of the actual type is the same as the subtype of the corresponding discriminant of the formal type. The exception CONSTRAINT_ERROR is raised if this check fails.

References: array type, constraint, constraint_error exception, default expression for a discriminant, derived type, discriminant, discriminant part, elaboration, generic actual type, generic body, generic formal type, generic instantiation, generic specification, limited type, matching generic actual parameter, name, private type, raising of exceptions, subtype, subtype indication, type, type with discriminants, unconstrained array type, unconstrained subtype.

Style Guide references: 5.3.3 Private Types, 8.3.4 Using Generic Units for Abstract Data Types

12.3.3. Matching Rules for Formal Scalar Types

[PREVIOUS][UP][NEXT]

A generic formal type defined by (<>) is matched by any discrete subtype (that is, any enumeration or integer subtype). A generic formal type defined by range <> is matched by any integer subtype. A generic formal type defined by digits <> is matched by any floating point subtype. A generic formal type defined by delta <> is matched by any fixed point subtype. No other matches are possible for these generic formal types.

References: box delimiter, discrete type, enumeration type, fixed point type, floating point type, generic actual type, generic formal type, generic type definition, integer type, matching generic actual parameter, scalar type.

12.3.4. Matching Rules for Formal Array Types

[PREVIOUS][UP][NEXT]

A formal array type is matched by an actual array subtype that satisfies the following conditions:

If a generic unit has a formal array type, the elaboration of a corresponding instantiation checks that the constraints (if any) on the component type are the same for the actual array type as for the formal array type, and likewise that for any given index position the index subtypes or the discrete ranges have the same bounds. The exception CONSTRAINT_ERROR is raised if this check fails.

Example:

    --  given the generic package 

    generic
       type ITEM   is private;
       type INDEX  is (<>);
       type VECTOR is array (INDEX range <>) of ITEM;
       type TABLE  is array (INDEX) of ITEM;
    package P is
       ...
    end; 

    --  and the types 

    type MIX    is array (COLOR range <>) of BOOLEAN;
    type OPTION is array (COLOR) of BOOLEAN; 

    --  then MIX can match VECTOR and OPTION can match TABLE 

    package R is new P(ITEM   => BOOLEAN, INDEX => COLOR,
                       VECTOR => MIX,     TABLE => OPTION); 

    --  Note that MIX cannot match TABLE and OPTION cannot match VECTOR

Note:

For the above rules, if any of the index or component types of the formal array type is itself a formal type, then within the instance its name denotes the corresponding actual subtype (see 12.3(d)).

References: array type, array type definition, component of an array, constrained array type, constraint, constraint_error exception, elaboration, formal type, generic formal type, generic instantiation, index, index constraint, matching generic actual parameter, raise statement, subtype, unconstrained array type.

Style Guide references: 8.2.2 Unconstrained Arrays

12.3.5. Matching Rules for Formal Access Types

[PREVIOUS][UP][NEXT]

A formal access type is matched by an actual access subtype if the type of the designated objects is the same for the actual type as for the formal type. If the designated type is other than a scalar type, then the designated subtypes must be either both constrained or both unconstrained.

If a generic unit has a formal access type, the elaboration of a corresponding instantiation checks that any constraints on the designated objects are the same for the actual access subtype as for the formal access type. The exception CONSTRAINT_ERROR is raised if this check fails.

Example:

    --  the formal types of the generic package 

    generic
       type NODE is private;
       type LINK is access NODE;
    package P is
       ...
    end; 

    --  can be matched by the actual types 

    type CAR;
    type CAR_NAME is access CAR; 

    type CAR is
       record
          PRED, SUCC : CAR_NAME;
          NUMBER     : LICENSE_NUMBER;
          OWNER      : PERSON;
       end record;  

    --  in the following generic instantiation 

    package R is new P(NODE => CAR, LINK => CAR_NAME);

Note:

For the above rules, if the designated type is itself a formal type, then within the instance its name denotes the corresponding actual subtype (see 12.3(d)).

References: access type, access type definition, constraint, constraint_error exception, designate, elaboration, generic formal type, generic instantiation, matching generic actual parameter, object, raise statement, value of access type.

12.3.6. Matching Rules for Formal Subprograms

[PREVIOUS][UP]

A formal subprogram is matched by an actual subprogram, enumeration literal, or entry if both have the same parameter and result type profile (see 6.6); in addition, parameter modes must be identical for formal parameters that are at the same parameter position.

If a generic unit has a default subprogram specified by a name, this name must denote a subprogram, an enumeration literal, or an entry, that matches the formal subprogram (in the above sense). The evaluation of the default name takes place during the elaboration of each instantiation that uses the default, as defined in section 12.3.

If a generic unit has a default subprogram specified by a box, the corresponding actual parameter can be omitted if a subprogram, enumeration literal, or entry matching the formal subprogram, and with the same designator as the formal subprogram, is directly visible at the place of the generic instantiation; this subprogram, enumeration literal, or entry is then used by default (there must be exactly one subprogram, enumeration literal, or entry satisfying the previous conditions).

Example:

    --  given the generic function specification 

    generic
       type ITEM is private;
       with function "*" (U, V : ITEM) return ITEM is <>;
    function SQUARING(X : ITEM) return ITEM; 

    --  and the function 

    function MATRIX_PRODUCT(A, B : MATRIX) return MATRIX; 

    --  the following instantiation is possible 

    function SQUARE is new SQUARING(MATRIX, MATRIX_PRODUCT); 

    --  the following instantiations are equivalent 

    function SQUARE is new SQUARING(ITEM => INTEGER, "*" => "*");
    function SQUARE is new SQUARING(INTEGER, "*");
    function SQUARE is new SQUARING(INTEGER); 

Notes:

The matching rules for formal subprograms state requirements that are similar to those applying to subprogram renaming declarations (see 8.5). In particular, the name of a parameter of the formal subprogram need not be the same as that of the corresponding parameter of the actual subprogram; similarly, for these parameters, default expressions need not correspond.

A formal subprogram is matched by an attribute of a type if the attribute is a function with a matching specification. An enumeration literal of a given type matches a parameterless formal function whose result type is the given type.

References: attribute, box delimiter, designator, entry, function, generic actual type, generic formal subprogram, generic formal type, generic instantiation, matching generic actual parameter, name, parameter and result type profile, subprogram, subprogram specification, subtype, visibility.

[INDEX][CONTENTS]


[Ada Information Clearinghouse]

Address any questions or comments to adainfo@sw-eng.falls-church.va.us.