To Minimize Run-Time Complexity, Ada Requires Types And Subprograms To Be Fully Determined At Compile Time
Unlike Pascal And C, Ada Prohibits Passing Subprograms As Parameters
Generic Units Are Non-Executable Templates From Which Specific Executable Instances Of That Unit Can Be Produced
Generic Units Facilitate Writing General Purpose Reusable Software Components, A Major Ada Goal
Generic Units Make It Possible To Solve Similar But Not Identical Problems With A Single Program Unit
Generic Units Require Compilation
Compilation May Produce Object Code In Varying Degrees Of Completeness
Compilation May Simply Save Source Code
Generic Units Require Instantiation
Instantiation Produces Complete Executable Object Code
generic_declaration ::=
generic_specification;
generic_specification ::=
generic_formal_part subprogram_specification | generic_formal_part package_specification
generic_formal_part ::=
GENERIC {generic_parameter_declarations}
generic_parameter_declaration ::=
identifier_list: [IN [OUT]] type_mark [:= expression]; | TYPE identifier IS generic_type_definition; | private_type_declaration | WITH subprogram_specification [IS name]; | WITH subprogram_specification [IS <>];
(<>) | RANGE <> | DIGITS <> | DELTA <> | array_type_definition | access_type_definition
1. Generic Units Can Be Subprograms Or Packages
2. Generic Formal Parameters Can Be Objects, Types Or Subprograms
Limited Private: Most General
Private: May Use Assignment Or Test For Equality
Discrete: May Use Any Operation Valid For Discrete Types
GENERIC TYPE Privates IS PRIVATE; PROCEDURE Swap(X,Y: IN OUT Privates); PROCEDURE Swap(X,Y: IN OUT Privates) IS Temporary: Privates; BEGIN Temporary := X; X := Y; Y := Temporary; END Swap;
GENERIC
TYPE Discretes IS (<>);
FUNCTION Successor(Item: Discretes)
RETURN Discretes;
FUNCTION Successor(Item: Discretes)
RETURN Discretes IS
BEGIN
IF Item = Discretes'Last THEN
RETURN Discretes'First;
ELSE
RETURN Discretes'Succ(Item);
END IF;
END Successor;
GENERIC
TYPE Elements IS (<>);
PACKAGE Set_Package IS
TYPE Sets IS PRIVATE;
TYPE Lists IS ARRAY (Positive RANGE <>) OF
Elements;
FUNCTION "+"(Set1,Set2: Sets) RETURN Sets;
FUNCTION "*"(Set1,Set2: Sets) RETURN Sets;
FUNCTION Set(List: Lists) RETURN Sets;
PRIVATE
TYPE Sets IS ARRAY (Elements) OF Boolean;
END Set_Package;
PACKAGE BODY Set_Package IS
FUNCTION "+"(Set1,Set2: Sets) RETURN Sets IS
BEGIN RETURN Set1 OR Set2; END "+";
FUNCTION "*"(Set1,Set2: Sets) RETURN Sets IS
BEGIN RETURN Set1 AND Set2; END "*";
FUNCTION Set(List: Lists) RETURN Sets IS
Result: Sets := (OTHERS => False);
BEGIN
FOR Element IN List'Range LOOP
Result(List(Element)) := True;
END LOOP;
RETURN Result;
END Set;
END Set_Package;
GENERIC
TYPE Scalars IS DIGITS <>;
Length: IN Positive;
PACKAGE Vector_Package IS
TYPE Vectors IS PRIVATE;
SUBTYPE Indices IS Integer RANGE
1..Length;
FUNCTION "+" (X,Y: Vectors)
RETURN Vectors;
FUNCTION "*" (Scalar: Scalars; Vector:
Vectors) RETURN Vectors;
FUNCTION "*" (X,Y: Vectors)
RETURN Scalars;
PRIVATE
TYPE Vectors IS ARRAY (Indices) OF
Scalars;
END Vector_Package;
1. Since Unconstrained Array Types Cannot Be Private, Providing A Generic Length Adds Flexibility
2. The First "*' Is Scalar Multiplication, The Second "*" Is Inner Product
PACKAGE BODY Vector_Package IS
FUNCTION "+" (X,Y: Vectors) RETURN Vectors IS
Result: Vectors;
BEGIN
FOR Index IN Indices LOOP
Result(Index) := X(Index) + Y(Index);
END LOOP;
RETURN Result;
END "+";
FUNCTION "*" (Scalar: Scalars; Vector:
Vectors) RETURN Vectors IS
Result: Vectors;
BEGIN
FOR Index IN Indices LOOP
Result(Index) := Scalar * Vector(Index);
END LOOP;
RETURN Result;
END "*";
FUNCTION "*" (X,Y: Vectors) RETURN Scalars IS
Result: Scalars := 0.0;
BEGIN
FOR Index IN Indices LOOP
Result := Result + X(Index) * Y(Index);
END LOOP;
RETURN Result;
END "*";
END Vector_Package;
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 | type_mark
1. Generic Parameter Associations Are Similar To Subprogram Parameter Associations, They Can Be: Named; Positional; Or Mixed With Positional First
GENERIC TYPE Discretes is (<>); FUNCTION Successor(Item: Discretes) RETURN Discretes; TYPE Days IS (Mon,Tue,Wed,Thu,Fri,Sat,Sun); FUNCTION Days_Successor IS NEW Successor(Discretes => Days);
GENERIC TYPE Privates IS PRIVATE; PROCEDURE Swap(X,Y: IN OUT Privates); TYPE Floats IS DIGITS 8; PROCEDURE Floats_Swap IS NEW Swap(Floats);
GENERIC TYPE Elements is (<>); PACKAGE Set_Package IS ... END Set_Package; PACKAGE Sets_Of_Days IS NEW Set_Package(Elements => Days);
GENERIC
WITH FUNCTION f(i: Integer) RETURN Float;
FUNCTION Sum_Terms(n: Integer) RETURN Float;
FUNCTION Sum_Terms(n: Integer)
RETURN Float IS
Sum: Float := 0.0;
BEGIN
FOR Index IN 1..n LOOP
Sum := Sum + f(Index);
END LOOP;
RETURN Sum;
END Sum_Terms;
FUNCTION Square(x: Integer) RETURN Float IS BEGIN RETURN (Float(x * x)); END Square;
FUNCTION Sum_Of_Squares IS NEW Sum_Terms(f => Square);
GENERIC
TYPE Scalars IS PRIVATE;
WITH FUNCTION "+"(Left,Right: Scalars)
RETURN Scalars IS <>;
WITH FUNCTION "*"(Left,Right: Scalars)
RETURN Scalars IS <>;
Zero: IN Scalars;
Length: IN Positive;
PACKAGE Vector_Package IS
TYPE Vectors IS PRIVATE;
SUBTYPE Indices IS Integer RANGE
1..Length;
FUNCTION "+" (X,Y: Vectors)
RETURN Vectors;
FUNCTION "*" (Scalar: Scalars; Vector:
Vectors) RETURN Vectors;
FUNCTION "*" (X,Y: Vectors)
RETURN Scalars;
PRIVATE
TYPE Vectors IS ARRAY (Indices) OF
Scalars;
END Vector_Package;
1. The Scalar Type Can Be Generalized To Any Numeric Type By Supplying The Operators And Constants
1. A Library Unit Must Be Compiled Before Its Corresponding Body
2. A Library Unit Must Be Compiled Before Any Compilation Unit Naming That Compilation Unit In A With Clause
3. A Parent Unit Must Be Compiled Before Any Of Its Subunits
4. The Body Of A Generic Unit Must Be Compiled Before Any Unit Naming It In A With Clause
1. These Rules Define A Partial Order, Any Order Consistent With These Rules Is A Valid Order
2. A Program For Which No Valid Order Exists Is An Illegal Program, Illegal Programs Contain Circular With References
3. An Example Of An Illegal Program Is A Program Containing Two Package Specifications Which Name Each Other In Their With Clauses
4. A Program Which Contains Two Packages Whose Bodies Name Each In Their With Clauses Is A Legal Program, However It Is Not A Recommended Design
/ Top of Page /