/* * Copyright (c) 2012 Google Inc. * * 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 */ package com.google.eclipse.protobuf.cdt.util; import static java.util.Collections.emptyList; import static java.util.Collections.unmodifiableList; import java.util.Arrays; import java.util.List; import com.google.common.annotations.VisibleForTesting; import com.google.common.collect.AbstractIterator; /** * {@code Iterator} for {@code List}s. This implementation keeps track of the index of the current element to be able * to: * <ul> * <li>Retrieve the elements that have not been visited yet</li> * <li>Check whether we are visiting the last element of the {@code List}</li> * @param <T> the generic type of the iterator. * * @author alruiz@google.com (Alex Ruiz) */ public class ExtendedListIterator<T> extends AbstractIterator<T> implements ExtendedIterator<T> { private static final ExtendedIterator<Object> EMPTY = newIterator(emptyList()); private static final int NOT_STARTED = -1; private final List<T> list; private int index = NOT_STARTED; /** * Creates a new <code>{@link ExtendedListIterator}</code>. * @param elements the elements of the {@code Iterator} to create. * @return the created {@code ListIterator}. */ @SafeVarargs public static <T> ExtendedIterator<T> newIterator(T... elements) { return new ExtendedListIterator<T>(Arrays.asList(elements)); } /** * Creates a new <code>{@link ExtendedListIterator}</code>. * @param list the {@code List} to iterate. * @return the created {@code ListIterator}. * @throws NullPointerException if the given {@code List} is {@code null}. */ public static <T> ExtendedIterator<T> newIterator(List<T> list) { if (list == null) { throw new NullPointerException("The list to iterate should not be null"); } return new ExtendedListIterator<T>(list); } @VisibleForTesting ExtendedListIterator(List<T> list) { this.list = list; } /** {@inheritDoc} */ @SuppressWarnings("unchecked") @Override public ExtendedIterator<T> notRetrievedYet() { int listSize = list.size(); if (listSize == 0) { return (ExtendedIterator<T>) EMPTY; } List<T> remaining = list.subList(index + 1, listSize); return newIterator(remaining); } /** {@inheritDoc} */ @Override public boolean wasLastListElementRetrieved() { if (index == NOT_STARTED) { return false; } int listSize = list.size(); return listSize > 0 && index == listSize - 1; } /** {@inheritDoc} */ @Override public ExtendedIterator<T> copy() { return new ExtendedListIterator<T>(list); } @Override protected T computeNext() { int listSize = list.size(); if (index + 1 < listSize && listSize > 0) { return list.get(++index); } return endOfData(); } @Override public String toString() { return list.toString(); } @VisibleForTesting List<T> contents() { return unmodifiableList(list); } }