2.11 Generic Units

[ Table of Contents ] Prev ] Chapter Overview ] Next ] [ Glossary/Index ]

Here is the third in the series of examples implementing push-down stacks. We use it to introduce the topic of generic units and the process of generic instantiation. Generic units are templates, which form the basis for creating other units called generic instances via instantiation. Generics provide a form of static polymorphism. The declaration of a generic unit always begins with the reserved word, generic.

The package represented on the right side of this diagram has a structure very similar to the ADT package of the previous example. However, it is a generic unit, a package with two formal generic parameters: Size and Item_Type. The test procedure declares two generic instances, packages SS4 and SS5. Based on these, two actual stacks called S4 and S5 are declared. One stores strings of length 4, and the other stores strings of length 5.

Im2-10.gif (6811 bytes)

This generic package can be considered a "parameterized ADT" facility. We can now create instances of stacks with any desired value of Size and any desired choice of Item_Type. Note the use of the reserved word new in declaring the generic instances, SS4 and SS5.

Source Code Listing

----------------------------------------------------------
----------------------- Generic_Stack --------------------
--  This generic package provides a template that can be 
--  the basis for stacks with different sizes and which 
--  store items of different types.
----------------------------------------------------------
generic
  Size : Positive;             -- formal generic parameter
  type Item_Type is private;   -- formal generic parameter
package Generic_Stack is
    
  type Stack_Type is private;
  procedure Push(Stack : in out Stack_Type;
                 Item  : in Item_Type);
  procedure Pop (Stack : in out Stack_Type;
                 Item  : out Item_Type);
private
    
  type Space_Type is array (1..Size) of Item_Type;

  type Stack_Type is record
    Index : Integer range 0..Size := 0;
    Space : Space_Type;
  end record;
               
end Generic_Stack;
---------------------------------------------
package body Generic_Stack is
  
  procedure Push(Stack : in out Stack_Type;
                 Item  : in Item_Type) is
  begin
    Stack.Index := Stack.Index + 1;
    Stack.Space(Stack.Index) := Item;  
  end Push;                   
                     
  procedure Pop (Stack : in out Stack_Type;
                 Item  : out Item_Type) is
  begin
    Item := Stack.Space(Stack.Index);
    Stack.Index := Stack.Index - 1;  
  end Pop;                   
                       
end Generic_Stack;   
----------------------------------------------------------
--------------------- Test_Generic_Stack -----------------
--  This test procedure declares two instances of the 
--  generic stack. Both have size 8. One stores strings 
--  of four characters. The other stores strings of five 
--  characters. Five items are pushed onto each stack, and
--  then two loops are set up to pop and display the items.
----------------------------------------------------------
with Ada.Text_IO;
use  Ada.Text_IO;
with Generic_Stack;
procedure Test_Generic_Stack is          
  
  subtype String_4 is String(1..4);
  subtype String_5 is String(1..5);
  
  Str4 : String_4;
  Str5 : String_5;
  
  package SS4 is new Generic_Stack
          (Size => 8, Item_Type => String_4);
  package SS5 is new Generic_Stack
          (Size => 8, Item_Type => String_5);
          
  S4 : SS4.Stack_Type;
  S5 : SS5.Stack_Type;
    
begin
    Put_Line("Testing generic stack");
    New_Line;
    
    SS4.Push(S4,"Eric"); SS5.Push(S5, "Erica");
    SS4.Push(S4,"Dave"); SS5.Push(S5, "Doris");
    SS4.Push(S4,"Carl"); SS5.Push(S5, "Carol");
    SS4.Push(S4,"Bill"); SS5.Push(S5, "Betty");
    SS4.Push(S4,"Adam"); SS5.Push(S5, "Alice");
                                               
    for I in 1..5 loop
      SS4.Pop(S4, Str4);
      SS5.Pop(S5, Str5);
      Put_Line(Str4 & "  " & Str5);
    end loop;
    
end Test_Generic_Stack;
----------------------------------------------------------

The above program produces the following output:

     Testing generic stack

     Adam  Alice
     Bill  Betty
     Carl  Carol
     Dave  Doris
     Eric  Erica

Generic File-Handling  and Input-Output Services

The predefined environment includes several generic packages whose facilities can be used as templates for generic instances with procedures that create, open, close, write-to, and read-from external files. The names of these generic packages are Ada.Direct_IO, Ada.Sequential_IO, and Ada.Streams.Stream_IO. (These services are not illustrated in this volume.)

The predefined package Ada.Text_IO exports several generic packages, which can be the basis for instantiation of new packages that provide input/output facilities for specific user-defined quantities such as integers, floating-point types, fixed-point types and enumeration types. (Some examples are given in Chapter 4.)

Related Topics

2.2 Program Units 2.9 Simple (ADO) Stack
2.10 Abstract (ADT) Stack 3.9 The raise Statement
4.5 Numeric Types B.2 Package Ada and Children

[ Back to top of pagePrev ] Next ]