1 /*******************************************************************************
\r
2 * Copyright (c) 2007, 2010 Association for Decentralized Information Management
\r
3 * in Industry THTH ry.
\r
4 * All rights reserved. This program and the accompanying materials
\r
5 * are made available under the terms of the Eclipse Public License v1.0
\r
6 * which accompanies this distribution, and is available at
\r
7 * http://www.eclipse.org/legal/epl-v10.html
\r
10 * VTT Technical Research Centre of Finland - initial API and implementation
\r
11 *******************************************************************************/
\r
12 package org.simantics.utils.datastructures.persistent;
\r
14 public abstract class ImmutableStack<T> {
\r
16 private ImmutableStack() {
\r
19 private static class SingleStackNode<T> extends ImmutableStack<T> {
\r
20 ImmutableStack<T> parent;
\r
23 public SingleStackNode(ImmutableStack<T> parent, T value) {
\r
24 this.parent = parent;
\r
29 public T get(int i) {
\r
30 return i==0 ? value : parent.get(i-1);
\r
34 private static class MultiStackNode<T> extends ImmutableStack<T> {
\r
35 ImmutableStack<T> parent;
\r
38 public MultiStackNode(ImmutableStack<T> parent, T[] values) {
\r
39 this.parent = parent;
\r
40 this.values = values;
\r
44 public T get(int i) {
\r
45 return i<values.length ? values[i] : parent.get(i-values.length);
\r
49 private static class EmptyStack<T> extends ImmutableStack<T> {
\r
52 public T get(int i) {
\r
53 throw new IllegalArgumentException("No such element in stack.");
\r
58 @SuppressWarnings({ "rawtypes" })
\r
59 static final EmptyStack EMPTY = new EmptyStack();
\r
61 public ImmutableStack<T> push(T value) {
\r
62 return new SingleStackNode<T>(this, value);
\r
65 public ImmutableStack<T> push(T[] values) {
\r
66 if(values.length > 1)
\r
67 return new MultiStackNode<T>(this, values);
\r
68 else if(values.length == 1)
\r
69 return new SingleStackNode<T>(this, values[0]);
\r
74 public abstract T get(int i);
\r
76 @SuppressWarnings("unchecked")
\r
77 public static <T> ImmutableStack<T> empty() {
\r
78 return (ImmutableStack<T>)EMPTY;
\r
81 public static <T> ImmutableStack<T> of(T value) {
\r
82 return new SingleStackNode<T>(null, value);
\r
85 @SuppressWarnings("unchecked")
\r
86 public static <T> ImmutableStack<T> of(T[] values) {
\r
87 if(values.length > 1)
\r
88 return new MultiStackNode<T>((ImmutableStack<T>)empty(), values);
\r
89 else if(values.length == 1)
\r
90 return new SingleStackNode<T>((ImmutableStack<T>)empty(), values[0]);
\r