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