def missing is public, readable = object{
method asString->String{"-"}
}
type Iterator = {
reset->Void
hasNext->Boolean
get->T
next->T}
type Queue = {
enqueue(_:T)->Void
dequeue->T
peek->T
size->Number
clear->Void
isFull->Boolean
isEmpty->Boolean
asString->String
iterator->Iterator}
method withSize(capacity:Number)->Queue is public{QueueArray.new(capacity)}
class QueueArray.new(capacity:Number){
// references to values stored within queue
var data is readable:= PrimitiveArray.new(capacity)
// index of head in queue
var head:Number is readable := 0
// current size of queue
var count:Number is readable := 0
// Add a value to tail of queue
// @pre queue is not full
// @post value added to tail of queue
// @param value the value added
method enqueue(value)->Void is public{
if(!isFull) then {
var tail:Number := (head + count) % data.size
data[tail] := value
count := count + 1}
else{print "Queue is full; can't enqueue value"}
}
// Remove value from head of queue
// @pre queue not empty
// @post head of queue removed and returned
// @return value actually removed
method dequeue->Dynamic is public{
if(!isEmpty) then {
var value := data[head]
head := (head + 1) % data.size
count := count - 1
value}
else{
print "Queue is empty"
missing}
}
// Fetch value at head of queue
// @pre the queue is not empty
// @post @return element at head of queue
method peek->Dynamic is public{
if(!isEmpty) then {data[head]}
else{
print "Queue is empty"
missing}
}
// @post @return number of elements in queue
method size->Number is public{count}
// @post removes all elements from queue
method clear->Void is public{
count := 0
head := 0}
// @post @return true iff queue is at its capacity
method isFull->Boolean is public{count == data.size}
// @post @return true iff queue is empty
method isEmpty->Boolean is public{count == 0}
// @post @return string representation
method asString->String is public{
var str:String := "
str := str ++ " {data[l]}"
l := (l + 1) % data.size}
return str ++ ">"}
// @post @return iterator to traverse queue
method iterator->Iterator is public{QueueIterator.new(data, head)}
}
class QueueIterator.new(source, start:Number){
var data is readable := source
var current:Number is readable := start
var remaining:Number is readable:= data.size
method reset->Void is public{
current := start
remaining := data.size}
method hasNext->Boolean is public{remaining > 0}
method next->Dynamic is public{
var temp:Dynamic := data[current]
current := (current + 1) % data.size
remaining := remaining - 1
temp}
method get->Dynamic is public{data[current]}
}