![[PREVIOUS]](lrm-prev.gif)
![[UP]](lrm-up.gif)
The following example provides a possible formulation of stacks by means of a generic package. The size of each stack and the type of the stack elements are provided as generic parameters.
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;
Instances of this generic package can be obtained as follows:
package STACK_INT is new STACK(SIZE => 200, ITEM => INTEGER);
package STACK_BOOL is new STACK(100, BOOLEAN);
Thereafter, the procedures of the instantiated packages can be called as follows:
STACK_INT.PUSH(N);
STACK_BOOL.PUSH(TRUE);
Alternatively, a generic formulation of the type STACK can be given as follows (package body omitted):
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;
In order to use such a package, an instantiation must be created and thereafter stacks of the corresponding type can be declared:
declare
package STACK_REAL is new ON_STACKS(REAL); use STACK_REAL;
S : STACK(100)
begin
...
PUSH(S, 2.54);
...
end;
![[INDEX]](lrm-idx.gif)
![[CONTENTS]](lrm-toc.gif)