/* * Kodkod -- Copyright (c) 2005-present, Emina Torlak * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ package kodkod.util.collections; import java.util.EmptyStackException; import java.util.Iterator; import java.util.NoSuchElementException; /** * A Stack implementation based on an array. * * @author Emina Torlak */ public class ArrayStack<T> extends Stack<T> { /* stack elements: the last element in the array is at the top of the stack. */ private T[] elems; private int size; /** * Constructs an empty stack with the inital capacity of 10. * @ensures no this.elems' */ public ArrayStack() { this(10); } @SuppressWarnings("unchecked") public ArrayStack(int initialCapacity) { if (initialCapacity < 0) throw new IllegalArgumentException(initialCapacity + "<0"); elems = (T[]) new Object[initialCapacity]; size = 0; } /** * Increases the capacity of this ArrayStack, if necessary, to ensure that * it can hold at least the number of elements specified by the minimum * capacity argument. */ @SuppressWarnings("unchecked") public void ensureCapacity(int minCapacity) { final int oldCapacity = elems.length; if (minCapacity > oldCapacity) { final T[] oldElems = elems; elems = (T[]) new Object[StrictMath.max(minCapacity, (oldCapacity * 3) / 2)]; System.arraycopy(oldElems,0,elems,0,size); } } /** * Trims the capacity of this ArrayStack to be the * stack's current size. An application can use this operation to minimize * the storage of an ArrayStack instance. */ @SuppressWarnings("unchecked") public void trimToSize() { final int oldCapacity = elems.length; if (size < oldCapacity) { final Object oldElems[] = elems; elems = (T[])new Object[size]; System.arraycopy(oldElems, 0, elems, 0, size); } } /** * @see kodkod.util.collections.Stack#size() */ public int size() { return size; } /** * {@inheritDoc} * @see kodkod.util.collections.Stack#push */ public T push(T item) { ensureCapacity(size + 1); elems[size++] = item; return item; } /** * @see kodkod.util.collections.Stack#pop() */ public T pop() { if (empty()) throw new EmptyStackException(); final T top = elems[--size]; elems[size] = null; return top; } /** * @see kodkod.util.collections.Stack#peek() */ public T peek() { if (empty()) throw new EmptyStackException(); return elems[size-1]; } /** * @see kodkod.util.collections.Stack#search(java.lang.Object) */ public int search(Object o) { for(int i = size-1; i >= 0; i--) { if (equal(o, elems[i])) return i; } return -1; } /** * @see kodkod.util.collections.Stack#empty() */ public boolean empty() { return size==0; } /** * {@inheritDoc} * @see kodkod.util.collections.Stack#iterator() */ public Iterator<T> iterator() { return new Iterator<T>() { int cursor = size - 1, lastReturned = -1; public boolean hasNext() { return cursor >= 0; } public T next() { if (cursor < 0) throw new NoSuchElementException(); lastReturned = cursor; return elems[cursor--]; } public void remove() { if (lastReturned < 0) throw new UnsupportedOperationException(); size--; System.arraycopy(elems, lastReturned+1, elems, lastReturned, size - lastReturned); elems[size] = null; lastReturned = -1; } }; } }