/******************************************************************************* * 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.collections; import java.util.Arrays; public class LightweightList { public static final Object EMPTY = new LL0(); public static Object add(Object list, Object value) { if(list instanceof LL) return ((LL)list).add(value); else return new LL2(list, value); } public static Object remove(Object list, Object value) { if(list instanceof LL) return ((LL)list).remove(value); else return value.equals(list) ? EMPTY : list; } public static int size(Object list) { if(list instanceof LL) return ((LL)list).size(); else return 1; } public static boolean isEmpty(Object list) { return list==EMPTY; } public static Object[] toArray(Object list) { if(list == null) return EMPTY_ARRAY; else if(list instanceof LL) return ((LL)list).toArray(); else return new Object[] { list }; } public static interface IProcedure { void exec(Object obj); } public static void forEach(Object list, IProcedure proc) { if(list == null) return; else if(list instanceof LL) ((LL)list).forEach(proc); else proc.exec(list); } private static interface LL { Object add(Object value); Object remove(Object value); int size(); Object[] toArray(); void forEach(IProcedure proc); } static final Object[] EMPTY_ARRAY = new Object[0]; private static class LL0 implements LL { @Override public Object add(Object value) { return value; } @Override public Object remove(Object value) { return this; } @Override public int size() { return 0; } @Override public Object[] toArray() { return EMPTY_ARRAY; } @Override public void forEach(IProcedure proc) { } } private static class LL2 implements LL { Object v0, v1; public LL2(Object v0, Object v1) { this.v0 = v0; this.v1 = v1; } @Override public Object add(Object value) { return new LL3(v0, v1, value); } @Override public Object remove(Object value) { if(value.equals(v0)) return v1; else if(value.equals(v1)) return v0; else return this; } @Override public int size() { return 2; } @Override public Object[] toArray() { return new Object[] { v0, v1 }; } @Override public void forEach(IProcedure proc) { proc.exec(v0); proc.exec(v1); } } private static class LL3 implements LL { Object v0, v1, v2; public LL3(Object v0, Object v1, Object v2) { this.v0 = v0; this.v1 = v1; this.v2 = v2; } @Override public Object add(Object value) { return new LLN(v0, v1, v2, value); } @Override public Object remove(Object value) { if(value.equals(v0)) return new LL2(v1, v2); else if(value.equals(v1)) return new LL2(v0, v2); else if(value.equals(v2)) return new LL2(v0, v1); else return this; } @Override public int size() { return 3; } @Override public Object[] toArray() { return new Object[] { v0, v1, v2 }; } @Override public void forEach(IProcedure proc) { proc.exec(v0); proc.exec(v1); proc.exec(v2); } } private static class LLN implements LL { Object[] array; int size; public LLN(Object v0, Object v1, Object v2, Object v3) { array = new Object[] { v0, v1, v2, v3, null, null }; size = 4; } @Override public Object add(Object value) { if(size==array.length) array = Arrays.copyOf(array, (size*3)/2+1); array[size++] = value; return this; } @Override public Object remove(Object value) { for(int i=0;i