/******************************************************************************* * Copyright (c) 2007, 2010 Association for Decentralized Information Management * in Industry THTH ry. * 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: * VTT Technical Research Centre of Finland - initial API and implementation *******************************************************************************/ package org.simantics.utils.datastructures.persistent; public abstract class ImmutableStack { private ImmutableStack() { } private static class SingleStackNode extends ImmutableStack { ImmutableStack parent; T value; public SingleStackNode(ImmutableStack parent, T value) { this.parent = parent; this.value = value; } @Override public T get(int i) { return i==0 ? value : parent.get(i-1); } } private static class MultiStackNode extends ImmutableStack { ImmutableStack parent; T[] values; public MultiStackNode(ImmutableStack parent, T[] values) { this.parent = parent; this.values = values; } @Override public T get(int i) { return i extends ImmutableStack { @Override public T get(int i) { throw new IllegalArgumentException("No such element in stack."); } } @SuppressWarnings({ "rawtypes" }) static final EmptyStack EMPTY = new EmptyStack(); public ImmutableStack push(T value) { return new SingleStackNode(this, value); } public ImmutableStack push(T[] values) { if(values.length > 1) return new MultiStackNode(this, values); else if(values.length == 1) return new SingleStackNode(this, values[0]); else return this; } public abstract T get(int i); @SuppressWarnings("unchecked") public static ImmutableStack empty() { return (ImmutableStack)EMPTY; } public static ImmutableStack of(T value) { return new SingleStackNode(null, value); } @SuppressWarnings("unchecked") public static ImmutableStack of(T[] values) { if(values.length > 1) return new MultiStackNode((ImmutableStack)empty(), values); else if(values.length == 1) return new SingleStackNode((ImmutableStack)empty(), values[0]); else return empty(); } }