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