Generics
Display Array
Goal: create a generic procedure that displays the elements of an array.
Steps:
Implement the generic procedure
Display_Array.
Requirements:
Generic procedure
Display_Arraydisplays the elements of an array.
It uses the following scheme:
First, it displays a header.
Then, it displays the elements of the array.
When displaying the elements, it must:
use one line per element, and
include the corresponding index of the array.
This is the expected format:
<HEADER> <index #1>: <element #1> <index #2>: <element #2> ...For example:
For the following code:
procedure Test is A : Int_Array (1 .. 2) := (1, 5); begin Display_Int_Array ("Elements of A", A);; end Test;The output is:
Elements of A 1: 1 2: 5These are the formal parameters of the procedure:
a range type
T_Rangefor the the array;a formal type
T_Elementfor the elements of the array;
This type must be declared in such a way that it can be mapped to any type in the instantiation — including record types.
an array type
T_Arrayusing theT_RangeandT_Elementtypes;a function
Imagethat converts a variable ofT_Elementtype to aString.
generic
procedure Display_Array (Header : String;
A : T_Array);
with Ada.Text_IO; use Ada.Text_IO;
procedure Display_Array (Header : String;
A : T_Array) is
begin
null;
end Display_Array;
with Ada.Command_Line; use Ada.Command_Line;
with Ada.Text_IO; use Ada.Text_IO;
with Display_Array;
procedure Main is
type Test_Case_Index is (Int_Array_Chk,
Point_Array_Chk);
procedure Test_Int_Array is
type Int_Array is array (Positive range <>) of Integer;
procedure Display_Int_Array is new
Display_Array (T_Range => Positive,
T_Element => Integer,
T_Array => Int_Array,
Image => Integer'Image);
A : constant Int_Array (1 .. 5) := (1, 2, 5, 7, 10);
begin
Display_Int_Array ("Integers", A);
end Test_Int_Array;
procedure Test_Point_Array is
type Point is record
X : Float;
Y : Float;
end record;
type Point_Array is array (Natural range <>) of Point;
function Image (P : Point) return String is
begin
return "(" & Float'Image (P.X)
& ", " & Float'Image (P.Y) & ")";
end Image;
procedure Display_Point_Array is new
Display_Array (T_Range => Natural,
T_Element => Point,
T_Array => Point_Array,
Image => Image);
A : constant Point_Array (0 .. 3) := ((1.0, 0.5), (2.0, -0.5),
(5.0, 2.0), (-0.5, 2.0));
begin
Display_Point_Array ("Points", A);
end Test_Point_Array;
procedure Check (TC : Test_Case_Index) is
begin
case TC is
when Int_Array_Chk =>
Test_Int_Array;
when Point_Array_Chk =>
Test_Point_Array;
end case;
end Check;
begin
if Argument_Count < 1 then
Put_Line ("ERROR: missing arguments! Exiting...");
return;
elsif Argument_Count > 1 then
Put_Line ("Ignoring additional arguments...");
end if;
Check (Test_Case_Index'Value (Argument (1)));
end Main;
Average of Array of Float
Goal: create a generic function that calculates the average of an array of floating-point elements.
Steps:
Declare and implement the generic function
Average.
Requirements:
Generic function
Averagecalculates the average of an array containing floating-point values of arbitrary precision.Generic function
Averagemust contain the following formal parameters:
a range type
T_Rangefor the array;a formal type
T_Elementthat can be mapped to floating-point types of arbitrary precision;an array type
T_ArrayusingT_RangeandT_Element;
Remarks:
You should use the
Floattype for the accumulator.
generic
function Average (A : T_Array) return T_Element;
function Average (A : T_Array) return T_Element is
begin
return 0.0;
end Average;
with Ada.Command_Line; use Ada.Command_Line;
with Ada.Text_IO; use Ada.Text_IO;
with Average;
procedure Main is
type Test_Case_Index is (Float_Array_Chk,
Digits_7_Float_Array_Chk);
procedure Test_Float_Array is
type Float_Array is array (Positive range <>) of Float;
function Average_Float is new
Average (T_Range => Positive,
T_Element => Float,
T_Array => Float_Array);
A : constant Float_Array (1 .. 5) := (1.0, 3.0, 5.0, 7.5, -12.5);
begin
Put_Line ("Average: " & Float'Image (Average_Float (A)));
end Test_Float_Array;
procedure Test_Digits_7_Float_Array is
type Custom_Float is digits 7 range 0.0 .. 1.0;
type Float_Array is
array (Integer range <>) of Custom_Float;
function Average_Float is new
Average (T_Range => Integer,
T_Element => Custom_Float,
T_Array => Float_Array);
A : constant Float_Array (-1 .. 3) := (0.5, 0.0, 1.0, 0.6, 0.5);
begin
Put_Line ("Average: "
& Custom_Float'Image (Average_Float (A)));
end Test_Digits_7_Float_Array;
procedure Check (TC : Test_Case_Index) is
begin
case TC is
when Float_Array_Chk =>
Test_Float_Array;
when Digits_7_Float_Array_Chk =>
Test_Digits_7_Float_Array;
end case;
end Check;
begin
if Argument_Count < 1 then
Put_Line ("ERROR: missing arguments! Exiting...");
return;
elsif Argument_Count > 1 then
Put_Line ("Ignoring additional arguments...");
end if;
Check (Test_Case_Index'Value (Argument (1)));
end Main;
Average of Array of Any Type
Goal: create a generic function that calculates the average of an array of elements of any arbitrary type.
Steps:
Declare and implement the generic function
Average.Implement the test procedure
Test_Item.
Declare the
F_IOpackage.Implement the
Get_Totalfunction for theItemtype.Implement the
Get_Pricefunction for theItemtype.Declare the
Average_Totalfunction.Declare the
Average_Pricefunction.
Requirements:
Generic function
Averagecalculates the average of an array containing elements of any arbitrary type.Generic function
Averagehas the same formal parameters as in the previous exercise, except for:
T_Element, which is now a formal type that can be mapped to any arbitrary type.
To_Float, which is an additional formal parameter.
To_Floatis a function that converts the arbitrary element ofT_Elementtype to theFloattype.Procedure
Test_Itemis used to test the genericAverageprocedure for a record type (Item).
Record type
Itemcontains theQuantityandPricecomponents.The following functions have to implemented to be used for the formal
To_Floatfunction parameter:
For the
Decimaltype, the function is pretty straightforward: it simply returns the floating-point value converted from the decimal type.For the
Itemtype, two functions must be created to convert to floating-point type:
Get_Total, which returns the multiplication of the quantity and the price components of theItemtype;
Get_Price, which returns just the price.The generic function
Averagemust be instantiated as follows:
For the
Itemtype, you must:
declare the
Average_Totalfunction (as an instance ofAverage) using theGet_Totalfor theTo_Floatparameter;declare the
Average_Pricefunction (as an instance ofAverage) using theGet_Pricefor theTo_Floatparameter.You must use the
Putprocedure fromAda.Text_IO.Float_IO.
The generic standard package
Ada.Text_IO.Float_IOmust be instantiated asF_IOin the test procedures.This is the specification of the
Putprocedure, as described in the appendix A.10.9 of the Ada Reference Manual:procedure Put(Item : in Num; Fore : in Field := Default_Fore; Aft : in Field := Default_Aft; Exp : in Field := Default_Exp);This is the expected format when calling
PutfromFloat_IO:
Function
Fore
Aft
Exp
Test_Item3
2
0
Remarks:
In this exercise, you'll abstract the
Averagefunction from the previous exercises a step further.
In this case, the function shall be able to calculate the average of any arbitrary type — including arrays containing elements of record types.
Since record types can be composed by many components of different types, we need to provide a way to indicate which component (or components) of the record will be used when calculating the average of the array.
This problem is solved by specifying a
To_Floatfunction as a formal parameter, which converts the arbitrary element ofT_Elementtype to theFloattype.In the implementation of the
Averagefunction, we use theTo_Floatfunction and calculate the average using a floating-point variable.
generic
function Average (A : T_Array) return Float;
function Average (A : T_Array) return Float is
begin
null;
end Average;
procedure Test_Item;
with Ada.Text_IO; use Ada.Text_IO;
with Average;
procedure Test_Item is
type Amount is delta 0.01 digits 12;
type Item is record
Quantity : Natural;
Price : Amount;
end record;
type Item_Array is
array (Positive range <>) of Item;
A : constant Item_Array (1 .. 4)
:= ((Quantity => 5, Price => 10.00),
(Quantity => 80, Price => 2.50),
(Quantity => 40, Price => 5.00),
(Quantity => 20, Price => 12.50));
begin
Put ("Average per item & quantity: ");
F_IO.Put (Average_Total (A));
New_Line;
Put ("Average price: ");
F_IO.Put (Average_Price (A));
New_Line;
end Test_Item;
with Ada.Command_Line; use Ada.Command_Line;
with Ada.Text_IO; use Ada.Text_IO;
with Test_Item;
procedure Main is
type Test_Case_Index is (Item_Array_Chk);
procedure Check (TC : Test_Case_Index) is
begin
case TC is
when Item_Array_Chk =>
Test_Item;
end case;
end Check;
begin
if Argument_Count < 1 then
Put_Line ("ERROR: missing arguments! Exiting...");
return;
elsif Argument_Count > 1 then
Put_Line ("Ignoring additional arguments...");
end if;
Check (Test_Case_Index'Value (Argument (1)));
end Main;
Generic list
Goal: create a system based on a generic list to add and displays elements.
Steps:
Declare and implement the generic package
Gen_List.
Implement the
Initprocedure.Implement the
Addprocedure.Implement the
Displayprocedure.
Requirements:
Generic package
Gen_Listmust have the following subprograms:
Procedure
Initinitializes the list.Procedure
Addadds an item to the list.
This procedure must contain a
Statusoutput parameter that is set toFalsewhen the list was full — i.e. if the procedure failed while trying to add the item;Procedure
Displaydisplays the complete list.
This includes the name of the list and its elements — using one line per element.
This is the expected format:
<NAME> <element #1> <element #2> ...Generic package
Gen_Listhas these formal parameters:
an arbitrary formal type
Item;an unconstrained array type
ItemsofItemelement with positive range;the
Nameparameter containing the name of the list;
This must be a formal input object of
Stringtype.It must be used in the
Displayprocedure.an actual array
List_Arrayto store the list;
This must be a formal
in outobject ofItemstype.the variable
Lastto store the index of the last element;
This must be a formal
in outobject ofNaturaltype.a procedure
Putfor theItemtype.
This procedure is used in the
Displayprocedure to display individual elements of the list.The test procedure
Test_Intis used to test a list of elements ofIntegertype.For both test procedures, you must:
add missing type declarations;
declare and implement a
Putprocedure for individual elements of the list;declare instances of the
Gen_Listpackage.
For the
Test_Intprocedure, declare theInt_Listpackage.
Remarks:
In previous labs, you've been implementing lists for a variety of types.
The List of Names exercise from the Arrays labs is an example.
In this exercise, you have to abstract those implementations to create the generic
Gen_Listpackage.
generic
package Gen_List is
procedure Init;
procedure Add (I : Item;
Status : out Boolean);
procedure Display;
end Gen_List;
with Ada.Text_IO; use Ada.Text_IO;
package body Gen_List is
procedure Init is
begin
null;
end Init;
procedure Add (I : Item;
Status : out Boolean) is
begin
null;
end Add;
procedure Display is
begin
null;
end Display;
end Gen_List;
procedure Test_Int;
with Ada.Text_IO; use Ada.Text_IO;
with Gen_List;
procedure Test_Int is
type Integer_Array is array (Positive range <>) of Integer;
A : Integer_Array (1 .. 3);
L : Natural;
Success : Boolean;
procedure Display_Add_Success (Success : Boolean) is
begin
if Success then
Put_Line ("Added item successfully!");
else
Put_Line ("Couldn't add item!");
end if;
end Display_Add_Success;
begin
Int_List.Init;
Int_List.Add (2, Success);
Display_Add_Success (Success);
Int_List.Add (5, Success);
Display_Add_Success (Success);
Int_List.Add (7, Success);
Display_Add_Success (Success);
Int_List.Add (8, Success);
Display_Add_Success (Success);
Int_List.Display;
end Test_Int;
with Ada.Command_Line; use Ada.Command_Line;
with Ada.Text_IO; use Ada.Text_IO;
with Test_Int;
procedure Main is
type Test_Case_Index is (Int_Chk);
procedure Check (TC : Test_Case_Index) is
begin
case TC is
when Int_Chk =>
Test_Int;
end case;
end Check;
begin
if Argument_Count < 1 then
Put_Line ("ERROR: missing arguments! Exiting...");
return;
elsif Argument_Count > 1 then
Put_Line ("Ignoring additional arguments...");
end if;
Check (Test_Case_Index'Value (Argument (1)));
end Main;