12.6 Formal Subprograms
Formal subprograms
can be used to pass callable entities to a generic unit.
Syntax
Name Resolution Rules
The expected profile for the
default_name,
if any, is that of the formal subprogram.
For a generic formal subprogram,
the expected profile for the actual is that of the formal subprogram.
Legality Rules
The profiles of the formal and any named default
shall be mode conformant.
The profiles of the formal and actual shall be mode
conformant.
if the actual matching the
formal_subprogram_declaration
statically denotes a generic formal subprogram of another generic unit
G, and the instantiation containing the actual occurs within the
body of a generic unit
G or within the body of a generic unit
declared within the declarative region of the generic unit
G,
then the corresponding parameter or result type of the formal subprogram
of
G shall have a
null_exclusion;
otherwise, the subtype of the corresponding parameter
or result type of the actual matching the
formal_subprogram_declaration
shall exclude null.
In addition to the places where
Legality Rules normally apply (see
12.3),
this rule applies also in the private part of an instance of a generic
unit.
If the named default, if any, is a prefixed view,
the prefix of that view shall denote an object for which renaming is
allowed (see
8.5.1). Similarly, if the actual
subprogram in an instantiation is a prefixed view, the prefix of that
view shall denote an object for which renaming is allowed.
a dispatching operation of the controlling type;
or
if the controlling type is a formal type, and the
actual type corresponding to that formal type is a specific type T,
a dispatching operation of type T; or
if the controlling type is a formal type, and the
actual type is a class-wide type T'Class, an implicitly declared
subprogram corresponding to a primitive operation of type T (see
Static Semantics below).
Static Semantics
A
formal_subprogram_declaration
declares a generic formal subprogram. The types of the formal parameters
and result, if any, of the formal subprogram are those determined by
the
subtype_marks
given in the
formal_subprogram_declaration;
however, independent of the particular subtypes that are denoted by the
subtype_marks,
the nominal subtypes of the formal parameters and result, if any, are
defined to be nonstatic, and unconstrained if of an array type (no applicable
index constraint is provided in a call on a formal subprogram). In an
instance, a
formal_subprogram_declaration
declares a view of the actual. The profile of this view takes its subtypes
and calling convention from the original profile of the actual entity,
while taking the formal parameter
names
and
default_expressions
from the profile given in the
formal_subprogram_declaration.
The view is a function or procedure, never an entry.
If a
subtype_mark
in the profile of the
formal_subprogram_declaration
denotes a formal private or formal derived type and the actual type for
this formal type is a class-wide type
T'Class, then for the purposes
of resolving the corresponding actual subprogram at the point of the
instantiation, certain implicit declarations may be available as possible
resolutions as follows:
For each primitive subprogram of
T that
is directly visible at the point of the instantiation, and that has at
least one controlling formal parameter, a corresponding implicitly declared
subprogram with the same defining name, and having the same profile as
the primitive subprogram except that
T is systematically replaced
by
T'Class in the types of its profile, is potentially use-visible.
The body of such a subprogram is as defined in
12.5.1
for primitive subprograms of a formal type when the actual type is class-wide.
If a generic unit has a
subprogram_default
specified by a box, and the corresponding actual parameter is omitted,
then it is equivalent to an explicit actual parameter that is a usage
name identical to the defining name of the formal.
If a generic unit has a
subprogram_default
specified by the reserved word
null, and the corresponding actual
parameter is omitted, then it is equivalent to an explicit actual parameter
that is a null procedure having the profile given in the
formal_subprogram_declaration.
NOTE 1 The matching rules for formal
subprograms state requirements that are similar to those applying to
subprogram_renaming_declarations
(see
8.5.4). In particular, the name of a
parameter of the formal subprogram can be different from that of the
corresponding parameter of the actual subprogram; similarly, for these
parameters,
default_expressions
can be different.
NOTE 2 The constraints that apply
to a parameter of a formal subprogram are those of the corresponding
formal parameter of the matching actual subprogram (not those implied
by the corresponding
subtype_mark
in the
_specification of the formal subprogram).
A similar remark applies to the result of a function. Therefore, to avoid
confusion, it is recommended that the
name
of a first subtype be used in any declaration of a formal subprogram.
NOTE 3 The subtype specified for
a formal parameter of a generic formal subprogram can be any visible
subtype, including a generic formal subtype of the same
generic_formal_part.
NOTE 4 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.
NOTE 8 A null procedure as a subprogram
default has convention Intrinsic (see
6.3.1).
Examples
Examples of generic
formal subprograms:
with function "+"(X, Y : Item)
return Item
is <>;
with function Image(X : Enum)
return String
is Enum'Image;
with procedure Update
is Default_Update;
with procedure Pre_Action(X :
in Item)
is null; --
defaults to no action
with procedure Write(S :
not null access Root_Stream_Type'Class;
Desc : Descriptor)
is abstract Descriptor'Write; --
see 13.13.2
--
Dispatching operation on Descriptor with default
-- given the generic procedure declaration
generic
with procedure Action (X : in Item);
procedure Iterate(Seq : in Item_Sequence);
-- and the procedure
procedure Put_Item(X : in Item);
-- the following instantiation is possible
procedure Put_List is new Iterate(Action => Put_Item);
Ada 2005 and 2012 Editions sponsored in part by Ada-Europe