DEFINITION MODULE QPNSUMI;
(*===========================================================
    Version  : 1.00  04 May 1989  C. Lins
    Compiler : TopSpeed Modula-2
    Component: Monolithic Structures - Queue (Opaque version)
      Priority Non-balking Sequential Unbounded Managed Iterator

    REVISION HISTORY
    v1.00  04 May 1989  C. Lins:
      Initial TopSpeed Modula-2 implementation.

    (C) Copyright 1989 Charles A. Lins
===========================================================*)

FROM ErrorHandling IMPORT
    (*--Type*) HandlerProc;

FROM Items IMPORT
    (*--Type*) Item, AccessProc, LoopAccessProc;

FROM QEnum IMPORT
    (*--Type*) Exceptions;

FROM Relations IMPORT
    (*--Type*) Relation;

FROM TypeManager IMPORT
    (*--Type*) TypeID;

    (*--------------------*)

(*
11.3.1 Type Declarations

A queue is declared as the abstract data type, Queue.

An item's priority is declared as a generic entity, allowing the client
module to have priorities of any complexity.  All that is needed for
the priority form of queue is the ability to retrieve an item's priority
and to compare priorities for the relational ordering between them.
*)

TYPE  Queue;
CONST NullQueue = Queue(NIL);

TYPE  Priority;
TYPE  PriorityProc    = PROCEDURE (Item) : Priority;
TYPE  PriorityCompare = PROCEDURE (Priority, Priority) : Relation;


(*
11.3.2 Exceptions

The ModuleID uniquely identifies this module from all others.

QueueError returns the most recent queue exception, or noerr if the
last operation was successful.  While SetHandler and GetHandler allow
assignment and retrieval of exception handling routines for specific
exceptions.
*)

CONST ModuleID = 11;

PROCEDURE QueueError () : Exceptions (*-- out   *);

PROCEDURE SetHandler (    theError   : Exceptions  (*-- in    *);
                          theHandler : HandlerProc (*-- in    *));

PROCEDURE GetHandler (    theError   : Exceptions  (*-- in    *))
                                     : HandlerProc (*-- out   *);


(*
11.3.3 Constructors

Only the constructor Create has been changed from the non-priority
form of queue to accomodate procedure parameters to (1) retrieve the
priority for an item, and (2) compare two priorities.  All other
constructors remain unchanged.
*)

PROCEDURE Create  (    theType    : TypeID          (*-- in    *);
                       priorityOf : PriorityProc    (*-- in    *);
                       comparison : PriorityCompare (*-- in    *))
                                  : Queue           (*-- out   *);

PROCEDURE Destroy (VAR theQueue : Queue     (*-- inout *));

PROCEDURE Clear   (VAR theQueue : Queue     (*-- inout *));

PROCEDURE Assign  (    theQueue : Queue     (*-- in    *);
                   VAR toQueue  : Queue     (*-- inout *));

PROCEDURE Arrive  (VAR theQueue : Queue     (*-- inout *);
                       theItem  : Item      (*-- in    *));

PROCEDURE Depart  (VAR theQueue : Queue     (*-- inout *));


(*
11.3.4 Selectors

The is no change to any of the interfaces from the non-priority form.
*)

PROCEDURE IsDefined (    theQueue : Queue    (*-- in    *))
                                  : BOOLEAN  (*-- out   *);

PROCEDURE IsEmpty   (    theQueue : Queue    (*-- in    *))
                                  : BOOLEAN  (*-- out   *);

PROCEDURE IsEqual   (    left     : Queue    (*-- in    *);
                         right    : Queue    (*-- in    *))
                                  : BOOLEAN  (*-- out   *);

PROCEDURE LengthOf  (    theQueue : Queue    (*-- in    *))
                                  : CARDINAL (*-- out   *);

PROCEDURE TypeOf    (    theQueue : Queue    (*-- in    *))
                                  : TypeID   (*-- out   *);

PROCEDURE FrontOf   (    theQueue : Queue    (*-- in    *))
                                  : Item     (*-- out   *);


(*
11.3.5 Iterators
*)

PROCEDURE LoopOver (    theQueue  : Queue          (*-- in    *);
                        theProcess: LoopAccessProc (*-- in    *));

PROCEDURE Traverse (    theQueue  : Queue          (*-- in    *);
                        theProcess: AccessProc     (*-- in    *));

END QPNSUMI.