spliterator);
/**
* Apply the pipeline stages described by this {@code PipelineHelper} to the provided {@code Spliterator} and
* send the results to the provided {@code Sink}.
*
* @implSpec
* The implementation behaves as if:
*
* intoWrapped(wrapSink(sink), spliterator);
*
*
* @param sink the {@code Sink} to receive the results
* @param spliterator the spliterator describing the portion of the source input to process
*/
> S into(S sink, Spliterator spliterator);
/**
* Push elements obtained from the {@code Spliterator} into the provided {@code Sink}. If the stream
* pipeline is known to have short-circuiting stages in it (see {@link StreamOpFlag#SHORT_CIRCUIT}), then the
* elements are delivered as per {@link #intoWrappedWithCancel(Sink, Spliterator)}.
*
* @implSpec
* This method conforms to the {@code Sink} protocol of calling {@code Sink.begin} before pushing
* elements, via {@code Sink.accept}, and calling {@code Sink.end} after all elements have
* been pushed.
*
* @param wrappedSink the destination {@code Sink}
* @param spliterator the source {@code Spliterator}
*/
void intoWrapped(Sink wrappedSink, Spliterator spliterator);
/**
* Push elements obtained from the {@code Spliterator} into the provided {@code Sink}, checking
* {@link Sink#cancellationRequested()} after each element, and stopping if cancellation is requested.
*
* @implSpec
* This method conforms to the {@code Sink} protocol of calling {@code Sink.begin} before pushing
* elements, via {@code Sink.accept}, and calling {@code Sink.end} after all elements have
* been pushed or if cancellation is requested.
*
* @param wrappedSink the destination {@code Sink}
* @param spliterator the source {@code Spliterator}
*/
void intoWrappedWithCancel(Sink wrappedSink, Spliterator spliterator);
/**
* Take a {@code Sink} that accepts elements of the output type of the {@code PipelineHelper}, and wrap it with
* a {@code Sink} that accepts elements of the input type and implements all the intermediate operations described
* by this {@code PipelineHelper}, delivering the result into the provided {@code Sink}.
*
* @param sink the {@code Sink} to receive the results
* @return a {@code Sink} that implements the pipeline stages and sends results to the provided {@code Sink}
*/
Sink wrapSink(Sink sink);
/**
* Construct a @{link Node.Builder} compatible with the output shape of this {@code PipelineHelper}
*
* @param exactSizeIfKnown if >=0 then a builder will be created that has a fixed capacity of exactly
* sizeIfKnown elements; if < 0 then the builder has variable capacity.
* A fixed capacity builder will fail if an element is added and the builder has reached
* capacity.
* @return A {@code Node.Builder} compatible with the output shape of this {@code PipelineHelper}
*/
Node.Builder makeNodeBuilder(long exactSizeIfKnown);
/**
* Collect all output elements resulting from applying the pipeline stages to the source {@code Spliterator}
* into a {@code Node}.
*
* @implSpec
* If the pipeline has no intermediate operations and the source is backed by a {@code Node} then
* that {@code Node} will be returned or flattened and then returned. This reduces copying for a pipeline
* consisting of a stateful operation followed by a terminal operation that returns an array, such as:
* {@code
* stream.sorted().toArray();
* }
*
* @param flatten if true and the pipeline is a parallel pipeline then the {@code Node} returned
* will contain no children, otherwise the {@code Node} may represent the root in a
* tree that reflects the shape of the computation tree.
* @return the {@code Node} containing all output elements
*/
Node collectOutput(boolean flatten);
/**
* Get an array factory associated with the output type of this pipeline.
*
* @return a factory for arrays of the output type of this pipeline.
*/
IntFunction arrayGenerator();
}