package basictype;
/**
 * A queue is an ordered collection of items.
 * You can add items at the end of the queue, 
 * remove items from the head of the queue, and get its size.
 * 
 * You can also get an iterator on its elements.
 * 
 * @author Frederic Boulanger frederic.boulanger@supelec.fr
 *
 * @param <T> the type of elements in the queue
 * 
 * In the specification, we split the dequeue method into a head() 
 * operation which yields the first item in the queue, and a dequeue 
 * operation which removes it from the queue 
 * 
 * @spec
 * emptyQueue : -> Queue
 * enqueue : Queue, Item -> Queue
 * dequeue : Queue -> Queue
 * head : Queue -> Item
 * size : Queue -> Nat
 * 
 * pre(dequeue(q)) = size(q) > 0
 * pre(head(q)) = size(q) > 0
 * 
 * dequeue(enqueue(emptyQueue, e)) = emptyQueue
 * dequeue(enqueue(enqueue(q, e_1), e_2) = enqueue(dequeue(enqueue(q, e_1)), e_2)
 * head(enqueue(emptyQueue, e)) = e
 * head(enqueue(enqueue(q, e_1), e_2) = head(enqueue(q, e_1))
 * size(Queue) = 0
 * size(enqueue(q,i)) = succ(size(q))
 * 
 */
public abstract class Queue<T> implements Iterable<T> {
  public abstract void enqueue(T item);
  public abstract T dequeue();
  public abstract int size();
  @Override
  public String toString() {
    StringBuffer buf = new StringBuffer("<");
    boolean first = true;
    for (T item : this) {
      if (first) {
        first = false;
      } else {
        buf.append(", ");
      }
      buf.append(item.toString());
    }
    buf.append("<");
    return buf.toString();
  }
}
