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;
Rationale references: 12.3.3 A Generic Package with Tasks, 12.3.4 A More Complicated Example
Address any questions or comments to adainfo@sw-eng.falls-church.va.us.