1 /*
2  * Hunt - A refined core library for D programming language.
3  *
4  * Copyright (C) 2018-2019 HuntLabs
5  *
6  * Website: https://www.huntlabs.net/
7  *
8  * Licensed under the Apache-2.0 License.
9  *
10  */
11 
12 module hunt.util.Spliterator;
13 
14 
15 enum SpliteratorCharacteristic {
16     /**
17      * Characteristic value signifying that an encounter order is defined for
18      * elements. If so, this Spliterator guarantees that method
19      * {@link #trySplit} splits a strict prefix of elements, that method
20      * {@link #tryAdvance} steps by one element in prefix order, and that
21      * {@link #forEachRemaining} performs actions in encounter order.
22      *
23      * <p>A {@link Collection} has an encounter order if the corresponding
24      * {@link Collection#iterator} documents an order. If so, the encounter
25      * order is the same as the documented order. Otherwise, a collection does
26      * not have an encounter order.
27      *
28      * @apiNote Encounter order is guaranteed to be ascending index order for
29      * any {@link List}. But no order is guaranteed for hash-based collections
30      * such as {@link HashSet}. Clients of a Spliterator that reports
31      * {@code ORDERED} are expected to preserve ordering constraints in
32      * non-commutative parallel computations.
33      */
34     ORDERED    = 0x00000010,
35 
36     /**
37      * Characteristic value signifying that, for each pair of
38      * encountered elements {@code x, y}, {@code !x.equals(y)}. This
39      * applies for example, to a Spliterator based on a {@link Set}.
40      */
41     DISTINCT   = 0x00000001,
42 
43     /**
44      * Characteristic value signifying that encounter order follows a defined
45      * sort order. If so, method {@link #getComparator()} returns the associated
46      * Comparator, or {@code null} if all elements are {@link Comparable} and
47      * are sorted by their natural ordering.
48      *
49      * <p>A Spliterator that reports {@code SORTED} must also report
50      * {@code ORDERED}.
51      *
52      * @apiNote The spliterators for {@code Collection} classes in the JDK that
53      * implement {@link NavigableSet} or {@link SortedSet} report {@code SORTED}.
54      */
55     SORTED     = 0x00000004,
56 
57     /**
58      * Characteristic value signifying that the value returned from
59      * {@code estimateSize()} prior to traversal or splitting represents a
60      * finite size that, in the absence of structural source modification,
61      * represents an exact count of the number of elements that would be
62      * encountered by a complete traversal.
63      *
64      * @apiNote Most Spliterators for Collections, that cover all elements of a
65      * {@code Collection} report this characteristic. Sub-spliterators, such as
66      * those for {@link HashSet}, that cover a sub-set of elements and
67      * approximate their reported size do not.
68      */
69     SIZED      = 0x00000040,
70 
71     /**
72      * Characteristic value signifying that the source guarantees that
73      * encountered elements will not be {@code null}. (This applies,
74      * for example, to most concurrent collections, queues, and maps.)
75      */
76     NONNULL    = 0x00000100,
77 
78     /**
79      * Characteristic value signifying that the element source cannot be
80      * structurally modified; that is, elements cannot be added, replaced, or
81      * removed, so such changes cannot occur during traversal. A Spliterator
82      * that does not report {@code IMMUTABLE} or {@code CONCURRENT} is expected
83      * to have a documented policy (for example throwing
84      * {@link ConcurrentModificationException}) concerning structural
85      * interference detected during traversal.
86      */
87     IMMUTABLE  = 0x00000400,
88 
89     /**
90      * Characteristic value signifying that the element source may be safely
91      * concurrently modified (allowing additions, replacements, and/or removals)
92      * by multiple threads without external synchronization. If so, the
93      * Spliterator is expected to have a documented policy concerning the impact
94      * of modifications during traversal.
95      *
96      * <p>A top-level Spliterator should not report both {@code CONCURRENT} and
97      * {@code SIZED}, since the finite size, if known, may change if the source
98      * is concurrently modified during traversal. Such a Spliterator is
99      * inconsistent and no guarantees can be made about any computation using
100      * that Spliterator. Sub-spliterators may report {@code SIZED} if the
101      * sub-split size is known and additions or removals to the source are not
102      * reflected when traversing.
103      *
104      * @apiNote Most concurrent collections maintain a consistency policy
105      * guaranteeing accuracy with respect to elements present at the point of
106      * Spliterator construction, but possibly not reflecting subsequent
107      * additions or removals.
108      */
109     CONCURRENT = 0x00001000,
110 
111     /**
112      * Characteristic value signifying that all Spliterators resulting from
113      * {@code trySplit()} will be both {@link #SIZED} and {@link #SUBSIZED}.
114      * (This means that all child Spliterators, whether direct or indirect, will
115      * be {@code SIZED}.)
116      *
117      * <p>A Spliterator that does not report {@code SIZED} as required by
118      * {@code SUBSIZED} is inconsistent and no guarantees can be made about any
119      * computation using that Spliterator.
120      *
121      * @apiNote Some spliterators, such as the top-level spliterator for an
122      * approximately balanced binary tree, will report {@code SIZED} but not
123      * {@code SUBSIZED}, since it is common to know the size of the entire tree
124      * but not the exact sizes of subtrees.
125      */
126     SUBSIZED = 0x00004000
127 }
128 
129 /**
130  * An object for traversing and partitioning elements of a source.  The source
131  * of elements covered by a Spliterator could be, for example, an array, a
132  * {@link Collection}, an IO channel, or a generator function.
133  *
134  * <p>A Spliterator may traverse elements individually ({@link
135  * #tryAdvance tryAdvance()}) or sequentially in bulk
136  * ({@link #forEachRemaining forEachRemaining()}).
137  *
138  * <p>A Spliterator may also partition off some of its elements (using
139  * {@link #trySplit}) as another Spliterator, to be used in
140  * possibly-parallel operations.  Operations using a Spliterator that
141  * cannot split, or does so in a highly imbalanced or inefficient
142  * manner, are unlikely to benefit from parallelism.  Traversal
143  * and splitting exhaust elements; each Spliterator is useful for only a single
144  * bulk computation.
145  *
146  * <p>A Spliterator also reports a set of {@link #characteristics()} of its
147  * structure, source, and elements from among {@link #ORDERED},
148  * {@link #DISTINCT}, {@link #SORTED}, {@link #SIZED}, {@link #NONNULL},
149  * {@link #IMMUTABLE}, {@link #CONCURRENT}, and {@link #SUBSIZED}. These may
150  * be employed by Spliterator clients to control, specialize or simplify
151  * computation.  For example, a Spliterator for a {@link Collection} would
152  * report {@code SIZED}, a Spliterator for a {@link Set} would report
153  * {@code DISTINCT}, and a Spliterator for a {@link SortedSet} would also
154  * report {@code SORTED}.  Characteristics are reported as a simple unioned bit
155  * set.
156  *
157  * Some characteristics additionally constrain method behavior; for example if
158  * {@code ORDERED}, traversal methods must conform to their documented ordering.
159  * New characteristics may be defined in the future, so implementors should not
160  * assign meanings to unlisted values.
161  *
162  * <p><a name="binding">A Spliterator that does not report {@code IMMUTABLE} or
163  * {@code CONCURRENT} is expected to have a documented policy concerning:
164  * when the spliterator <em>binds</em> to the element source; and detection of
165  * structural interference of the element source detected after binding.</a>  A
166  * <em>late-binding</em> Spliterator binds to the source of elements at the
167  * point of first traversal, first split, or first query for estimated size,
168  * rather than at the time the Spliterator is created.  A Spliterator that is
169  * not <em>late-binding</em> binds to the source of elements at the point of
170  * construction or first invocation of any method.  Modifications made to the
171  * source prior to binding are reflected when the Spliterator is traversed.
172  * After binding a Spliterator should, on a best-effort basis, throw
173  * {@link ConcurrentModificationException} if structural interference is
174  * detected.  Spliterators that do this are called <em>fail-fast</em>.  The
175  * bulk traversal method ({@link #forEachRemaining forEachRemaining()}) of a
176  * Spliterator may optimize traversal and check for structural interference
177  * after all elements have been traversed, rather than checking per-element and
178  * failing immediately.
179  *
180  * <p>Spliterators can provide an estimate of the number of remaining elements
181  * via the {@link #estimateSize} method.  Ideally, as reflected in characteristic
182  * {@link #SIZED}, this value corresponds exactly to the number of elements
183  * that would be encountered in a successful traversal.  However, even when not
184  * exactly known, an estimated value value may still be useful to operations
185  * being performed on the source, such as helping to determine whether it is
186  * preferable to split further or traverse the remaining elements sequentially.
187  *
188  * <p>Despite their obvious utility in parallel algorithms, spliterators are not
189  * expected to be thread-safe; instead, implementations of parallel algorithms
190  * using spliterators should ensure that the spliterator is only used by one
191  * thread at a time.  This is generally easy to attain via <em>serial
192  * thread-confinement</em>, which often is a natural consequence of typical
193  * parallel algorithms that work by recursive decomposition.  A thread calling
194  * {@link #trySplit()} may hand over the returned Spliterator to another thread,
195  * which in turn may traverse or further split that Spliterator.  The behaviour
196  * of splitting and traversal is undefined if two or more threads operate
197  * concurrently on the same spliterator.  If the original thread hands a
198  * spliterator off to another thread for processing, it is best if that handoff
199  * occurs before any elements are consumed with {@link #tryAdvance(Consumer)
200  * tryAdvance()}, as certain guarantees (such as the accuracy of
201  * {@link #estimateSize()} for {@code SIZED} spliterators) are only valid before
202  * traversal has begun.
203  *
204  * <p>Primitive subtype specializations of {@code Spliterator} are provided for
205  * {@link OfInt int}, {@link OfLong long}, and {@link OfDouble double} values.
206  * The subtype default implementations of
207  * {@link Spliterator#tryAdvance(hunt.util.functional.Consumer)}
208  * and {@link Spliterator#forEachRemaining(hunt.util.functional.Consumer)} box
209  * primitive values to instances of their corresponding wrapper class.  Such
210  * boxing may undermine any performance advantages gained by using the primitive
211  * specializations.  To avoid boxing, the corresponding primitive-based methods
212  * should be used.  For example,
213  * {@link Spliterator.OfInt#tryAdvance(hunt.util.functional.IntConsumer)}
214  * and {@link Spliterator.OfInt#forEachRemaining(hunt.util.functional.IntConsumer)}
215  * should be used in preference to
216  * {@link Spliterator.OfInt#tryAdvance(hunt.util.functional.Consumer)} and
217  * {@link Spliterator.OfInt#forEachRemaining(hunt.util.functional.Consumer)}.
218  * Traversal of primitive values using boxing-based methods
219  * {@link #tryAdvance tryAdvance()} and
220  * {@link #forEachRemaining(hunt.util.functional.Consumer) forEachRemaining()}
221  * does not affect the order in which the values, transformed to boxed values,
222  * are encountered.
223  *
224  * @apiNote
225  * <p>Spliterators, like {@code Iterator}s, are for traversing the elements of
226  * a source.  The {@code Spliterator} API was designed to support efficient
227  * parallel traversal in addition to sequential traversal, by supporting
228  * decomposition as well as single-element iteration.  In addition, the
229  * protocol for accessing elements via a Spliterator is designed to impose
230  * smaller per-element overhead than {@code Iterator}, and to avoid the inherent
231  * race involved in having separate methods for {@code hasNext()} and
232  * {@code next()}.
233  *
234  * <p>For mutable sources, arbitrary and non-deterministic behavior may occur if
235  * the source is structurally interfered with (elements added, replaced, or
236  * removed) between the time that the Spliterator binds to its data source and
237  * the end of traversal.  For example, such interference will produce arbitrary,
238  * non-deterministic results when using the {@code java.util.stream} framework.
239  *
240  * <p>Structural interference of a source can be managed in the following ways
241  * (in approximate order of decreasing desirability):
242  * <ul>
243  * <li>The source cannot be structurally interfered with.
244  * <br>For example, an instance of
245  * {@link hunt.concurrency.CopyOnWriteArrayList} is an immutable source.
246  * A Spliterator created from the source reports a characteristic of
247  * {@code IMMUTABLE}.</li>
248  * <li>The source manages concurrent modifications.
249  * <br>For example, a key set of a {@link hunt.concurrency.ConcurrentHashMap}
250  * is a concurrent source.  A Spliterator created from the source reports a
251  * characteristic of {@code CONCURRENT}.</li>
252  * <li>The mutable source provides a late-binding and fail-fast Spliterator.
253  * <br>Late binding narrows the window during which interference can affect
254  * the calculation; fail-fast detects, on a best-effort basis, that structural
255  * interference has occurred after traversal has commenced and throws
256  * {@link ConcurrentModificationException}.  For example, {@link ArrayList},
257  * and many other non-concurrent {@code Collection} classes in the JDK, provide
258  * a late-binding, fail-fast spliterator.</li>
259  * <li>The mutable source provides a non-late-binding but fail-fast Spliterator.
260  * <br>The source increases the likelihood of throwing
261  * {@code ConcurrentModificationException} since the window of potential
262  * interference is larger.</li>
263  * <li>The mutable source provides a late-binding and non-fail-fast Spliterator.
264  * <br>The source risks arbitrary, non-deterministic behavior after traversal
265  * has commenced since interference is not detected.
266  * </li>
267  * <li>The mutable source provides a non-late-binding and non-fail-fast
268  * Spliterator.
269  * <br>The source increases the risk of arbitrary, non-deterministic behavior
270  * since non-detected interference may occur after construction.
271  * </li>
272  * </ul>
273  *
274  * <p><b>Example.</b> Here is a class (not a very useful one, except
275  * for illustration) that maintains an array in which the actual data
276  * are held in even locations, and unrelated tag data are held in odd
277  * locations. Its Spliterator ignores the tags.
278  *
279  * <pre> {@code
280  * class TaggedArray!(T) {
281  *   private final Object[] elements; // immutable after construction
282  *   TaggedArray(T[] data, Object[] tags) {
283  *     int size = data.length;
284  *     if (tags.length != size) throw new IllegalArgumentException();
285  *     this.elements = new Object[2 * size];
286  *     for (int i = 0, j = 0; i < size; ++i) {
287  *       elements[j++] = data[i];
288  *       elements[j++] = tags[i];
289  *     }
290  *   }
291  *
292  *   public Spliterator!(T) spliterator() {
293  *     return new TaggedArraySpliterator<>(elements, 0, elements.length);
294  *   }
295  *
296  *   static class TaggedArraySpliterator!(T) : Spliterator!(T) {
297  *     private final Object[] array;
298  *     private int origin; // current index, advanced on split or traversal
299  *     private final int fence; // one past the greatest index
300  *
301  *     TaggedArraySpliterator(Object[] array, int origin, int fence) {
302  *       this.array = array; this.origin = origin; this.fence = fence;
303  *     }
304  *
305  *     public void forEachRemaining(Consumer!(T) action) {
306  *       for (; origin < fence; origin += 2)
307  *         action.accept((T) array[origin]);
308  *     }
309  *
310  *     public bool tryAdvance(Consumer!(T) action) {
311  *       if (origin < fence) {
312  *         action.accept((T) array[origin]);
313  *         origin += 2;
314  *         return true;
315  *       }
316  *       else // cannot advance
317  *         return false;
318  *     }
319  *
320  *     public Spliterator!(T) trySplit() {
321  *       int lo = origin; // divide range in half
322  *       int mid = ((lo + fence) >>> 1) & ~1; // force midpoint to be even
323  *       if (lo < mid) { // split out left half
324  *         origin = mid; // reset this Spliterator's origin
325  *         return new TaggedArraySpliterator<>(array, lo, mid);
326  *       }
327  *       else       // too small to split
328  *         return null;
329  *     }
330  *
331  *     public long estimateSize() {
332  *       return (long)((fence - origin) / 2);
333  *     }
334  *
335  *     public int characteristics() {
336  *       return ORDERED | SIZED | IMMUTABLE | SUBSIZED;
337  *     }
338  *   }
339  * }}</pre>
340  *
341  * <p>As an example how a parallel computation framework, such as the
342  * {@code java.util.stream} package, would use Spliterator in a parallel
343  * computation, here is one way to implement an associated parallel forEach,
344  * that illustrates the primary usage idiom of splitting off subtasks until
345  * the estimated amount of work is small enough to perform
346  * sequentially. Here we assume that the order of processing across
347  * subtasks doesn't matter; different (forked) tasks may further split
348  * and process elements concurrently in undetermined order.  This
349  * example uses a {@link hunt.concurrency.CountedCompleter};
350  * similar usages apply to other parallel task constructions.
351  *
352  * <pre>{@code
353  * static !(T) void parEach(TaggedArray!(T) a, Consumer!(T) action) {
354  *   Spliterator!(T) s = a.spliterator();
355  *   long targetBatchSize = s.estimateSize() / (ForkJoinPool.getCommonPoolParallelism() * 8);
356  *   new ParEach(null, s, action, targetBatchSize).invoke();
357  * }
358  *
359  * static class ParEach!(T) extends CountedCompleter!(void) {
360  *   final Spliterator!(T) spliterator;
361  *   final Consumer!(T) action;
362  *   final long targetBatchSize;
363  *
364  *   ParEach(ParEach!(T) parent, Spliterator!(T) spliterator,
365  *           Consumer!(T) action, long targetBatchSize) {
366  *     super(parent);
367  *     this.spliterator = spliterator; this.action = action;
368  *     this.targetBatchSize = targetBatchSize;
369  *   }
370  *
371  *   public void compute() {
372  *     Spliterator!(T) sub;
373  *     while (spliterator.estimateSize() > targetBatchSize &&
374  *            (sub = spliterator.trySplit()) !is null) {
375  *       addToPendingCount(1);
376  *       new ParEach<>(this, sub, action, targetBatchSize).fork();
377  *     }
378  *     spliterator.forEachRemaining(action);
379  *     propagateCompletion();
380  *   }
381  * }}</pre>
382  *
383  * @implNote
384  * If the bool system property {@code org.openjdk.java.util.stream.tripwire}
385  * is set to {@code true} then diagnostic warnings are reported if boxing of
386  * primitive values occur when operating on primitive subtype specializations.
387  *
388  * @param (T) the type of elements returned by this Spliterator
389  *
390  * @see Collection
391  */
392 interface Spliterator(T) {
393 //     /**
394 //      * If a remaining element exists, performs the given action on it,
395 //      * returning {@code true}; else returns {@code false}.  If this
396 //      * Spliterator is {@link #ORDERED} the action is performed on the
397 //      * next element in encounter order.  Exceptions thrown by the
398 //      * action are relayed to the caller.
399 //      *
400 //      * @param action The action
401 //      * @return {@code false} if no remaining elements existed
402 //      * upon entry to this method, else {@code true}.
403 //      * @throws NullPointerException if the specified action is null
404 //      */
405 //     bool tryAdvance(Consumer!(T) action);
406 
407 //     /**
408 //      * Performs the given action for each remaining element, sequentially in
409 //      * the current thread, until all elements have been processed or the action
410 //      * throws an exception.  If this Spliterator is {@link #ORDERED}, actions
411 //      * are performed in encounter order.  Exceptions thrown by the action
412 //      * are relayed to the caller.
413 //      *
414 //      * @implSpec
415 //      * The default implementation repeatedly invokes {@link #tryAdvance} until
416 //      * it returns {@code false}.  It should be overridden whenever possible.
417 //      *
418 //      * @param action The action
419 //      * @throws NullPointerException if the specified action is null
420 //      */
421 //     default void forEachRemaining(Consumer!(T) action) {
422 //         do { } while (tryAdvance(action));
423 //     }
424 
425 //     /**
426 //      * If this spliterator can be partitioned, returns a Spliterator
427 //      * covering elements, that will, upon return from this method, not
428 //      * be covered by this Spliterator.
429 //      *
430 //      * <p>If this Spliterator is {@link #ORDERED}, the returned Spliterator
431 //      * must cover a strict prefix of the elements.
432 //      *
433 //      * <p>Unless this Spliterator covers an infinite number of elements,
434 //      * repeated calls to {@code trySplit()} must eventually return {@code null}.
435 //      * Upon non-null return:
436 //      * <ul>
437 //      * <li>the value reported for {@code estimateSize()} before splitting,
438 //      * must, after splitting, be greater than or equal to {@code estimateSize()}
439 //      * for this and the returned Spliterator; and</li>
440 //      * <li>if this Spliterator is {@code SUBSIZED}, then {@code estimateSize()}
441 //      * for this spliterator before splitting must be equal to the sum of
442 //      * {@code estimateSize()} for this and the returned Spliterator after
443 //      * splitting.</li>
444 //      * </ul>
445 //      *
446 //      * <p>This method may return {@code null} for any reason,
447 //      * including emptiness, inability to split after traversal has
448 //      * commenced, data structure constraints, and efficiency
449 //      * considerations.
450 //      *
451 //      * @apiNote
452 //      * An ideal {@code trySplit} method efficiently (without
453 //      * traversal) divides its elements exactly in half, allowing
454 //      * balanced parallel computation.  Many departures from this ideal
455 //      * remain highly effective; for example, only approximately
456 //      * splitting an approximately balanced tree, or for a tree in
457 //      * which leaf nodes may contain either one or two elements,
458 //      * failing to further split these nodes.  However, large
459 //      * deviations in balance and/or overly inefficient {@code
460 //      * trySplit} mechanics typically result in poor parallel
461 //      * performance.
462 //      *
463 //      * @return a {@code Spliterator} covering some portion of the
464 //      * elements, or {@code null} if this spliterator cannot be split
465 //      */
466 //     Spliterator!(T) trySplit();
467 
468 //     /**
469 //      * Returns an estimate of the number of elements that would be
470 //      * encountered by a {@link #forEachRemaining} traversal, or returns {@link
471 //      * Long#MAX_VALUE} if infinite, unknown, or too expensive to compute.
472 //      *
473 //      * <p>If this Spliterator is {@link #SIZED} and has not yet been partially
474 //      * traversed or split, or this Spliterator is {@link #SUBSIZED} and has
475 //      * not yet been partially traversed, this estimate must be an accurate
476 //      * count of elements that would be encountered by a complete traversal.
477 //      * Otherwise, this estimate may be arbitrarily inaccurate, but must decrease
478 //      * as specified across invocations of {@link #trySplit}.
479 //      *
480 //      * @apiNote
481 //      * Even an inexact estimate is often useful and inexpensive to compute.
482 //      * For example, a sub-spliterator of an approximately balanced binary tree
483 //      * may return a value that estimates the number of elements to be half of
484 //      * that of its parent; if the root Spliterator does not maintain an
485 //      * accurate count, it could estimate size to be the power of two
486 //      * corresponding to its maximum depth.
487 //      *
488 //      * @return the estimated size, or {@code Long.MAX_VALUE} if infinite,
489 //      *         unknown, or too expensive to compute.
490 //      */
491 //     long estimateSize();
492 
493 //     /**
494 //      * Convenience method that returns {@link #estimateSize()} if this
495 //      * Spliterator is {@link #SIZED}, else {@code -1}.
496 //      * @implSpec
497 //      * The default implementation returns the result of {@code estimateSize()}
498 //      * if the Spliterator reports a characteristic of {@code SIZED}, and
499 //      * {@code -1} otherwise.
500 //      *
501 //      * @return the exact size, if known, else {@code -1}.
502 //      */
503 //     default long getExactSizeIfKnown() {
504 //         return (characteristics() & SIZED) == 0 ? -1L : estimateSize();
505 //     }
506 
507 //     /**
508 //      * Returns a set of characteristics of this Spliterator and its
509 //      * elements. The result is represented as ORed values from {@link
510 //      * #ORDERED}, {@link #DISTINCT}, {@link #SORTED}, {@link #SIZED},
511 //      * {@link #NONNULL}, {@link #IMMUTABLE}, {@link #CONCURRENT},
512 //      * {@link #SUBSIZED}.  Repeated calls to {@code characteristics()} on
513 //      * a given spliterator, prior to or in-between calls to {@code trySplit},
514 //      * should always return the same result.
515 //      *
516 //      * <p>If a Spliterator reports an inconsistent set of
517 //      * characteristics (either those returned from a single invocation
518 //      * or across multiple invocations), no guarantees can be made
519 //      * about any computation using this Spliterator.
520 //      *
521 //      * @apiNote The characteristics of a given spliterator before splitting
522 //      * may differ from the characteristics after splitting.  For specific
523 //      * examples see the characteristic values {@link #SIZED}, {@link #SUBSIZED}
524 //      * and {@link #CONCURRENT}.
525 //      *
526 //      * @return a representation of characteristics
527 //      */
528 //     int characteristics();
529 
530 //     /**
531 //      * Returns {@code true} if this Spliterator's {@link
532 //      * #characteristics} contain all of the given characteristics.
533 //      *
534 //      * @implSpec
535 //      * The default implementation returns true if the corresponding bits
536 //      * of the given characteristics are set.
537 //      *
538 //      * @param characteristics the characteristics to check for
539 //      * @return {@code true} if all the specified characteristics are present,
540 //      * else {@code false}
541 //      */
542 //     default bool hasCharacteristics(int characteristics) {
543 //         return (characteristics() & characteristics) == characteristics;
544 //     }
545 
546 //     /**
547 //      * If this Spliterator's source is {@link #SORTED} by a {@link Comparator},
548 //      * returns that {@code Comparator}. If the source is {@code SORTED} in
549 //      * {@linkplain Comparable natural order}, returns {@code null}.  Otherwise,
550 //      * if the source is not {@code SORTED}, throws {@link IllegalStateException}.
551 //      *
552 //      * @implSpec
553 //      * The default implementation always throws {@link IllegalStateException}.
554 //      *
555 //      * @return a Comparator, or {@code null} if the elements are sorted in the
556 //      * natural order.
557 //      * @throws IllegalStateException if the spliterator does not report
558 //      *         a characteristic of {@code SORTED}.
559 //      */
560 //     default Comparator<T> getComparator() {
561 //         throw new IllegalStateException();
562 //     }
563 
564 
565 
566 //     /**
567 //      * A Spliterator specialized for primitive values.
568 //      *
569 //      * @param (T) the type of elements returned by this Spliterator.  The
570 //      * type must be a wrapper type for a primitive type, such as {@code Integer}
571 //      * for the primitive {@code int} type.
572 //      * @param <T_CONS> the type of primitive consumer.  The type must be a
573 //      * primitive specialization of {@link hunt.util.functional.Consumer} for
574 //      * {@code T}, such as {@link hunt.util.functional.IntConsumer} for
575 //      * {@code Integer}.
576 //      * @param <T_SPLITR> the type of primitive Spliterator.  The type must be
577 //      * a primitive specialization of Spliterator for {@code T}, such as
578 //      * {@link Spliterator.OfInt} for {@code Integer}.
579 //      *
580 //      * @see Spliterator.OfInt
581 //      * @see Spliterator.OfLong
582 //      * @see Spliterator.OfDouble
583 //      * @since 1.8
584 //      */
585 //     public interface OfPrimitive<T, T_CONS, T_SPLITR extends Spliterator.OfPrimitive<T, T_CONS, T_SPLITR>>
586 //             extends Spliterator!(T) {
587 //         @Override
588 //         T_SPLITR trySplit();
589 
590 //         /**
591 //          * If a remaining element exists, performs the given action on it,
592 //          * returning {@code true}; else returns {@code false}.  If this
593 //          * Spliterator is {@link #ORDERED} the action is performed on the
594 //          * next element in encounter order.  Exceptions thrown by the
595 //          * action are relayed to the caller.
596 //          *
597 //          * @param action The action
598 //          * @return {@code false} if no remaining elements existed
599 //          * upon entry to this method, else {@code true}.
600 //          * @throws NullPointerException if the specified action is null
601 //          */
602 //     
603 //         bool tryAdvance(T_CONS action);
604 
605 //         /**
606 //          * Performs the given action for each remaining element, sequentially in
607 //          * the current thread, until all elements have been processed or the
608 //          * action throws an exception.  If this Spliterator is {@link #ORDERED},
609 //          * actions are performed in encounter order.  Exceptions thrown by the
610 //          * action are relayed to the caller.
611 //          *
612 //          * @implSpec
613 //          * The default implementation repeatedly invokes {@link #tryAdvance}
614 //          * until it returns {@code false}.  It should be overridden whenever
615 //          * possible.
616 //          *
617 //          * @param action The action
618 //          * @throws NullPointerException if the specified action is null
619 //          */
620 //     
621 //         default void forEachRemaining(T_CONS action) {
622 //             do { } while (tryAdvance(action));
623 //         }
624 //     }
625 
626 //     /**
627 //      * A Spliterator specialized for {@code int} values.
628 //      * @since 1.8
629 //      */
630 //     public interface OfInt extends OfPrimitive<Integer, IntConsumer, OfInt> {
631 
632 //         @Override
633 //         OfInt trySplit();
634 
635 //         @Override
636 //         bool tryAdvance(IntConsumer action);
637 
638 //         @Override
639 //         default void forEachRemaining(IntConsumer action) {
640 //             do { } while (tryAdvance(action));
641 //         }
642 
643 //         /**
644 //          * {@inheritDoc}
645 //          * @implSpec
646 //          * If the action is an instance of {@code IntConsumer} then it is cast
647 //          * to {@code IntConsumer} and passed to
648 //          * {@link #tryAdvance(hunt.util.functional.IntConsumer)}; otherwise
649 //          * the action is adapted to an instance of {@code IntConsumer}, by
650 //          * boxing the argument of {@code IntConsumer}, and then passed to
651 //          * {@link #tryAdvance(hunt.util.functional.IntConsumer)}.
652 //          */
653 //         @Override
654 //         default bool tryAdvance(Consumer<Integer> action) {
655 //             if (action instanceof IntConsumer) {
656 //                 return tryAdvance((IntConsumer) action);
657 //             }
658 //             else {
659 //                 if (Tripwire.ENABLED)
660 //                     Tripwire.trip(getClass(),
661 //                                   "{0} calling Spliterator.OfInt.tryAdvance((IntConsumer) action::accept)");
662 //                 return tryAdvance((IntConsumer) action::accept);
663 //             }
664 //         }
665 
666 //         /**
667 //          * {@inheritDoc}
668 //          * @implSpec
669 //          * If the action is an instance of {@code IntConsumer} then it is cast
670 //          * to {@code IntConsumer} and passed to
671 //          * {@link #forEachRemaining(hunt.util.functional.IntConsumer)}; otherwise
672 //          * the action is adapted to an instance of {@code IntConsumer}, by
673 //          * boxing the argument of {@code IntConsumer}, and then passed to
674 //          * {@link #forEachRemaining(hunt.util.functional.IntConsumer)}.
675 //          */
676 //         @Override
677 //         default void forEachRemaining(Consumer<Integer> action) {
678 //             if (action instanceof IntConsumer) {
679 //                 forEachRemaining((IntConsumer) action);
680 //             }
681 //             else {
682 //                 if (Tripwire.ENABLED)
683 //                     Tripwire.trip(getClass(),
684 //                                   "{0} calling Spliterator.OfInt.forEachRemaining((IntConsumer) action::accept)");
685 //                 forEachRemaining((IntConsumer) action::accept);
686 //             }
687 //         }
688 //     }
689 
690 //     /**
691 //      * A Spliterator specialized for {@code long} values.
692 //      * @since 1.8
693 //      */
694 //     public interface OfLong extends OfPrimitive<Long, LongConsumer, OfLong> {
695 
696 //         @Override
697 //         OfLong trySplit();
698 
699 //         @Override
700 //         bool tryAdvance(LongConsumer action);
701 
702 //         @Override
703 //         default void forEachRemaining(LongConsumer action) {
704 //             do { } while (tryAdvance(action));
705 //         }
706 
707 //         /**
708 //          * {@inheritDoc}
709 //          * @implSpec
710 //          * If the action is an instance of {@code LongConsumer} then it is cast
711 //          * to {@code LongConsumer} and passed to
712 //          * {@link #tryAdvance(hunt.util.functional.LongConsumer)}; otherwise
713 //          * the action is adapted to an instance of {@code LongConsumer}, by
714 //          * boxing the argument of {@code LongConsumer}, and then passed to
715 //          * {@link #tryAdvance(hunt.util.functional.LongConsumer)}.
716 //          */
717 //         @Override
718 //         default bool tryAdvance(Consumer<Long> action) {
719 //             if (action instanceof LongConsumer) {
720 //                 return tryAdvance((LongConsumer) action);
721 //             }
722 //             else {
723 //                 if (Tripwire.ENABLED)
724 //                     Tripwire.trip(getClass(),
725 //                                   "{0} calling Spliterator.OfLong.tryAdvance((LongConsumer) action::accept)");
726 //                 return tryAdvance((LongConsumer) action::accept);
727 //             }
728 //         }
729 
730 //         /**
731 //          * {@inheritDoc}
732 //          * @implSpec
733 //          * If the action is an instance of {@code LongConsumer} then it is cast
734 //          * to {@code LongConsumer} and passed to
735 //          * {@link #forEachRemaining(hunt.util.functional.LongConsumer)}; otherwise
736 //          * the action is adapted to an instance of {@code LongConsumer}, by
737 //          * boxing the argument of {@code LongConsumer}, and then passed to
738 //          * {@link #forEachRemaining(hunt.util.functional.LongConsumer)}.
739 //          */
740 //         @Override
741 //         default void forEachRemaining(Consumer<Long> action) {
742 //             if (action instanceof LongConsumer) {
743 //                 forEachRemaining((LongConsumer) action);
744 //             }
745 //             else {
746 //                 if (Tripwire.ENABLED)
747 //                     Tripwire.trip(getClass(),
748 //                                   "{0} calling Spliterator.OfLong.forEachRemaining((LongConsumer) action::accept)");
749 //                 forEachRemaining((LongConsumer) action::accept);
750 //             }
751 //         }
752 //     }
753 
754 //     /**
755 //      * A Spliterator specialized for {@code double} values.
756 //      * @since 1.8
757 //      */
758 //     public interface OfDouble extends OfPrimitive<Double, DoubleConsumer, OfDouble> {
759 
760 //         @Override
761 //         OfDouble trySplit();
762 
763 //         @Override
764 //         bool tryAdvance(DoubleConsumer action);
765 
766 //         @Override
767 //         default void forEachRemaining(DoubleConsumer action) {
768 //             do { } while (tryAdvance(action));
769 //         }
770 
771 //         /**
772 //          * {@inheritDoc}
773 //          * @implSpec
774 //          * If the action is an instance of {@code DoubleConsumer} then it is
775 //          * cast to {@code DoubleConsumer} and passed to
776 //          * {@link #tryAdvance(hunt.util.functional.DoubleConsumer)}; otherwise
777 //          * the action is adapted to an instance of {@code DoubleConsumer}, by
778 //          * boxing the argument of {@code DoubleConsumer}, and then passed to
779 //          * {@link #tryAdvance(hunt.util.functional.DoubleConsumer)}.
780 //          */
781 //         @Override
782 //         default bool tryAdvance(Consumer<Double> action) {
783 //             if (action instanceof DoubleConsumer) {
784 //                 return tryAdvance((DoubleConsumer) action);
785 //             }
786 //             else {
787 //                 if (Tripwire.ENABLED)
788 //                     Tripwire.trip(getClass(),
789 //                                   "{0} calling Spliterator.OfDouble.tryAdvance((DoubleConsumer) action::accept)");
790 //                 return tryAdvance((DoubleConsumer) action::accept);
791 //             }
792 //         }
793 
794 //         /**
795 //          * {@inheritDoc}
796 //          * @implSpec
797 //          * If the action is an instance of {@code DoubleConsumer} then it is
798 //          * cast to {@code DoubleConsumer} and passed to
799 //          * {@link #forEachRemaining(hunt.util.functional.DoubleConsumer)};
800 //          * otherwise the action is adapted to an instance of
801 //          * {@code DoubleConsumer}, by boxing the argument of
802 //          * {@code DoubleConsumer}, and then passed to
803 //          * {@link #forEachRemaining(hunt.util.functional.DoubleConsumer)}.
804 //          */
805 //         @Override
806 //         default void forEachRemaining(Consumer<Double> action) {
807 //             if (action instanceof DoubleConsumer) {
808 //                 forEachRemaining((DoubleConsumer) action);
809 //             }
810 //             else {
811 //                 if (Tripwire.ENABLED)
812 //                     Tripwire.trip(getClass(),
813 //                                   "{0} calling Spliterator.OfDouble.forEachRemaining((DoubleConsumer) action::accept)");
814 //                 forEachRemaining((DoubleConsumer) action::accept);
815 //             }
816 //         }
817 //     }
818 }