-- This is the generic specification for a queue abstract data type.

generic

    Size : Positive;

    type ItemType is private;

package QueuePkg is

    type Queue is limited private;

    Queue_Empty, Queue_Full : exception;

    function IsEmpty  (Q : Queue) return Boolean;
    function IsFull   (Q : Queue) return Boolean;

    procedure Enqueue (Item : ItemType; Q : in out Queue);
    procedure Dequeue (                 Q : in out Queue);

    function  Front   (Q : Queue) return ItemType;

private
    type QueueElements is array(0..Size-1) of ItemType;

    -- Implemented by accessing an array in a CIRCULAR order.  
        -- The array is accessed in circular order by using "mod Size"
        -- Remember that (x mod Size) is in the range (0..Size-1)

        -- Back points to the spot where the NEXT enqueued item is to go!  
        -- CurSize contains the number of elements currently on the queue

        -- A queue is empty when the next element to be added would go into
        -- the Front position (ie when the Front and Back have the same value)
        -- A queue is full when the next element to add would fill the last
        --   open position in the queue [ie when (Back + 1) mod Size = Front]

    type Queue is record
        Elements : QueueElements;
        Front, Back, CurSize : Natural := 0;
    end record;

end QueuePkg;