1/*
2 * Copyright 2012, Google Inc.
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are
7 * met:
8 *
9 *     * Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 *     * Redistributions in binary form must reproduce the above
12 * copyright notice, this list of conditions and the following disclaimer
13 * in the documentation and/or other materials provided with the
14 * distribution.
15 *     * Neither the name of Google Inc. nor the names of its
16 * contributors may be used to endorse or promote products derived from
17 * this software without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
21 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
22 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
23 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
24 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
25 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
26 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
27 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
29 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30 */
31
32package org.jf.util;
33
34import javax.annotation.Nonnull;
35import javax.annotation.Nullable;
36import java.util.AbstractSequentialList;
37import java.util.Iterator;
38import java.util.ListIterator;
39import java.util.NoSuchElementException;
40
41public abstract class AbstractForwardSequentialList<T> extends AbstractSequentialList<T> {
42
43    @Nonnull private Iterator<T> iterator(int index) {
44        if (index < 0) {
45            throw new NoSuchElementException();
46        }
47
48        Iterator<T> it = iterator();
49        for (int i=0; i<index; i++) {
50            it.next();
51        }
52        return it;
53    }
54
55    @Override @Nonnull public abstract Iterator<T> iterator();
56
57    @Override @Nonnull public ListIterator<T> listIterator(final int initialIndex) {
58
59        final Iterator<T> initialIterator;
60        try {
61            initialIterator = iterator(initialIndex);
62        } catch (NoSuchElementException ex) {
63            throw new IndexOutOfBoundsException();
64        }
65
66        return new AbstractListIterator<T>() {
67            private int index = initialIndex - 1;
68            @Nullable private Iterator<T> forwardIterator = initialIterator;
69
70            @Nonnull
71            private Iterator<T> getForwardIterator() {
72                if (forwardIterator == null) {
73                    try {
74                        forwardIterator = iterator(index+1);
75                    } catch (IndexOutOfBoundsException ex) {
76                        throw new NoSuchElementException();
77                    }
78                }
79                return forwardIterator;
80            }
81
82            @Override public boolean hasNext() {
83                return getForwardIterator().hasNext();
84            }
85
86            @Override public boolean hasPrevious() {
87                return index >= 0;
88            }
89
90            @Override public T next() {
91                T ret = getForwardIterator().next();
92                index++;
93                return ret;
94            }
95
96            @Override public int nextIndex() {
97                return index+1;
98            }
99
100            @Override public T previous() {
101                forwardIterator = null;
102                try {
103                    return iterator(index--).next();
104                } catch (IndexOutOfBoundsException ex) {
105                    throw new NoSuchElementException();
106                }
107            }
108
109            @Override public int previousIndex() {
110                return index;
111            }
112        };
113    }
114
115    @Override @Nonnull public ListIterator<T> listIterator() {
116        return listIterator(0);
117    }
118}
119