[ Table of Contents ]
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. |
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 page
]