001package components.list;
002
003import java.util.Iterator;
004import java.util.LinkedList;
005import java.util.NoSuchElementException;
006
007/**
008 * {@code List} represented as a {@link java.util.List java.util.List} with
009 * implementations of primary methods.
010 *
011 * @param <T>
012 *            type of {@code List} entries
013 * @correspondence <pre>
014 * this.left = [$this.leftList, based on java.util.List's "proper sequence"]  and
015 * this.right = [$this.rightList, based on java.util.List's "proper sequence"]
016 * </pre>
017 */
018public class List1L<T> extends ListSecondary<T> {
019
020    /*
021     * Private members --------------------------------------------------------
022     */
023
024    /**
025     * Representation of {@code this.left}.
026     */
027    private java.util.List<T> leftList;
028
029    /**
030     * Representation of {@code this.right}.
031     */
032    private java.util.List<T> rightList;
033
034    /**
035     * Creator of initial representation.
036     */
037    private void createNewRep() {
038        this.leftList = new LinkedList<T>();
039        this.rightList = new LinkedList<T>();
040    }
041
042    /*
043     * Constructors -----------------------------------------------------------
044     */
045
046    /**
047     * No-argument constructor.
048     */
049    public List1L() {
050        this.createNewRep();
051    }
052
053    /*
054     * Standard methods -------------------------------------------------------
055     */
056
057    @SuppressWarnings("unchecked")
058    @Override
059    public final List1L<T> newInstance() {
060        try {
061            return this.getClass().getConstructor().newInstance();
062        } catch (ReflectiveOperationException e) {
063            throw new AssertionError(
064                    "Cannot construct object of type " + this.getClass());
065        }
066    }
067
068    @Override
069    public final void clear() {
070        this.createNewRep();
071    }
072
073    @Override
074    public final void transferFrom(List<T> source) {
075        assert source != null : "Violation of: source is not null";
076        assert source != this : "Violation of: source is not this";
077        assert source instanceof List1L<?>
078                : "Violation of: source is of dynamic type List1L<?>";
079        /*
080         * This cast cannot fail since the assert above would have stopped
081         * execution in that case: source must be of dynamic type List1L<?>, and
082         * the ? must be T or the call would not have compiled.
083         */
084        List1L<T> localSource = (List1L<T>) source;
085        this.leftList = localSource.leftList;
086        this.rightList = localSource.rightList;
087        localSource.createNewRep();
088    }
089
090    /*
091     * Kernel methods ---------------------------------------------------------
092     */
093
094    @Override
095    public final void addRightFront(T x) {
096        assert x != null : "Violation of: x is not null";
097        this.rightList.add(0, x);
098    }
099
100    @Override
101    public final T removeRightFront() {
102        assert this.rightLength() > 0 : "Violation of: this.right /= <>";
103        return this.rightList.remove(0);
104    }
105
106    @Override
107    public final void advance() {
108        assert this.rightLength() > 0 : "Violation of: this.right /= <>";
109        T x = this.rightList.remove(0);
110        this.leftList.add(x);
111    }
112
113    @Override
114    public final void moveToStart() {
115        this.rightList.addAll(0, this.leftList);
116        this.leftList.clear();
117    }
118
119    @Override
120    public final int leftLength() {
121        return this.leftList.size();
122    }
123
124    @Override
125    public final int rightLength() {
126        return this.rightList.size();
127    }
128
129    @Override
130    public final Iterator<T> iterator() {
131        return new List1LIterator();
132    }
133
134    /**
135     * Implementation of {@code Iterator} interface for {@code List1L}.
136     */
137    private final class List1LIterator implements Iterator<T> {
138
139        /**
140         * Current position of iterator.
141         */
142        private int notSeenCount;
143
144        /**
145         * Representation left iterator.
146         */
147        private Iterator<T> iterator;
148
149        /**
150         * No-argument constructor.
151         */
152        private List1LIterator() {
153            this.iterator = List1L.this.leftList.iterator();
154            this.notSeenCount = List1L.this.leftList.size()
155                    + List1L.this.rightList.size();
156        }
157
158        @Override
159        public boolean hasNext() {
160            return this.notSeenCount > 0;
161        }
162
163        @Override
164        public T next() {
165            assert this.hasNext() : "Violation of: ~this.unseen /= <>";
166            if (!this.hasNext()) {
167                /*
168                 * Exception is supposed to be thrown in this case, but with
169                 * assertion-checking enabled it cannot happen because of assert
170                 * above.
171                 */
172                throw new NoSuchElementException();
173            }
174            if (!this.iterator.hasNext()) {
175                this.iterator = List1L.this.rightList.iterator();
176            }
177            this.notSeenCount--;
178            return this.iterator.next();
179        }
180
181        @Override
182        public void remove() {
183            throw new UnsupportedOperationException("remove operation not supported");
184        }
185
186    }
187
188    /*
189     * Other methods (overridden for performance reasons) ---------------------
190     */
191
192    @Override
193    public final T rightFront() {
194        assert this.rightLength() > 0 : "Violation of: this.right /= <>";
195        return this.rightList.get(0);
196    }
197
198    @Override
199    public final T replaceRightFront(T x) {
200        assert this.rightLength() > 0 : "Violation of: this.right /= <>";
201        return this.rightList.set(0, x);
202    }
203
204    @Override
205    public final void moveToFinish() {
206        this.leftList.addAll(this.rightList);
207        this.rightList.clear();
208    }
209
210    @Override
211    public final void retreat() {
212        assert this.leftLength() > 0 : "Violation of: this.left /= <>";
213        this.rightList.add(0, this.leftList.remove(this.leftList.size() - 1));
214    }
215
216}