--::::::::::
--qucntcnt.ads   -- queue_Cntl_Cntl
--::::::::::
-- Copyright (c) 1995      John Beidler
--                         Computing Sciences Dept.
--                         Univ. of Scranton, Scranton, PA 18510
--
--                         (717) 941-7446 voice
--                         (717) 941-4250 FAX
--                         beidler@cs.uofs.edu
--
--  For use by non-profit educational institutions only.
--  This software is GUARANTEED.  Please report any errors.  All
--  corrections will be made as soon as possible (normally within
--  one working day).
------------------------------------------------------------------
--  Assertion notation:
--   /=  not equal
--   {}  empty queue
--   ,   and
--   |   or
--   +   if a is and object and p and p are lists (possibly empty) then
--         p+a+q is a list
-- (f,...,r) a queue may be viewed as an n-tuple with f, the object at the
--       front and r the object at the rear
--   '   If x passed as argument then x' is result after subprog executes
--  #(q) No. of objects in q
------------------------------------------------------------------
--  For safe use of this package
--  The instantiating object should be CONTROLLED
--  Queue_Type is CONTROLLED
------------------------------------------------------------------
with Queue_LPBase, Ada.Finalization;
use Ada.Finalization;
generic
   type Object_Type is private;
   with procedure Swap (Source, Target: in out Object_Type);
package Queue_Cntl_Cntl is
   ------------------------------------------------------
   -- DO NOT USE lpq
      procedure Null_Proc (Object: in out Object_Type);
      procedure Copy (Source: in     Object_Type;
                      Target: in out Object_Type);
      package lpq is new Queue_LPBase
         (Object_Type, Null_Proc, Null_Proc, Copy, Swap);
   ------------------------------------------------------

  type Queue_Type is new controlled with private;

  Queue_Error    : exception renames lpq.Queue_Error;
  Queue_Underflow: exception renames lpq.Queue_Underflow;
  Queue_Overflow : exception renames lpq.Queue_Overflow;

function Empty (Queue: Queue_Type) return boolean;
   ------------------------------------------------------
   -- Pre  Cond  : None
   -- Post Cond  : Return (Queue /= {})
   -- Exceptions : None
   ------------------------------------------------------

function Front (Queue: Queue_Type) return Object_Type;
   ------------------------------------------------------
   -- Pre  Cond  : Queue /= {}
   -- Post Cond  : Returns Queue(1)
   -- Exceptions : Queue_Underflow
   ------------------------------------------------------

procedure Dequeue (Queue : in out Queue_Type);

procedure Dequeue (Queue : in out Queue_Type;
                   Object: in out Object_Type);
   ------------------------------------------------------
   -- Pre  Cond  : Queue /= {}, Queue = (f, rest), rest is a queue
   -- Post Cond  : Object' = f, Queue' = (rest)
   -- Exceptions : Queue_Underflow
   -- NOTE:   Swap used to exchange value of Object_Type
   ------------------------------------------------------

procedure Enqueue (Object: in out Object_Type;
                   Queue : in out Queue_Type);
   ------------------------------------------------------
   -- Pre  Cond  : none,
   -- Post Cond  : Queue' = (Queue, Object)
   -- Exceptions : Queue_Overflow
   -- NOTE:   Swap used to exchange value of Object_Type
   ------------------------------------------------------

procedure Swap (Source: in out Queue_Type;
                Target: in out Queue_Type);
   ------------------------------------------------------
   -- Pre  Cond  : None
   -- Post Cond  : Target' = Source, Source' = Target
   -- Exceptions : None
   ------------------------------------------------------

private
   procedure Initialize (Queue: in out Queue_Type);
   procedure Finalize (Queue: in out Queue_Type);
   procedure Adjust (Queue: in out Queue_Type);

   type Queue_Type is new controlled with
      record
         Actual: lpq.LPQueue_Type;
      end record;

end Queue_Cntl_Cntl;