generic_declaration ::= generic_subprogram_declaration | generic_package_declaration
generic_subprogram_declaration ::= generic_formal_part subprogram_specification;
generic_package_declaration ::= generic_formal_part package_specification;
generic_formal_part ::= generic {generic_formal_parameter_declaration | use_clause}
generic_formal_parameter_declaration ::= formal_object_declaration | formal_type_declaration | formal_subprogram_declaration | formal_package_declaration
Static Semantics
generic -- parameterless
generic Size : Natural; -- formal object
generic Length : Integer := 200; -- formal object with a default expression
Area : Integer := Length*Length; -- formal object with a default expression
generic type Item is private; -- formal type type Index is (<>); -- formal type type Row is array(Index range <>) of Item; -- formal type with function "<"(X, Y : Item) return Boolean; -- formal subprogram
generic type Elem is private; procedure Exchange(U, V : in out Elem);
generic type Item is private; with function "*"(U, V : Item) return Item is <>; function Squaring(X : Item) return Item;
generic type Item is private; type Vector is array (Positive range <>) of Item; with function Sum(X, Y : Item) return Item; package On_Vectors is function Sum (A, B : Vector) return Vector; function Sigma(A : Vector) return Item; Length_Error : exception; end On_Vectors;
procedure Exchange(U, V : in out Elem) is -- see section Generic Declarations T : Elem; -- the generic formal type begin T := U; U := V; V := T; end Exchange;
function Squaring(X : Item) return Item is -- see section Generic Declarations begin return X*X; -- the formal operator "*" end Squaring;
package body On_Vectors is -- see section Generic Declarations
function Sum(A, B : Vector) return Vector is Result : Vector(A'Range); -- the formal type Vector Bias : constant Integer := B'First - A'First; begin if A'Length /= B'Length then raise Length_Error; end if;
for N in A'Range loop Result(N) := Sum(A(N), B(N + Bias)); -- the formal function Sum end loop; return Result; end Sum;
function Sigma(A : Vector) return Item is Total : Item := A(A'First); -- the formal type Item begin for N in A'First + 1 .. A'Last loop Total := Sum(Total, A(N)); -- the formal function Sum end loop; return Total; end Sigma; end On_Vectors;
generic_instantiation ::= package defining_program_unit_name is new generic_package_name [generic_actual_part]; | procedure defining_program_unit_name is new generic_procedure_name [generic_actual_part]; | function defining_designator is new generic_function_name [generic_actual_part];
generic_actual_part ::= (generic_association {, generic_association})
generic_association ::= [generic_formal_parameter_selector_name =>] explicit_generic_actual_parameter
explicit_generic_actual_parameter ::= expression | variable_name | subprogram_name | entry_name | subtype_mark | package_instance_name
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, "+");
Swap(A, B); A := Square(A);
T : Table(1 .. 5) := (10, 20, 30, 40, 50); N : Integer := Int_Vectors.Sigma(T); -- 150 (see section Generic Bodies, for the body of Sigma)
use Int_Vectors; M : Integer := Sigma(T); -- 150
formal_object_declaration ::= defining_identifier_list : mode subtype_mark [:= default_expression];Name Resolution Rules
formal_type_declaration ::= type defining_identifier[discriminant_part] is formal_type_definition;
formal_type_definition ::= formal_private_type_definition | formal_derived_type_definition | formal_discrete_type_definition | formal_signed_integer_type_definition | formal_modular_type_definition | formal_floating_point_definition | formal_ordinary_fixed_point_definition | formal_decimal_fixed_point_definition | formal_array_type_definition | formal_access_type_definitionLegality Rules
type Item is private; type Buffer(Length : Natural) is limited private;
type Enum is (<>); type Int is range <>; type Angle is delta <>; type Mass is digits <>;
type Table is array (Enum) of Item;
generic type Rank is range <>; First : Rank := Rank'First; Second : Rank := First + 1; -- the operator "+" of the type Rank
formal_private_type_definition ::= [[abstract] tagged] [limited] private
formal_derived_type_definition ::= [abstract] new subtype_mark [with private]Legality Rules
Type Definition Determined Class limited private the class of all types private the class of all nonlimited types tagged limited private the class of all tagged types tagged private the class of all nonlimited tagged types
S'Definite yields True if the actual subtype corresponding to S is definite; otherwise it yields False. The value of this attribute is of the predefined type Boolean.NOTES
formal_discrete_type_definition ::= (<>)
formal_signed_integer_type_definition ::= range <>
formal_modular_type_definition ::= mod <>
formal_floating_point_definition ::= digits <>
formal_ordinary_fixed_point_definition ::= delta <>
formal_decimal_fixed_point_definition ::= delta <> digits <>Legality Rules
formal_array_type_definition ::= array_type_definitionLegality Rules
Examples
-- 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 P;
-- 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
formal_access_type_definition ::= access_type_definitionLegality Rules
-- the formal types of the generic package
generic type Node is private; type Link is access Node; package P is ... end P;
-- 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);
formal_subprogram_declaration ::= with subprogram_specification [is subprogram_default];
subprogram_default ::= default_name | <>
default_name ::= nameName Resolution Rules
with function "+"(X, Y : Item) return Item is <>; with function Image(X : Enum) return String is Enum'Image; with procedure Update is Default_Update;
-- 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);
formal_package_declaration ::= with package defining_identifier is new generic_package_name formal_package_actual_part;
formal_package_actual_part ::= (<>) | [generic_actual_part]Legality Rules
Static Semantics
generic Size : Positive; type Item is private; package Stack is procedure Push(E : in Item); procedure Pop (E : out Item); Overflow, Underflow : exception; end Stack;
package body Stack is
type Table is array (Positive range <>) of Item; Space : Table(1 .. Size); Index : Natural := 0;
procedure Push(E : in Item) is begin if Index >= Size then raise Overflow; end if; Index := Index + 1; Space(Index) := E; end Push;
procedure Pop(E : out Item) is begin if Index = 0 then raise Underflow; end if; E := Space(Index); Index := Index - 1; end Pop;
end Stack;
package Stack_Int is new Stack(Size => 200, Item => Integer); package Stack_Bool is new Stack(100, Boolean);
Stack_Int.Push(N); Stack_Bool.Push(True);
generic type Item is private; package On_Stacks is type Stack(Size : Positive) is limited private; procedure Push(S : in out Stack; E : in Item); procedure Pop (S : in out Stack; E : out Item); Overflow, Underflow : exception; private type Table is array (Positive range <>) of Item; type Stack(Size : Positive) is record Space : Table(1 .. Size); Index : Natural := 0; end record; end On_Stacks;
declare package Stack_Real is new On_Stacks(Real); use Stack_Real; S : Stack(100); begin ... Push(S, 2.54); ... end;
Go to the first, previous, next, last section, table of contents.