-- GENERIC PACKAGE FOR QUEUES -------------------------- -- Last Modified By: Mats Weber -- Last Modified On: Mon Jun 8 11:47:50 1998 -- Update Count : 10 -- Revision : 20-SEP-1986 by Mats Weber, corrected DESTROY. -- Creation : 10-FEB-1986 by Mats Weber. with Exchange, Unchecked_Deallocation; package body Queues is ------------------- procedure Put (Item : in Item_Type; Into : in out Queue) is begin Into.Length := Into.Length + 1; -- may raise CONSTRAINT_ERROR if Into.Last /= null then Into.Last.Next := new Cell'(Val => Item, Next => null); Into.Last := Into.Last.Next; else Into.Last := new Cell'(Val => Item, Next => null); Into.First := Into.Last; end if; end Put; procedure Dispose is new Unchecked_Deallocation(Cell, Link); procedure Get (From : in out Queue; Item : out Item_Type) is Z : Link := From.First; begin if From.First = null then raise Queue_Empty; end if; Item := From.First.Val; From.First := From.First.Next; if From.First = null then From.Last := null; end if; From.Length := From.Length - 1; Dispose(Z); end Get; procedure Get (From : in out Queue) is Z : Link := From.First; begin if From.First = null then raise Queue_Empty; end if; From.First := From.First.Next; if From.First = null then From.Last := null; end if; From.Length := From.Length - 1; Dispose(Z); end Get; function First (Of_Queue : Queue) return Item_Type is begin if Of_Queue.First = null then raise Queue_Empty; end if; return Of_Queue.First.Val; end; function Last (Of_Queue : Queue) return Item_Type is begin if Of_Queue.Last = null then raise Queue_Empty; end if; return Of_Queue.Last.Val; end; function Length (Of_Queue : Queue) return Natural_Count is begin return Of_Queue.Length; end; function Empty (The_Queue : Queue) return Boolean is begin return The_Queue.First = null; end; function "=" (Left, Right : Queue) return Boolean is begin if Left.Length /= Right.Length then return False; end if; declare Z_Left : Link := Left.First; Z_Right : Link := Right.First; begin while Z_Left /= null loop if Z_Left.Val /= Z_Right.Val then return False; end if; Z_Left := Z_Left.Next; Z_Right := Z_Right.Next; end loop; return True; end; end "="; procedure Traversal (On_Queue : in Queue) is P : Link := On_Queue.First; begin while P /= null loop Action(P.Val); P := P.Next; end loop; end Traversal; procedure Update_All (On_Queue : in out Queue) is P : Link := On_Queue.First; begin while P /= null loop Update_Item(P.Val); P := P.Next; end loop; end Update_All; procedure Assign (Object : in out Queue; Value : in Queue) is begin Destroy(Object); if Value.First /= null then declare Z : Link := Value.First.Next; P : Link := new Cell'(Val => Value.First.Val, Next => null); begin Object.First := P; while Z /= null loop P.Next := new Cell'(Val => Z.Val, Next => null); P := P.Next; Z := Z.Next; end loop; Object.Last := P; Object.Length := Value.Length; end; end if; end Assign; procedure Swap (Left, Right : in out Queue) is procedure Swap is new Exchange(Link); procedure Swap is new Exchange(Natural_Count); begin Swap(Left.First, Right.First); Swap(Left.Last, Right.Last); Swap(Left.Length, Right.Length); end Swap; procedure Destroy (The_Queue : in out Queue) is Z : Link; begin while The_Queue.First /= null loop Z := The_Queue.First; The_Queue.First := The_Queue.First.Next; Dispose(Z); end loop; The_Queue.Last := null; The_Queue.Length := 0; end Destroy; end Queues;