1ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin/*
2ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
3ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin *
5ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin * This code is free software; you can redistribute it and/or modify it
6ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin * under the terms of the GNU General Public License version 2 only, as
7ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin * published by the Free Software Foundation.  Oracle designates this
8ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin * particular file as subject to the "Classpath" exception as provided
9ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin * by Oracle in the LICENSE file that accompanied this code.
10ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin *
11ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin * This code is distributed in the hope that it will be useful, but WITHOUT
12ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
14ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin * version 2 for more details (a copy is included in the LICENSE file that
15ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin * accompanied this code).
16ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin *
17ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin * You should have received a copy of the GNU General Public License version
18ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin * 2 along with this work; if not, write to the Free Software Foundation,
19ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin *
21ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin * or visit www.oracle.com if you need additional information or have any
23ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin * questions.
24ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin */
25ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkinpackage java.util.stream;
26ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin
27ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkinimport java.util.Spliterator;
28ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkinimport java.util.function.Consumer;
29ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkinimport java.util.function.DoubleConsumer;
30ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkinimport java.util.function.IntConsumer;
31ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkinimport java.util.function.IntFunction;
32ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkinimport java.util.function.LongConsumer;
33ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin
34ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin/**
35ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin * An immutable container for describing an ordered sequence of elements of some
36ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin * type {@code T}.
37ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin *
38ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin * <p>A {@code Node} contains a fixed number of elements, which can be accessed
39ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin * via the {@link #count}, {@link #spliterator}, {@link #forEach},
40ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin * {@link #asArray}, or {@link #copyInto} methods.  A {@code Node} may have zero
41ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin * or more child {@code Node}s; if it has no children (accessed via
42ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin * {@link #getChildCount} and {@link #getChild(int)}, it is considered <em>flat
43ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin * </em> or a <em>leaf</em>; if it has children, it is considered an
44ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin * <em>internal</em> node.  The size of an internal node is the sum of sizes of
45ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin * its children.
46ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin *
47ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin * @apiNote
48ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin * <p>A {@code Node} typically does not store the elements directly, but instead
49ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin * mediates access to one or more existing (effectively immutable) data
50ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin * structures such as a {@code Collection}, array, or a set of other
51ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin * {@code Node}s.  Commonly {@code Node}s are formed into a tree whose shape
52ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin * corresponds to the computation tree that produced the elements that are
53ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin * contained in the leaf nodes.  The use of {@code Node} within the stream
54ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin * framework is largely to avoid copying data unnecessarily during parallel
55ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin * operations.
56ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin *
57ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin * @param <T> the type of elements.
58ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin * @since 1.8
59289e51c2258b001f2aa6d6e67b21be7bb65d5102Igor Murashkin * @hide Visible for CTS testing only (OpenJDK8 tests).
60ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin */
61289e51c2258b001f2aa6d6e67b21be7bb65d5102Igor Murashkinpublic interface Node<T> {
62ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin
63ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin    /**
64ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin     * Returns a {@link Spliterator} describing the elements contained in this
65ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin     * {@code Node}.
66ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin     *
67ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin     * @return a {@code Spliterator} describing the elements contained in this
68ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin     *         {@code Node}
69ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin     */
70ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin    Spliterator<T> spliterator();
71ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin
72ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin    /**
73ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin     * Traverses the elements of this node, and invoke the provided
74ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin     * {@code Consumer} with each element.  Elements are provided in encounter
75ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin     * order if the source for the {@code Node} has a defined encounter order.
76ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin     *
77ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin     * @param consumer a {@code Consumer} that is to be invoked with each
78ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin     *        element in this {@code Node}
79ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin     */
80ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin    void forEach(Consumer<? super T> consumer);
81ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin
82ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin    /**
83ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin     * Returns the number of child nodes of this node.
84ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin     *
85ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin     * @implSpec The default implementation returns zero.
86ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin     *
87ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin     * @return the number of child nodes
88ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin     */
89ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin    default int getChildCount() {
90ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin        return 0;
91ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin    }
92ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin
93ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin    /**
94ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin     * Retrieves the child {@code Node} at a given index.
95ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin     *
96ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin     * @implSpec The default implementation always throws
97ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin     * {@code IndexOutOfBoundsException}.
98ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin     *
99ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin     * @param i the index to the child node
100ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin     * @return the child node
101ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin     * @throws IndexOutOfBoundsException if the index is less than 0 or greater
102ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin     *         than or equal to the number of child nodes
103ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin     */
104ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin    default Node<T> getChild(int i) {
105ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin        throw new IndexOutOfBoundsException();
106ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin    }
107ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin
108ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin    /**
109ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin     * Return a node describing a subsequence of the elements of this node,
110ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin     * starting at the given inclusive start offset and ending at the given
111ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin     * exclusive end offset.
112ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin     *
113ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin     * @param from The (inclusive) starting offset of elements to include, must
114ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin     *             be in range 0..count().
115ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin     * @param to The (exclusive) end offset of elements to include, must be
116ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin     *           in range 0..count().
117ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin     * @param generator A function to be used to create a new array, if needed,
118ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin     *                  for reference nodes.
119ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin     * @return the truncated node
120ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin     */
121ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin    default Node<T> truncate(long from, long to, IntFunction<T[]> generator) {
122ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin        if (from == 0 && to == count())
123ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin            return this;
124ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin        Spliterator<T> spliterator = spliterator();
125ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin        long size = to - from;
126ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin        Node.Builder<T> nodeBuilder = Nodes.builder(size, generator);
127ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin        nodeBuilder.begin(size);
128ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin        for (int i = 0; i < from && spliterator.tryAdvance(e -> { }); i++) { }
129ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin        for (int i = 0; (i < size) && spliterator.tryAdvance(nodeBuilder); i++) { }
130ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin        nodeBuilder.end();
131ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin        return nodeBuilder.build();
132ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin    }
133ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin
134ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin    /**
135ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin     * Provides an array view of the contents of this node.
136ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin     *
137ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin     * <p>Depending on the underlying implementation, this may return a
138ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin     * reference to an internal array rather than a copy.  Since the returned
139ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin     * array may be shared, the returned array should not be modified.  The
140ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin     * {@code generator} function may be consulted to create the array if a new
141ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin     * array needs to be created.
142ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin     *
143ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin     * @param generator a factory function which takes an integer parameter and
144ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin     *        returns a new, empty array of that size and of the appropriate
145ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin     *        array type
146ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin     * @return an array containing the contents of this {@code Node}
147ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin     */
148ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin    T[] asArray(IntFunction<T[]> generator);
149ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin
150ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin    /**
151ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin     * Copies the content of this {@code Node} into an array, starting at a
152ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin     * given offset into the array.  It is the caller's responsibility to ensure
153ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin     * there is sufficient room in the array, otherwise unspecified behaviour
154ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin     * will occur if the array length is less than the number of elements
155ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin     * contained in this node.
156ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin     *
157ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin     * @param array the array into which to copy the contents of this
158ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin     *       {@code Node}
159ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin     * @param offset the starting offset within the array
160ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin     * @throws IndexOutOfBoundsException if copying would cause access of data
161ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin     *         outside array bounds
162ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin     * @throws NullPointerException if {@code array} is {@code null}
163ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin     */
164ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin    void copyInto(T[] array, int offset);
165ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin
166ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin    /**
167ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin     * Gets the {@code StreamShape} associated with this {@code Node}.
168ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin     *
169ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin     * @implSpec The default in {@code Node} returns
170ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin     * {@code StreamShape.REFERENCE}
171ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin     *
172ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin     * @return the stream shape associated with this node
173ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin     */
174ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin    default StreamShape getShape() {
175ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin        return StreamShape.REFERENCE;
176ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin    }
177ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin
178ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin    /**
179ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin     * Returns the number of elements contained in this node.
180ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin     *
181ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin     * @return the number of elements contained in this node
182ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin     */
183ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin    long count();
184ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin
185ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin    /**
186ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin     * A mutable builder for a {@code Node} that implements {@link Sink}, which
187ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin     * builds a flat node containing the elements that have been pushed to it.
188ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin     */
189ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin    interface Builder<T> extends Sink<T> {
190ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin
191ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin        /**
192ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin         * Builds the node.  Should be called after all elements have been
193ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin         * pushed and signalled with an invocation of {@link Sink#end()}.
194ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin         *
195ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin         * @return the resulting {@code Node}
196ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin         */
197ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin        Node<T> build();
198ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin
199ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin        /**
200ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin         * Specialized @{code Node.Builder} for int elements
201ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin         */
202ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin        interface OfInt extends Node.Builder<Integer>, Sink.OfInt {
203ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin            @Override
204ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin            Node.OfInt build();
205ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin        }
206ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin
207ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin        /**
208ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin         * Specialized @{code Node.Builder} for long elements
209ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin         */
210ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin        interface OfLong extends Node.Builder<Long>, Sink.OfLong {
211ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin            @Override
212ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin            Node.OfLong build();
213ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin        }
214ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin
215ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin        /**
216ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin         * Specialized @{code Node.Builder} for double elements
217ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin         */
218ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin        interface OfDouble extends Node.Builder<Double>, Sink.OfDouble {
219ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin            @Override
220ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin            Node.OfDouble build();
221ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin        }
222ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin    }
223ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin
224ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin    public interface OfPrimitive<T, T_CONS, T_ARR,
225ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin                                 T_SPLITR extends Spliterator.OfPrimitive<T, T_CONS, T_SPLITR>,
226ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin                                 T_NODE extends OfPrimitive<T, T_CONS, T_ARR, T_SPLITR, T_NODE>>
227ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin            extends Node<T> {
228ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin
229ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin        /**
230ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin         * {@inheritDoc}
231ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin         *
232ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin         * @return a {@link Spliterator.OfPrimitive} describing the elements of
233ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin         *         this node
234ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin         */
235ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin        @Override
236ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin        T_SPLITR spliterator();
237ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin
238ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin        /**
239ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin         * Traverses the elements of this node, and invoke the provided
240ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin         * {@code action} with each element.
241ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin         *
242ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin         * @param action a consumer that is to be invoked with each
243ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin         *        element in this {@code Node.OfPrimitive}
244ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin         */
245ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin        @SuppressWarnings("overloads")
246ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin        void forEach(T_CONS action);
247ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin
248ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin        @Override
249ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin        default T_NODE getChild(int i) {
250ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin            throw new IndexOutOfBoundsException();
251ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin        }
252ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin
253ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin        T_NODE truncate(long from, long to, IntFunction<T[]> generator);
254ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin
255ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin        /**
256ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin         * {@inheritDoc}
257ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin         *
258ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin         * @implSpec the default implementation invokes the generator to create
259ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin         * an instance of a boxed primitive array with a length of
260ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin         * {@link #count()} and then invokes {@link #copyInto(T[], int)} with
261ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin         * that array at an offset of 0.
262ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin         */
263ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin        @Override
264ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin        default T[] asArray(IntFunction<T[]> generator) {
265ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin            if (java.util.stream.Tripwire.ENABLED)
266ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin                java.util.stream.Tripwire.trip(getClass(), "{0} calling Node.OfPrimitive.asArray");
267ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin
268ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin            long size = count();
269ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin            if (size >= Nodes.MAX_ARRAY_SIZE)
270ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin                throw new IllegalArgumentException(Nodes.BAD_SIZE);
271ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin            T[] boxed = generator.apply((int) count());
272ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin            copyInto(boxed, 0);
273ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin            return boxed;
274ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin        }
275ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin
276ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin        /**
277ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin         * Views this node as a primitive array.
278ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin         *
279ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin         * <p>Depending on the underlying implementation this may return a
280ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin         * reference to an internal array rather than a copy.  It is the callers
281ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin         * responsibility to decide if either this node or the array is utilized
282ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin         * as the primary reference for the data.</p>
283ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin         *
284ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin         * @return an array containing the contents of this {@code Node}
285ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin         */
286ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin        T_ARR asPrimitiveArray();
287ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin
288ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin        /**
289ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin         * Creates a new primitive array.
290ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin         *
291ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin         * @param count the length of the primitive array.
292ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin         * @return the new primitive array.
293ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin         */
294ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin        T_ARR newArray(int count);
295ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin
296ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin        /**
297ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin         * Copies the content of this {@code Node} into a primitive array,
298ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin         * starting at a given offset into the array.  It is the caller's
299ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin         * responsibility to ensure there is sufficient room in the array.
300ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin         *
301ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin         * @param array the array into which to copy the contents of this
302ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin         *              {@code Node}
303ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin         * @param offset the starting offset within the array
304ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin         * @throws IndexOutOfBoundsException if copying would cause access of
305ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin         *         data outside array bounds
306ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin         * @throws NullPointerException if {@code array} is {@code null}
307ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin         */
308ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin        void copyInto(T_ARR array, int offset);
309ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin    }
310ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin
311ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin    /**
312ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin     * Specialized {@code Node} for int elements
313ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin     */
314ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin    interface OfInt extends OfPrimitive<Integer, IntConsumer, int[], Spliterator.OfInt, OfInt> {
315ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin
316ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin        /**
317ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin         * {@inheritDoc}
318ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin         *
319ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin         * @param consumer a {@code Consumer} that is to be invoked with each
320ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin         *        element in this {@code Node}.  If this is an
321ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin         *        {@code IntConsumer}, it is cast to {@code IntConsumer} so the
322ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin         *        elements may be processed without boxing.
323ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin         */
324ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin        @Override
325ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin        default void forEach(Consumer<? super Integer> consumer) {
326ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin            if (consumer instanceof IntConsumer) {
327ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin                forEach((IntConsumer) consumer);
328ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin            }
329ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin            else {
330ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin                if (Tripwire.ENABLED)
331ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin                    Tripwire.trip(getClass(), "{0} calling Node.OfInt.forEachRemaining(Consumer)");
332ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin                spliterator().forEachRemaining(consumer);
333ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin            }
334ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin        }
335ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin
336ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin        /**
337ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin         * {@inheritDoc}
338ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin         *
339ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin         * @implSpec the default implementation invokes {@link #asPrimitiveArray()} to
340ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin         * obtain an int[] array then and copies the elements from that int[]
341ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin         * array into the boxed Integer[] array.  This is not efficient and it
342ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin         * is recommended to invoke {@link #copyInto(Object, int)}.
343ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin         */
344ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin        @Override
345ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin        default void copyInto(Integer[] boxed, int offset) {
346ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin            if (Tripwire.ENABLED)
347ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin                Tripwire.trip(getClass(), "{0} calling Node.OfInt.copyInto(Integer[], int)");
348ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin
349ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin            int[] array = asPrimitiveArray();
350ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin            for (int i = 0; i < array.length; i++) {
351ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin                boxed[offset + i] = array[i];
352ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin            }
353ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin        }
354ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin
355ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin        @Override
356ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin        default Node.OfInt truncate(long from, long to, IntFunction<Integer[]> generator) {
357ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin            if (from == 0 && to == count())
358ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin                return this;
359ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin            long size = to - from;
360ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin            Spliterator.OfInt spliterator = spliterator();
361ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin            Node.Builder.OfInt nodeBuilder = Nodes.intBuilder(size);
362ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin            nodeBuilder.begin(size);
363ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin            for (int i = 0; i < from && spliterator.tryAdvance((IntConsumer) e -> { }); i++) { }
364ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin            for (int i = 0; (i < size) && spliterator.tryAdvance((IntConsumer) nodeBuilder); i++) { }
365ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin            nodeBuilder.end();
366ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin            return nodeBuilder.build();
367ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin        }
368ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin
369ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin        @Override
370ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin        default int[] newArray(int count) {
371ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin            return new int[count];
372ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin        }
373ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin
374ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin        /**
375ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin         * {@inheritDoc}
376ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin         * @implSpec The default in {@code Node.OfInt} returns
377ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin         * {@code StreamShape.INT_VALUE}
378ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin         */
379ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin        default StreamShape getShape() {
380ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin            return StreamShape.INT_VALUE;
381ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin        }
382ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin    }
383ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin
384ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin    /**
385ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin     * Specialized {@code Node} for long elements
386ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin     */
387ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin    interface OfLong extends OfPrimitive<Long, LongConsumer, long[], Spliterator.OfLong, OfLong> {
388ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin
389ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin        /**
390ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin         * {@inheritDoc}
391ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin         *
392ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin         * @param consumer A {@code Consumer} that is to be invoked with each
393ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin         *        element in this {@code Node}.  If this is an
394ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin         *        {@code LongConsumer}, it is cast to {@code LongConsumer} so
395ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin         *        the elements may be processed without boxing.
396ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin         */
397ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin        @Override
398ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin        default void forEach(Consumer<? super Long> consumer) {
399ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin            if (consumer instanceof LongConsumer) {
400ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin                forEach((LongConsumer) consumer);
401ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin            }
402ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin            else {
403ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin                if (Tripwire.ENABLED)
404ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin                    Tripwire.trip(getClass(), "{0} calling Node.OfLong.forEachRemaining(Consumer)");
405ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin                spliterator().forEachRemaining(consumer);
406ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin            }
407ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin        }
408ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin
409ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin        /**
410ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin         * {@inheritDoc}
411ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin         *
412ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin         * @implSpec the default implementation invokes {@link #asPrimitiveArray()}
413ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin         * to obtain a long[] array then and copies the elements from that
414ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin         * long[] array into the boxed Long[] array.  This is not efficient and
415ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin         * it is recommended to invoke {@link #copyInto(Object, int)}.
416ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin         */
417ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin        @Override
418ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin        default void copyInto(Long[] boxed, int offset) {
419ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin            if (Tripwire.ENABLED)
420ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin                Tripwire.trip(getClass(), "{0} calling Node.OfInt.copyInto(Long[], int)");
421ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin
422ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin            long[] array = asPrimitiveArray();
423ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin            for (int i = 0; i < array.length; i++) {
424ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin                boxed[offset + i] = array[i];
425ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin            }
426ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin        }
427ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin
428ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin        @Override
429ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin        default Node.OfLong truncate(long from, long to, IntFunction<Long[]> generator) {
430ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin            if (from == 0 && to == count())
431ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin                return this;
432ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin            long size = to - from;
433ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin            Spliterator.OfLong spliterator = spliterator();
434ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin            Node.Builder.OfLong nodeBuilder = Nodes.longBuilder(size);
435ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin            nodeBuilder.begin(size);
436ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin            for (int i = 0; i < from && spliterator.tryAdvance((LongConsumer) e -> { }); i++) { }
437ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin            for (int i = 0; (i < size) && spliterator.tryAdvance((LongConsumer) nodeBuilder); i++) { }
438ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin            nodeBuilder.end();
439ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin            return nodeBuilder.build();
440ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin        }
441ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin
442ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin        @Override
443ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin        default long[] newArray(int count) {
444ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin            return new long[count];
445ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin        }
446ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin
447ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin        /**
448ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin         * {@inheritDoc}
449ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin         * @implSpec The default in {@code Node.OfLong} returns
450ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin         * {@code StreamShape.LONG_VALUE}
451ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin         */
452ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin        default StreamShape getShape() {
453ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin            return StreamShape.LONG_VALUE;
454ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin        }
455ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin    }
456ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin
457ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin    /**
458ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin     * Specialized {@code Node} for double elements
459ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin     */
460ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin    interface OfDouble extends OfPrimitive<Double, DoubleConsumer, double[], Spliterator.OfDouble, OfDouble> {
461ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin
462ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin        /**
463ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin         * {@inheritDoc}
464ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin         *
465ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin         * @param consumer A {@code Consumer} that is to be invoked with each
466ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin         *        element in this {@code Node}.  If this is an
467ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin         *        {@code DoubleConsumer}, it is cast to {@code DoubleConsumer}
468ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin         *        so the elements may be processed without boxing.
469ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin         */
470ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin        @Override
471ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin        default void forEach(Consumer<? super Double> consumer) {
472ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin            if (consumer instanceof DoubleConsumer) {
473ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin                forEach((DoubleConsumer) consumer);
474ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin            }
475ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin            else {
476ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin                if (Tripwire.ENABLED)
477ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin                    Tripwire.trip(getClass(), "{0} calling Node.OfLong.forEachRemaining(Consumer)");
478ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin                spliterator().forEachRemaining(consumer);
479ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin            }
480ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin        }
481ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin
482ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin        //
483ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin
484ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin        /**
485ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin         * {@inheritDoc}
486ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin         *
487ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin         * @implSpec the default implementation invokes {@link #asPrimitiveArray()}
488ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin         * to obtain a double[] array then and copies the elements from that
489ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin         * double[] array into the boxed Double[] array.  This is not efficient
490ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin         * and it is recommended to invoke {@link #copyInto(Object, int)}.
491ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin         */
492ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin        @Override
493ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin        default void copyInto(Double[] boxed, int offset) {
494ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin            if (Tripwire.ENABLED)
495ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin                Tripwire.trip(getClass(), "{0} calling Node.OfDouble.copyInto(Double[], int)");
496ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin
497ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin            double[] array = asPrimitiveArray();
498ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin            for (int i = 0; i < array.length; i++) {
499ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin                boxed[offset + i] = array[i];
500ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin            }
501ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin        }
502ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin
503ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin        @Override
504ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin        default Node.OfDouble truncate(long from, long to, IntFunction<Double[]> generator) {
505ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin            if (from == 0 && to == count())
506ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin                return this;
507ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin            long size = to - from;
508ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin            Spliterator.OfDouble spliterator = spliterator();
509ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin            Node.Builder.OfDouble nodeBuilder = Nodes.doubleBuilder(size);
510ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin            nodeBuilder.begin(size);
511ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin            for (int i = 0; i < from && spliterator.tryAdvance((DoubleConsumer) e -> { }); i++) { }
512ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin            for (int i = 0; (i < size) && spliterator.tryAdvance((DoubleConsumer) nodeBuilder); i++) { }
513ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin            nodeBuilder.end();
514ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin            return nodeBuilder.build();
515ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin        }
516ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin
517ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin        @Override
518ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin        default double[] newArray(int count) {
519ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin            return new double[count];
520ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin        }
521ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin
522ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin        /**
523ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin         * {@inheritDoc}
524ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin         *
525ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin         * @implSpec The default in {@code Node.OfDouble} returns
526ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin         * {@code StreamShape.DOUBLE_VALUE}
527ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin         */
528ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin        default StreamShape getShape() {
529ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin            return StreamShape.DOUBLE_VALUE;
530ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin        }
531ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin    }
532ff18b5f136f92154f2e05217e3953d10f459e561Igor Murashkin}
533