a_queue.sa


Generated by gen_html_sa_files from ICSI. Contact gomes@icsi.berkeley.edu for details
 
------------------------->  GNU Sather - sourcefile  <-------------------------
-- Copyright (C) 2000 by K Hopper, University of Waikato, New Zealand        --
-- This file is part of the GNU Sather library. It is free software; you may --
-- redistribute  and/or modify it under the terms of the GNU Library General --
-- Public  License (LGPL)  as published  by the  Free  Software  Foundation; --
-- either version 2 of the license, or (at your option) any later version.   --
-- This  library  is distributed  in the  hope that it will  be  useful, but --
-- WITHOUT ANY WARRANTY without even the implied warranty of MERCHANTABILITY --
-- or FITNESS FOR A PARTICULAR PURPOSE. See Doc/LGPL for more details.       --
-- The license text is also available from:  Free Software Foundation, Inc., --
-- 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA                     --
-------------->  Please email comments to <bug-sather@gnu.org>  <--------------


class QUEUE{ETP} < $QUEUE{ETP}

class QUEUE{ETP} < $QUEUE{ETP} is -- This class is merely a wrapper for the array queue implementation -- which follows. -- Version 1.1 Mar 97. Copyright K Hopper, U of Waikato -- Development History -- ------------------- -- Date Who By Detail -- ---- ------ ------ -- 13 Jul 96 bg Original -- 13 Mar 97 kh Adapted for style include A_QUEUE{ETP} ; end ; -- QUEUE

class A_QUEUE{ETP} < $QUEUE{ETP}

class A_QUEUE{ETP} < $QUEUE{ETP} is -- This class is an implementation of a queue based on the use of arrays -- and amortized doubling. -- Version 1.2 Nov 98. Copright K Hopper, U of Waikato -- Development History -- ------------------- -- Date Who By Detail -- ---- ------ ------ -- 13 Jul 96 bg Original -- 13 Mar 97 kh Adapted for CARD and STR -- 10 Nov 98 kh Refined, added pre/post conditions. include COMPARE{ETP} ; include ELT_FILTERS{ETP} ; include CONTAINER_STR{ETP} ; private attr buf : ARRAY{ETP} ; private attr head : CARD ; -- Index of head private attr tail : CARD ; -- Index of next insert private build( sz : CARD ) : SAME pre (sz > 0) post ~void(result) and (result.size = 0) is -- This private routine creates a new queue of the given size and makes -- both pointers point to the beginning. buf := ARRAY{ETP}::create(sz) ; head := 0 ; tail := 0 ; return(self) end ; create_capacity( allocate : CARD ) : SAME pre (allocate > 0) post ~void(result) is -- This creation routine creates a queue with the given number of -- elements. The queue can, of course, grow later. return (new.build(allocate)) end ; create : SAME is -- This routine creates a queue with capacity for one entry. return(create_capacity(1)) end ; create( arr : $ELT{ETP} ) : SAME is -- This routine creates a queue from the elements of arr in the order -- of the elements in the array such that the first element of the array is -- the first element in the queue. me : SAME := SAME::create ; loop me.enq(arr.elt!) end ; return me end ; create_from( arr : ARRAY{ETP} ) : SAME is -- This routine is the same as the one above, but permits the -- specification of a queue with a literal argument. return SAME::create(arr) end ; copy : SAME pre ~void(self) post true -- (result = self) is -- This routine returns a new copy of self. res : SAME := SAME::create(self) ; return res end ; is_empty : BOOL pre ~void(self) post true is -- This predicate returns true if and only if there are no items in -- the queue. return (head = tail) end ; contains( elem : ETP ) : BOOL is -- This predicate returns true if and only if the given element is -- present in the queue. loop element : ETP := elt! ; if elt_eq(elem,element) then return true end end ; return false end ; size : CARD pre ~void(self) post ((tail >= head) and (result = (tail - head))) or ((tail < head) and (result = ((buf.size - head) + tail))) is -- This routine returns the number of elements in the queue. if (tail >= head) then return (tail - head) else return ((buf.size - head) + tail) end end ; enq( elem : ETP ) pre ~void(self) post contains(elem) is -- This routine enqueues the given element at the end of the queue, -- provided that the queue is not void. if ((tail + 1).mod(buf.size) = head) then -- Queue full! loc_q : ARRAY{ETP} := ARRAY{ETP}::create(2 * buf.size) ; index : CARD := head ; loop until!(index = buf.size) ; loc_q[index] := buf[index] ; index := index + 1 end ; if (tail < head) then -- need to copy wrap-around dest : CARD := buf.size ; index := 0 ; loop until!(index = tail) ; loc_q[dest] := buf[index] ; index := index + 1 ; dest := dest + 1 end ; tail := buf.size + tail end ; buf := loc_q end ; buf[tail] := elem ; tail := (tail + 1).mod(buf.size) end ; remove : ETP pre ~is_empty post (head = initial(head + 1).mod(buf.size)) is -- This routine removes the entry at the head of the queue. res : ETP := buf[head] ; buf[head] := void ; -- May be garbage collected head := (head + 1).mod(buf.size) ; return res end ; top : ETP pre ~is_empty post true -- (result = buf[head]) is -- This routine returns the object at the head of the queue without -- removing it. return(buf[head]) end ; current : ETP pre ~is_empty post true -- (result = buf[head]) is -- This routine is a synonym for top. return top end ; elt! : ETP pre ~void(self) post contains(result) is -- This iter returns the elements of the queue in the normal order -- from head to tail without altering the queue. if (head = tail) then quit end ; index : CARD := head ; loop until!(index = tail) ; yield(buf[index]) ; index := (index + 1).mod(buf.size) end end ; end ; -- QUEUE