1/*
2 * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation.  Oracle designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Oracle in the LICENSE file that accompanied this code.
10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 * or visit www.oracle.com if you need additional information or have any
23 * questions.
24 */
25package java.util;
26
27import java.util.function.Consumer;
28import java.util.function.DoubleConsumer;
29import java.util.function.IntConsumer;
30import java.util.function.LongConsumer;
31
32/**
33 * A base type for primitive specializations of {@code Iterator}.  Specialized
34 * subtypes are provided for {@link OfInt int}, {@link OfLong long}, and
35 * {@link OfDouble double} values.
36 *
37 * <p>The specialized subtype default implementations of {@link Iterator#next}
38 * and {@link Iterator#forEachRemaining(java.util.function.Consumer)} box
39 * primitive values to instances of their corresponding wrapper class.  Such
40 * boxing may offset any advantages gained when using the primitive
41 * specializations.  To avoid boxing, the corresponding primitive-based methods
42 * should be used.  For example, {@link PrimitiveIterator.OfInt#nextInt()} and
43 * {@link PrimitiveIterator.OfInt#forEachRemaining(java.util.function.IntConsumer)}
44 * should be used in preference to {@link PrimitiveIterator.OfInt#next()} and
45 * {@link PrimitiveIterator.OfInt#forEachRemaining(java.util.function.Consumer)}.
46 *
47 * <p>Iteration of primitive values using boxing-based methods
48 * {@link Iterator#next next()} and
49 * {@link Iterator#forEachRemaining(java.util.function.Consumer) forEachRemaining()},
50 * does not affect the order in which the values, transformed to boxed values,
51 * are encountered.
52 *
53 * @implNote
54 * If the boolean system property {@code org.openjdk.java.util.stream.tripwire}
55 * is set to {@code true} then diagnostic warnings are reported if boxing of
56 * primitive values occur when operating on primitive subtype specializations.
57 *
58 * @param <T> the type of elements returned by this PrimitiveIterator.  The
59 *        type must be a wrapper type for a primitive type, such as
60 *        {@code Integer} for the primitive {@code int} type.
61 * @param  the type of primitive consumer.  The type must be a
62 *        primitive specialization of {@link java.util.function.Consumer} for
63 *        {@code T}, such as {@link java.util.function.IntConsumer} for
64 *        {@code Integer}.
65 *
66 * @since 1.8
67 */
68public interface PrimitiveIterator<T, T_CONS> extends Iterator<T> {
69
70    /**
71     * Performs the given action for each remaining element, in the order
72     * elements occur when iterating, until all elements have been processed
73     * or the action throws an exception.  Errors or runtime exceptions
74     * thrown by the action are relayed to the caller.
75     *
76     * @param action The action to be performed for each element
77     * @throws NullPointerException if the specified action is null
78     */
79    @SuppressWarnings("overloads")
80    void forEachRemaining(T_CONS action);
81
82    /**
83     * An Iterator specialized for {@code int} values.
84     * @since 1.8
85     */
86    public static interface OfInt extends PrimitiveIterator<Integer, IntConsumer> {
87
88        /**
89         * Returns the next {@code int} element in the iteration.
90         *
91         * @return the next {@code int} element in the iteration
92         * @throws NoSuchElementException if the iteration has no more elements
93         */
94        int nextInt();
95
96        /**
97         * Performs the given action for each remaining element until all elements
98         * have been processed or the action throws an exception.  Actions are
99         * performed in the order of iteration, if that order is specified.
100         * Exceptions thrown by the action are relayed to the caller.
101         *
102         * @implSpec
103         * <p>The default implementation behaves as if:
104         * <pre>{@code
105         *     while (hasNext())
106         *         action.accept(nextInt());
107         * }</pre>
108         *
109         * @param action The action to be performed for each element
110         * @throws NullPointerException if the specified action is null
111         */
112        default void forEachRemaining(IntConsumer action) {
113            Objects.requireNonNull(action);
114            while (hasNext())
115                action.accept(nextInt());
116        }
117
118        /**
119         * {@inheritDoc}
120         * @implSpec
121         * The default implementation boxes the result of calling
122         * {@link #nextInt()}, and returns that boxed result.
123         */
124        @Override
125        default Integer next() {
126            if (Tripwire.ENABLED)
127                Tripwire.trip(getClass(), "{0} calling PrimitiveIterator.OfInt.nextInt()");
128            return nextInt();
129        }
130
131        /**
132         * {@inheritDoc}
133         * @implSpec
134         * If the action is an instance of {@code IntConsumer} then it is cast
135         * to {@code IntConsumer} and passed to {@link #forEachRemaining};
136         * otherwise the action is adapted to an instance of
137         * {@code IntConsumer}, by boxing the argument of {@code IntConsumer},
138         * and then passed to {@link #forEachRemaining}.
139         */
140        @Override
141        default void forEachRemaining(Consumer<? super Integer> action) {
142            if (action instanceof IntConsumer) {
143                forEachRemaining((IntConsumer) action);
144            }
145            else {
146                // The method reference action::accept is never null
147                Objects.requireNonNull(action);
148                if (Tripwire.ENABLED)
149                    Tripwire.trip(getClass(), "{0} calling PrimitiveIterator.OfInt.forEachRemainingInt(action::accept)");
150                forEachRemaining((IntConsumer) action::accept);
151            }
152        }
153
154    }
155
156    /**
157     * An Iterator specialized for {@code long} values.
158     * @since 1.8
159     */
160    public static interface OfLong extends PrimitiveIterator<Long, LongConsumer> {
161
162        /**
163         * Returns the next {@code long} element in the iteration.
164         *
165         * @return the next {@code long} element in the iteration
166         * @throws NoSuchElementException if the iteration has no more elements
167         */
168        long nextLong();
169
170        /**
171         * Performs the given action for each remaining element until all elements
172         * have been processed or the action throws an exception.  Actions are
173         * performed in the order of iteration, if that order is specified.
174         * Exceptions thrown by the action are relayed to the caller.
175         *
176         * @implSpec
177         * <p>The default implementation behaves as if:
178         * <pre>{@code
179         *     while (hasNext())
180         *         action.accept(nextLong());
181         * }</pre>
182         *
183         * @param action The action to be performed for each element
184         * @throws NullPointerException if the specified action is null
185         */
186        default void forEachRemaining(LongConsumer action) {
187            Objects.requireNonNull(action);
188            while (hasNext())
189                action.accept(nextLong());
190        }
191
192        /**
193         * {@inheritDoc}
194         * @implSpec
195         * The default implementation boxes the result of calling
196         * {@link #nextLong()}, and returns that boxed result.
197         */
198        @Override
199        default Long next() {
200            if (Tripwire.ENABLED)
201                Tripwire.trip(getClass(), "{0} calling PrimitiveIterator.OfLong.nextLong()");
202            return nextLong();
203        }
204
205        /**
206         * {@inheritDoc}
207         * @implSpec
208         * If the action is an instance of {@code LongConsumer} then it is cast
209         * to {@code LongConsumer} and passed to {@link #forEachRemaining};
210         * otherwise the action is adapted to an instance of
211         * {@code LongConsumer}, by boxing the argument of {@code LongConsumer},
212         * and then passed to {@link #forEachRemaining}.
213         */
214        @Override
215        default void forEachRemaining(Consumer<? super Long> action) {
216            if (action instanceof LongConsumer) {
217                forEachRemaining((LongConsumer) action);
218            }
219            else {
220                // The method reference action::accept is never null
221                Objects.requireNonNull(action);
222                if (Tripwire.ENABLED)
223                    Tripwire.trip(getClass(), "{0} calling PrimitiveIterator.OfLong.forEachRemainingLong(action::accept)");
224                forEachRemaining((LongConsumer) action::accept);
225            }
226        }
227    }
228
229    /**
230     * An Iterator specialized for {@code double} values.
231     * @since 1.8
232     */
233    public static interface OfDouble extends PrimitiveIterator<Double, DoubleConsumer> {
234
235        /**
236         * Returns the next {@code double} element in the iteration.
237         *
238         * @return the next {@code double} element in the iteration
239         * @throws NoSuchElementException if the iteration has no more elements
240         */
241        double nextDouble();
242
243        /**
244         * Performs the given action for each remaining element until all elements
245         * have been processed or the action throws an exception.  Actions are
246         * performed in the order of iteration, if that order is specified.
247         * Exceptions thrown by the action are relayed to the caller.
248         *
249         * @implSpec
250         * <p>The default implementation behaves as if:
251         * <pre>{@code
252         *     while (hasNext())
253         *         action.accept(nextDouble());
254         * }</pre>
255         *
256         * @param action The action to be performed for each element
257         * @throws NullPointerException if the specified action is null
258         */
259        default void forEachRemaining(DoubleConsumer action) {
260            Objects.requireNonNull(action);
261            while (hasNext())
262                action.accept(nextDouble());
263        }
264
265        /**
266         * {@inheritDoc}
267         * @implSpec
268         * The default implementation boxes the result of calling
269         * {@link #nextDouble()}, and returns that boxed result.
270         */
271        @Override
272        default Double next() {
273            if (Tripwire.ENABLED)
274                Tripwire.trip(getClass(), "{0} calling PrimitiveIterator.OfDouble.nextLong()");
275            return nextDouble();
276        }
277
278        /**
279         * {@inheritDoc}
280         * @implSpec
281         * If the action is an instance of {@code DoubleConsumer} then it is
282         * cast to {@code DoubleConsumer} and passed to
283         * {@link #forEachRemaining}; otherwise the action is adapted to
284         * an instance of {@code DoubleConsumer}, by boxing the argument of
285         * {@code DoubleConsumer}, and then passed to
286         * {@link #forEachRemaining}.
287         */
288        @Override
289        default void forEachRemaining(Consumer<? super Double> action) {
290            if (action instanceof DoubleConsumer) {
291                forEachRemaining((DoubleConsumer) action);
292            }
293            else {
294                // The method reference action::accept is never null
295                Objects.requireNonNull(action);
296                if (Tripwire.ENABLED)
297                    Tripwire.trip(getClass(), "{0} calling PrimitiveIterator.OfDouble.forEachRemainingDouble(action::accept)");
298                forEachRemaining((DoubleConsumer) action::accept);
299            }
300        }
301    }
302}
303