/* * Copyright 2003-2011 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package jetbrains.mps.util; import org.jetbrains.annotations.NotNull; import java.util.Iterator; import java.util.ListIterator; /** * User: shatalin * Date: 9/12/13 */ public abstract class AbstractSequentialList<T> extends java.util.AbstractSequentialList<T> { private final T myFirst; private int mySize = -1; public AbstractSequentialList(@NotNull T first) { myFirst = first; } @Override public ListIterator<T> listIterator(int index) { if (index < 0) { throw new IndexOutOfBoundsException(); } ListIterator<T> iterator = createIterator(myFirst); for (int i = 0; i < index; i++) { if (iterator.hasNext()) { iterator.next(); } else { throw new IndexOutOfBoundsException(); } } return iterator; } @Override public int size() { if (mySize == -1) { mySize = 0; for (Iterator<T> iterator = iterator(); iterator.hasNext(); mySize++) { iterator.next(); } } return mySize; } protected abstract AbstractSequentialIterator<T> createIterator(T first); public static abstract class AbstractSequentialIterator<T> implements ListIterator<T> { private T myCurrent; private T myPrev; private int myIndex; public AbstractSequentialIterator(T node) { assert node != null; myCurrent = node; myPrev = null; myIndex = 0; } protected abstract T getNext(T node); protected abstract T getPrev(T node); protected T getCurrent() { return myCurrent; } protected void setCurrent(T current) { myCurrent = current; } protected T getPrev() { return myPrev; } protected void setPrev(T prev) { myPrev = prev; } @Override public boolean hasNext() { return getCurrent() != null; } @Override public T next() { T result = getCurrent(); if (result == null) { //TODO: throw new NoSuchElementException(); return null; } setPrev(result); myIndex++; setCurrent(getNext(result)); return result; } @Override public boolean hasPrevious() { return getPrev() != null; } @Override public T previous() { T result = getPrev(); if (result == null) { //TODO: throw new NoSuchElementException(); return null; } setCurrent(result); myIndex--; setPrev(myIndex == 0 ? null : getPrev(result)); return result; } @Override public int nextIndex() { return myIndex; } @Override public int previousIndex() { return myIndex - 1; } @Override public void remove() { throw new UnsupportedOperationException(); } @Override public void set(T t) { throw new UnsupportedOperationException(); } @Override public void add(T t) { throw new UnsupportedOperationException(); } } }