-- 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;