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