/*******************************************************************************
* Copyright (c) 2009-2013 CWI
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* * Arnold Lankamp - Arnold.Lankamp@cwi.nl
*******************************************************************************/
package org.rascalmpl.parser.gtd.util;
@SuppressWarnings("unchecked")
public class DoubleStack<E, F>{
private final static int DEFAULT_SIZE = 8;
private E[] firstData;
private F[] secondData;
private int size;
public DoubleStack(){
super();
firstData = (E[]) new Object[DEFAULT_SIZE];
secondData = (F[]) new Object[DEFAULT_SIZE];
size = 0;
}
public DoubleStack(int initialSize){
super();
firstData = (E[]) new Object[initialSize];
secondData = (F[]) new Object[initialSize];
size = 0;
}
public void enlarge(){
E[] oldFirstData = firstData;
firstData = (E[]) new Object[size << 1];
System.arraycopy(oldFirstData, 0, firstData, 0, size);
F[] oldSecondData = secondData;
secondData = (F[]) new Object[size << 1];
System.arraycopy(oldSecondData, 0, secondData, 0, size);
}
public void push(E first, F second){
while(size >= firstData.length){
enlarge();
}
firstData[size] = first;
secondData[size++] = second;
}
public E peekFirst(){
return firstData[size - 1];
}
public F peekSecond(){
return secondData[size - 1];
}
public E popFirst(){
E first = firstData[--size];
firstData[size] = null;
secondData[size] = null;
return first;
}
public F popSecond(){
F second = secondData[--size];
firstData[size] = null;
secondData[size] = null;
return second;
}
public void purge(){
firstData[--size] = null;
}
public E dirtyPop(){
return firstData[--size];
}
public void dirtyPurge(){
--size;
}
public E getFirst(int index){
return firstData[index];
}
public F getSecond(int index){
return secondData[index];
}
public int findFirst(E object){
for(int i = size - 1; i >= 0; --i){
if(firstData[i].equals(object)) return i;
}
return -1;
}
public int findSecond(F object){
for(int i = size - 1; i >= 0; --i){
if(secondData[i].equals(object)) return i;
}
return -1;
}
public boolean containsFirst(E object){
for(int i = size - 1; i >= 0; --i){
if(firstData[i].equals(object)) return true;
}
return false;
}
public boolean containsSecond(F object){
for(int i = size - 1; i >= 0; --i){
if(secondData[i].equals(object)) return true;
}
return false;
}
public E findFirstWithFirst(E object){
for(int i = size - 1; i >= 0; --i){
E objectToCompareWith = firstData[i];
if(objectToCompareWith.equals(object)) return objectToCompareWith;
}
return null;
}
public F findSecondWithFirst(E object){
for(int i = size - 1; i >= 0; --i){
if(firstData[i].equals(object)) return secondData[i];
}
return null;
}
public E findFirstWithSecond(F object){
for(int i = size - 1; i >= 0; --i){
if(secondData[i].equals(object)) return firstData[i];
}
return null;
}
public F findSecondWithSecond(F object){
for(int i = size - 1; i >= 0; --i){
F objectToCompareWith = secondData[i];
if(objectToCompareWith.equals(object)) return objectToCompareWith;
}
return null;
}
public int getSize(){
return size;
}
public boolean isEmpty(){
return (size == 0);
}
public void clear(){
firstData = (E[]) new Object[firstData.length];
secondData = (F[]) new Object[secondData.length];
size = 0;
}
public void dirtyClear(){
size = 0;
}
}