ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/jsr166/jsr166/src/extra166y/AbstractParallelAnyArray.java
Revision: 1.8
Committed: Sat May 7 19:06:27 2011 UTC (13 years ago) by jsr166
Branch: MAIN
Changes since 1.7: +1 -1 lines
Log Message:
whitespace

File Contents

# User Rev Content
1 dl 1.1 /*
2     * Written by Doug Lea with assistance from members of JCP JSR-166
3     * Expert Group and released to the public domain, as explained at
4 jsr166 1.6 * http://creativecommons.org/publicdomain/zero/1.0/
5 dl 1.1 */
6    
7     package extra166y;
8     import jsr166y.*;
9     import static extra166y.Ops.*;
10     import java.util.*;
11     import java.util.concurrent.atomic.*;
12     import java.lang.reflect.Array;
13    
14     /**
15     * Abstract class serving as the basis of parallel
16     * array classes across types.
17     */
18     public abstract class AbstractParallelAnyArray {
19     /*
20     * This class and its subclasses (most of which are defined here
21     * as nested static classes) maintain the execution parameters for
22     * ParallelArray, ParallelDoubleArray, and ParallelLongArray
23     * tasks. Pap instances hold the non-operation-specific control
24     * and data accessors needed for a task as a whole (as opposed to
25     * subtasks), and also house some of the leaf methods that perform
26     * the actual array processing. The leaf methods are for the most
27     * part just plain array operations. They are boringly repetitive
28     * in order to flatten out and minimize inner-loop overhead, as
29     * well as to minimize call-chain depth. This makes it more likely
30     * that dynamic compilers can go the rest of the way, and hoist
31     * per-element method call dispatch, so we have a good chance to
32     * speed up processing via parallelism rather than lose due to
33     * dispatch and indirection overhead. The dispatching from Pap to
34     * FJ and back is otherwise Visitor-pattern-like, allowing the
35     * basic parallelism control for most FJ tasks to be centralized.
36     *
37     * Note the extensive use of raw types. Arrays and generics do not
38     * work together very well. It is more manageable to avoid them here,
39     * and let the public classes perform casts in and out to the
40     * processing here. Also note that the majority of code in concrete
41     * classes is just for managing the various flavors created using
42     * with* methods.
43     *
44     * Internal concrete classes are named using an
45     * abbreviation scheme to avoid mile-long class names:
46     * O, D, L for Object, Double, Long, for underlying Parallel array
47     * U - unfiltered
48     * F - filtered
49     * R - relation-filtered (aka index-filtered)
50     * OM, DM, LM - Mapped
51     * OC, DC, LC - combiner-mapped (aka index-mapped)
52     */
53    
54     final ForkJoinPool ex;
55     final int origin;
56     int fence;
57     int threshold;
58    
59     AbstractParallelAnyArray(ForkJoinPool ex, int origin, int fence) {
60     this.ex = ex;
61     this.origin = origin;
62     this.fence = fence;
63     }
64    
65     // A few public methods exported across all subclasses
66    
67     /**
68     * Return the number of elements selected using bound or
69     * filter restrictions. Note that this method must evaluate
70     * all selectors to return its result.
71     * @return the number of elements
72     */
73     public int size() {
74     if (!hasFilter())
75     return fence - origin;
76     PAS.FJCountSelected f = new PAS.FJCountSelected
77     (this, origin, fence, null);
78     ex.invoke(f);
79     return f.count;
80     }
81    
82     /**
83     * Returns the index of some element matching bound and filter
84     * constraints, or -1 if none.
85     * @return index of matching element, or -1 if none.
86     */
87     public int anyIndex() {
88     if (!hasFilter())
89 jsr166 1.5 return (origin < fence) ? origin : -1;
90 dl 1.1 AtomicInteger result = new AtomicInteger(-1);
91     PAS.FJSelectAny f = new PAS.FJSelectAny
92     (this, origin, fence, null, result);
93     ex.invoke(f);
94     return result.get();
95     }
96    
97     /**
98     * Returns true if there are no elements
99     * @return true if there are no elements
100     */
101     public boolean isEmpty() {
102     return anyIndex() < 0;
103     }
104    
105    
106     /**
107     * Returns size threshold for splitting into subtask. By
108     * default, uses about 8 times as many tasks as threads
109     */
110     final int computeThreshold() {
111     int n = fence - origin;
112     int p = ex.getParallelism();
113     return threshold = (p > 1) ? (1 + n / (p << 3)) : n;
114     }
115    
116     /**
117     * Returns lazily computed threshold.
118     */
119     final int getThreshold() {
120     int t = threshold;
121 jsr166 1.2 if (t == 0)
122 dl 1.1 t = computeThreshold();
123     return t;
124     }
125    
126     /**
127     * Access methods for ref, double, long. Checking for
128     * null/false return is used as a sort of type test. These
129     * are used to avoid duplication in non-performance-critical
130     * aspects of control, as well as to provide a simple default
131     * mechanism for extensions.
132     */
133     Object[] ogetArray() { return null; }
134     double[] dgetArray() { return null; }
135     long[] lgetArray() { return null; }
136     abstract Object oget(int index);
137     abstract double dget(int index);
138     abstract long lget(int index);
139     boolean hasMap() { return false; }
140     boolean hasFilter() { return false; }
141     boolean isSelected(int index) { return true; }
142    
143     /*
144     * Leaf methods for FJ tasks. Default versions use isSelected,
145     * oget, dget, etc. But most are overridden in most concrete
146     * classes to avoid per-element dispatching.
147     */
148     void leafApply(int lo, int hi, Procedure procedure) {
149     for (int i = lo; i < hi; ++i)
150     if (isSelected(i))
151     procedure.op(oget(i));
152     }
153    
154     void leafApply(int lo, int hi, DoubleProcedure procedure) {
155     for (int i = lo; i < hi; ++i)
156     if (isSelected(i))
157     procedure.op(dget(i));
158     }
159    
160     void leafApply(int lo, int hi, LongProcedure procedure) {
161     for (int i = lo; i < hi; ++i)
162     if (isSelected(i))
163     procedure.op(lget(i));
164     }
165    
166     Object leafReduce(int lo, int hi, Reducer reducer, Object base) {
167     boolean gotFirst = false;
168     Object r = base;
169     for (int i = lo; i < hi; ++i) {
170     if (isSelected(i)) {
171     Object x = oget(i);
172     if (!gotFirst) {
173     gotFirst = true;
174     r = x;
175     }
176     else
177     r = reducer.op(r, x);
178     }
179     }
180     return r;
181     }
182    
183     double leafReduce(int lo, int hi, DoubleReducer reducer, double base) {
184     boolean gotFirst = false;
185     double r = base;
186     for (int i = lo; i < hi; ++i) {
187     if (isSelected(i)) {
188     double x = dget(i);
189     if (!gotFirst) {
190     gotFirst = true;
191     r = x;
192     }
193     else
194     r = reducer.op(r, x);
195     }
196     }
197     return r;
198     }
199    
200     long leafReduce(int lo, int hi, LongReducer reducer, long base) {
201     boolean gotFirst = false;
202     long r = base;
203     for (int i = lo; i < hi; ++i) {
204     if (isSelected(i)) {
205     long x = lget(i);
206     if (!gotFirst) {
207     gotFirst = true;
208     r = x;
209     }
210     else
211     r = reducer.op(r, x);
212     }
213     }
214     return r;
215     }
216    
217     // copy elements, ignoring selector, but applying mapping
218     void leafTransfer(int lo, int hi, Object[] dest, int offset) {
219     for (int i = lo; i < hi; ++i)
220     dest[offset++] = oget(i);
221     }
222    
223     void leafTransfer(int lo, int hi, double[] dest, int offset) {
224     for (int i = lo; i < hi; ++i)
225     dest[offset++] = dget(i);
226     }
227    
228     void leafTransfer(int lo, int hi, long[] dest, int offset) {
229     for (int i = lo; i < hi; ++i)
230     dest[offset++] = lget(i);
231     }
232    
233     // copy elements indexed in indices[loIdx..hiIdx], ignoring
234     // selector, but applying mapping
235     void leafTransferByIndex(int[] indices, int loIdx, int hiIdx,
236     Object[] dest, int offset) {
237     for (int i = loIdx; i < hiIdx; ++i)
238     dest[offset++] = oget(indices[i]);
239     }
240    
241     void leafTransferByIndex(int[] indices, int loIdx, int hiIdx,
242     double[] dest, int offset) {
243     for (int i = loIdx; i < hiIdx; ++i)
244     dest[offset++] = dget(indices[i]);
245     }
246    
247     void leafTransferByIndex(int[] indices, int loIdx, int hiIdx,
248     long[] dest, int offset) {
249     for (int i = loIdx; i < hiIdx; ++i)
250     dest[offset++] = lget(indices[i]);
251     }
252    
253     // add indices of selected elements to index array; return #added
254     final int leafIndexSelected(int lo, int hi, boolean positive,
255     int[] indices) {
256     int k = 0;
257     for (int i = lo; i < hi; ++i) {
258     if (isSelected(i) == positive)
259     indices[lo + k++] = i;
260     }
261     return k;
262     }
263    
264     // move selected elements to indices starting at offset,
265     // return final offset
266     abstract int leafMoveSelected(int lo, int hi, int offset,
267     boolean positive);
268    
269     // move elements indexed by indices[loIdx...hiIdx] starting
270     // at given offset
271     abstract void leafMoveByIndex(int[] indices, int loIdx,
272     int hiIdx, int offset);
273    
274     /**
275     * Shared support for select/map all -- probe filter, map, and
276     * type to start selection driver, or do parallel mapping, or
277     * just copy,
278     */
279     final Object[] allObjects(Class elementType) {
280     if (hasFilter()) {
281     if (elementType == null) {
282     if (!hasMap())
283     elementType = ogetArray().getClass().getComponentType();
284     else
285     elementType = Object.class;
286     }
287     PAS.FJOSelectAllDriver r = new PAS.FJOSelectAllDriver
288     (this, elementType);
289     ex.invoke(r);
290     return r.results;
291     }
292     else {
293     int n = fence - origin;
294     Object[] dest;
295     if (hasMap()) {
296     if (elementType == null)
297     dest = new Object[n];
298     else
299     dest = (Object[])Array.newInstance(elementType, n);
300     ex.invoke(new PAS.FJOMap(this, origin, fence,
301     null, dest, -origin));
302     }
303     else {
304     Object[] array = ogetArray();
305     if (elementType == null)
306     elementType = array.getClass().getComponentType();
307     dest = (Object[])Array.newInstance(elementType, n);
308     System.arraycopy(array, origin, dest, 0, n);
309     }
310     return dest;
311     }
312     }
313    
314     final double[] allDoubles() {
315     if (hasFilter()) {
316     PAS.FJDSelectAllDriver r = new PAS.FJDSelectAllDriver(this);
317     ex.invoke(r);
318     return r.results;
319     }
320     else {
321     int n = fence - origin;
322     double[] dest = new double[n];
323     if (hasMap()) {
324     ex.invoke(new PAS.FJDMap(this, origin, fence,
325     null, dest, -origin));
326     }
327     else {
328     double[] array = dgetArray();
329     System.arraycopy(array, origin, dest, 0, n);
330     }
331     return dest;
332     }
333     }
334    
335     final long[] allLongs() {
336     if (hasFilter()) {
337     PAS.FJLSelectAllDriver r = new PAS.FJLSelectAllDriver(this);
338     ex.invoke(r);
339     return r.results;
340     }
341     else {
342     int n = fence - origin;
343     long[] dest = new long[n];
344     if (hasMap()) {
345     ex.invoke(new PAS.FJLMap(this, origin, fence,
346     null, dest, -origin));
347     }
348     else {
349     long[] array = lgetArray();
350     System.arraycopy(array, origin, dest, 0, n);
351     }
352     return dest;
353     }
354     }
355    
356     // Bounds check a range
357     void boundsCheck(int lo, int hi) {
358     if (lo > hi)
359     throw new IllegalArgumentException(origin + " > " + fence);
360     if (lo < 0)
361     throw new ArrayIndexOutOfBoundsException(origin);
362     if (hi - lo > this.fence - this.origin)
363     throw new ArrayIndexOutOfBoundsException(fence);
364     }
365    
366     /*
367     * The following methods can be called only for classes
368     * supporting in-place replacements (currently, those classes
369     * without mappings). They are declared as no-ops here, and
370     * overridden only where applicable.
371     */
372    
373     void leafTransform(int l, int h, Op op) {}
374     void leafIndexMap(int l, int h, IntToObject op) {}
375     void leafBinaryIndexMap(int l, int h, IntAndObjectToObject op) {}
376     void leafGenerate(int l, int h, Generator generator) {}
377     void leafFill(int l, int h, Object value) {}
378     void leafCombineInPlace(int lo, int hi, Object[] other,
379     int otherOffset, BinaryOp combiner) {}
380     void leafCombineInPlace(int lo, int hi, ParallelArrayWithMapping other,
381     int otherOffset, BinaryOp combiner) {}
382    
383     void leafTransform(int l, int h, DoubleOp op) {}
384     void leafIndexMap(int l, int h, IntToDouble array) {}
385     void leafBinaryIndexMap(int l, int h, IntAndDoubleToDouble op) {}
386     void leafGenerate(int l, int h, DoubleGenerator generator) {}
387     void leafFill(int l, int h, double value) {}
388     void leafCombineInPlace(int lo, int hi, double[] other,
389     int otherOffset, BinaryDoubleOp combiner) {}
390     void leafCombineInPlace(int lo, int hi,
391     ParallelDoubleArrayWithDoubleMapping other,
392     int otherOffset, BinaryDoubleOp combiner) {}
393    
394     void leafTransform(int l, int h, LongOp op) {}
395     void leafIndexMap(int l, int h, IntToLong array) {}
396     void leafBinaryIndexMap(int l, int h, IntAndLongToLong op) {}
397     void leafGenerate(int l, int h, LongGenerator generator) {}
398     void leafFill(int l, int h, long value) {}
399     void leafCombineInPlace(int lo, int hi, long[] other,
400     int otherOffset, BinaryLongOp combiner) {}
401     void leafCombineInPlace(int lo, int hi,
402     ParallelLongArrayWithLongMapping other,
403     int otherOffset, BinaryLongOp combiner) {}
404    
405     // Base of object ref array classes
406     static abstract class OPap<T> extends AbstractParallelAnyArray {
407     T[] array;
408     OPap(ForkJoinPool ex, int origin, int fence, T[] array) {
409     super(ex, origin, fence);
410     this.array = array;
411     }
412    
413     final Object[] ogetArray() { return this.array; }
414     double dget(int i) { return ((Number)oget(i)).doubleValue(); }
415     long lget(int i) { return ((Number)oget(i)).longValue(); }
416    
417     final void leafMoveByIndex(int[] indices, int loIdx,
418     int hiIdx, int offset) {
419     final Object[] array = this.array;
420     for (int i = loIdx; i < hiIdx; ++i)
421     array[offset++] = array[indices[i]];
422     }
423    
424     final int leafMoveSelected(int lo, int hi, int offset,
425     boolean positive) {
426     final Object[] array = this.array;
427     for (int i = lo; i < hi; ++i) {
428     if (isSelected(i) == positive)
429     array[offset++] = array[i];
430     }
431     return offset;
432     }
433     }
434    
435     // Base of double array classes
436     static abstract class DPap extends AbstractParallelAnyArray {
437     double[] array;
438     DPap(ForkJoinPool ex, int origin, int fence, double[] array) {
439     super(ex, origin, fence);
440     this.array = array;
441     }
442    
443     final double[] dgetArray() { return this.array; }
444     Object oget(int i) { return Double.valueOf(dget(i)); }
445     long lget(int i) { return (long)(dget(i)); }
446    
447     final void leafMoveByIndex(int[] indices, int loIdx,
448     int hiIdx, int offset) {
449     final double[] array = this.array;
450     for (int i = loIdx; i < hiIdx; ++i)
451     array[offset++] = array[indices[i]];
452     }
453    
454     final int leafMoveSelected(int lo, int hi, int offset,
455     boolean positive) {
456     final double[] array = this.array;
457     for (int i = lo; i < hi; ++i) {
458     if (isSelected(i) == positive)
459     array[offset++] = array[i];
460     }
461     return offset;
462     }
463     }
464    
465     // Base of long array classes
466     static abstract class LPap extends AbstractParallelAnyArray {
467     long[] array;
468     LPap(ForkJoinPool ex, int origin, int fence, long[] array) {
469     super(ex, origin, fence);
470     this.array = array;
471     }
472    
473     final long[] lgetArray() { return this.array; }
474     Object oget(int i) { return Long.valueOf(lget(i)); }
475     double dget(int i) { return (double)(lget(i)); }
476    
477     final void leafMoveByIndex(int[] indices, int loIdx,
478     int hiIdx, int offset) {
479     final long[] array = this.array;
480     for (int i = loIdx; i < hiIdx; ++i)
481     array[offset++] = array[indices[i]];
482     }
483    
484     final int leafMoveSelected(int lo, int hi, int offset,
485     boolean positive) {
486     final long[] array = this.array;
487     for (int i = lo; i < hi; ++i) {
488     if (isSelected(i) == positive)
489     array[offset++] = array[i];
490     }
491     return offset;
492     }
493     }
494    
495     // Plain (unfiltered, unmapped) classes
496     static class OUPap<T> extends ParallelArrayWithBounds<T> {
497     OUPap(ForkJoinPool ex, int origin, int fence, T[] array) {
498     super(ex, origin, fence, array);
499     }
500    
501     public ParallelArrayWithBounds<T> withBounds(int lo, int hi) {
502     boundsCheck(lo, hi);
503     return new OUPap<T>(ex, origin + lo, origin + hi, array);
504     }
505    
506     public ParallelArrayWithFilter<T> withFilter
507     (Predicate<? super T> selector) {
508     return new OFPap<T>(ex, origin, fence, array, selector);
509     }
510    
511     public ParallelArrayWithFilter<T> withIndexedFilter
512     (IntAndObjectPredicate<? super T> selector) {
513     return new ORPap<T>(ex, origin, fence, array, selector);
514     }
515    
516     public <U> ParallelArrayWithMapping<T, U> withMapping
517     (Op<? super T, ? extends U> op) {
518     return new OUOMPap<T,U>(ex, origin, fence, array, op);
519     }
520    
521     public ParallelArrayWithDoubleMapping<T> withMapping
522     (ObjectToDouble<? super T> op) {
523     return new OUDMPap<T>(ex, origin, fence, array, op);
524     }
525    
526     public ParallelArrayWithLongMapping<T> withMapping
527     (ObjectToLong<? super T> op) {
528     return new OULMPap<T>(ex, origin, fence, array, op);
529     }
530    
531     public <V> ParallelArrayWithMapping<T,V> withIndexedMapping
532     (IntAndObjectToObject<? super T, ? extends V> mapper) {
533     return new OUOCPap<T,V>(ex, origin, fence, array, mapper);
534     }
535    
536     public ParallelArrayWithDoubleMapping<T> withIndexedMapping
537     (IntAndObjectToDouble<? super T> mapper) {
538     return new OUDCPap<T>(ex, origin, fence, array, mapper);
539     }
540    
541     public ParallelArrayWithLongMapping<T> withIndexedMapping
542     (IntAndObjectToLong<? super T> mapper) {
543     return new OULCPap<T>(ex, origin, fence, array, mapper);
544     }
545    
546     public int indexOf(T target) {
547     AtomicInteger result = new AtomicInteger(-1);
548     PAS.FJOIndexOf f = new PAS.FJOIndexOf
549     (this, origin, fence, null, result, target);
550     ex.invoke(f);
551     return result.get();
552     }
553    
554     public int binarySearch(T target) {
555     final Object[] a = this.array;
556     int lo = origin;
557     int hi = fence - 1;
558     while (lo <= hi) {
559     int mid = (lo + hi) >>> 1;
560     int c = ((Comparable)target).compareTo((Comparable)a[mid]);
561     if (c == 0)
562     return mid;
563     else if (c < 0)
564     hi = mid - 1;
565     else
566     lo = mid + 1;
567     }
568     return -1;
569     }
570    
571     public int binarySearch(T target, Comparator<? super T> comparator) {
572     Comparator cmp = comparator;
573     final Object[] a = this.array;
574     int lo = origin;
575     int hi = fence - 1;
576     while (lo <= hi) {
577     int mid = (lo + hi) >>> 1;
578     int c = cmp.compare(target, a[mid]);
579     if (c == 0)
580     return mid;
581     else if (c < 0)
582     hi = mid - 1;
583     else
584     lo = mid + 1;
585     }
586     return -1;
587     }
588    
589     public ParallelArrayWithBounds<T> cumulate(Reducer<T> reducer, T base) {
590     PAS.FJOCumulateOp op = new PAS.FJOCumulateOp(this, reducer, base);
591     PAS.FJOScan r = new PAS.FJOScan(null, op, origin, fence);
592     ex.invoke(r);
593     return this;
594     }
595    
596     public T precumulate(Reducer<T> reducer, T base) {
597     PAS.FJOPrecumulateOp op = new PAS.FJOPrecumulateOp
598     (this, reducer, base);
599     PAS.FJOScan r = new PAS.FJOScan(null, op, origin, fence);
600     ex.invoke(r);
601     return (T)(r.out);
602     }
603    
604     public ParallelArrayWithBounds<T> sort
605     (Comparator<? super T> cmp) {
606     final Object[] a = this.array;
607     Class tc = array.getClass().getComponentType();
608     T[] ws = (T[])Array.newInstance(tc, fence);
609     ex.invoke(new PAS.FJOSorter
610     (cmp, array, ws, origin,
611     fence - origin, getThreshold()));
612     return this;
613     }
614    
615     public ParallelArrayWithBounds<T> sort() {
616     final Object[] a = this.array;
617     Class tc = array.getClass().getComponentType();
618     if (!Comparable.class.isAssignableFrom(tc)) {
619     sort(CommonOps.castedComparator());
620     }
621     else {
622     Comparable[] ca = (Comparable[])array;
623     Comparable[] ws = (Comparable[])Array.newInstance(tc, fence);
624     ex.invoke(new PAS.FJOCSorter
625     (ca, ws, origin,
626     fence - origin, getThreshold()));
627     }
628     return this;
629     }
630    
631     final void leafApply(int lo, int hi, Procedure procedure) {
632     final Object[] a = this.array;
633     for (int i = lo; i < hi; ++i)
634     procedure.op(a[i]);
635     }
636    
637     final Object leafReduce(int lo, int hi, Reducer reducer, Object base) {
638     if (lo >= hi)
639     return base;
640     final Object[] a = this.array;
641     Object r = a[lo];
642     for (int i = lo+1; i < hi; ++i)
643     r = reducer.op(r, a[i]);
644     return r;
645     }
646    
647     final void leafTransform(int l, int h, Op op) {
648     final Object[] a = this.array;
649     for (int i = l; i < h; ++i)
650     a[i] = op.op(a[i]);
651     }
652    
653     final void leafIndexMap(int l, int h, IntToObject op) {
654     final Object[] a = this.array;
655     for (int i = l; i < h; ++i)
656     a[i] = op.op(i);
657     }
658    
659     final void leafBinaryIndexMap(int l, int h, IntAndObjectToObject op) {
660     final Object[] a = this.array;
661     for (int i = l; i < h; ++i)
662     a[i] = op.op(i, a[i]);
663     }
664    
665     final void leafGenerate(int l, int h, Generator generator) {
666     final Object[] a = this.array;
667     for (int i = l; i < h; ++i)
668     a[i] = generator.op();
669     }
670    
671     final void leafFill(int l, int h, Object value) {
672     final Object[] a = this.array;
673     for (int i = l; i < h; ++i)
674     a[i] = value;
675     }
676    
677     final void leafCombineInPlace(int l, int h, Object[] other,
678     int otherOffset, BinaryOp combiner) {
679     final Object[] a = this.array;
680     int k = l + otherOffset;
681     for (int i = l; i < h; ++i)
682     a[i] = combiner.op(a[i], other[k++]);
683     }
684    
685     final void leafCombineInPlace(int l, int h,
686     ParallelArrayWithMapping other,
687     int otherOffset, BinaryOp combiner) {
688     final Object[] a = this.array;
689     int k = l + otherOffset;
690     if (other.hasFilter()) {
691     for (int i = l; i < h; ++i) {
692     if (other.isSelected(k))
693     a[i] = combiner.op(a[i], other.oget(k));
694     k++;
695     }
696     }
697     else if (other.hasMap()) {
698     for (int i = l; i < h; ++i)
699     a[i] = combiner.op(a[i], other.oget(k++));
700     }
701     else {
702     Object[] b = other.array;
703     for (int i = l; i < h; ++i)
704     a[i] = combiner.op(a[i], b[k++]);
705     }
706     }
707     }
708    
709     static class DUPap extends ParallelDoubleArrayWithBounds {
710     DUPap(ForkJoinPool ex, int origin, int fence, double[] array) {
711     super(ex, origin, fence, array);
712     }
713    
714     public ParallelDoubleArrayWithBounds withBounds(int lo, int hi) {
715     boundsCheck(lo, hi);
716     return new DUPap(ex, origin + lo, origin + hi, array);
717     }
718    
719     public ParallelDoubleArrayWithFilter withFilter(DoublePredicate selector) {
720     return new DFPap(ex, origin, fence, array, selector);
721     }
722    
723     public ParallelDoubleArrayWithFilter withIndexedFilter
724     (IntAndDoublePredicate selector) {
725     return new DRPap(ex, origin, fence, array, selector);
726     }
727    
728     public <U> ParallelDoubleArrayWithMapping<U> withMapping
729     (DoubleToObject<? extends U> op) {
730     return new DUOMPap<U>(ex, origin, fence, array, op);
731     }
732    
733     public ParallelDoubleArrayWithDoubleMapping withMapping(DoubleOp op) {
734     return new DUDMPap(ex, origin, fence, array, op);
735     }
736    
737     public ParallelDoubleArrayWithLongMapping withMapping(DoubleToLong op) {
738     return new DULMPap(ex, origin, fence, array, op);
739     }
740    
741     public <V> ParallelDoubleArrayWithMapping<V> withIndexedMapping
742     (IntAndDoubleToObject<? extends V> mapper) {
743     return new DUOCPap<V>(ex, origin, fence, array, mapper);
744     }
745    
746     public ParallelDoubleArrayWithDoubleMapping withIndexedMapping
747     (IntAndDoubleToDouble mapper) {
748     return new DUDCPap(ex, origin, fence, array, mapper);
749     }
750    
751     public ParallelDoubleArrayWithLongMapping withIndexedMapping
752     (IntAndDoubleToLong mapper) {
753     return new DULCPap(ex, origin, fence, array, mapper);
754     }
755    
756     public int indexOf(double target) {
757     AtomicInteger result = new AtomicInteger(-1);
758     PAS.FJDIndexOf f = new PAS.FJDIndexOf
759     (this, origin, fence, null, result, target);
760     ex.invoke(f);
761     return result.get();
762     }
763    
764     public int binarySearch(double target) {
765     final double[] a = this.array;
766     int lo = origin;
767     int hi = fence - 1;
768     while (lo <= hi) {
769     int mid = (lo + hi) >>> 1;
770     double m = a[mid];
771     if (target == m)
772     return mid;
773     else if (target < m)
774     hi = mid - 1;
775     else
776     lo = mid + 1;
777     }
778     return -1;
779     }
780    
781     public int binarySearch(double target, DoubleComparator comparator) {
782     final double[] a = this.array;
783     int lo = origin;
784     int hi = fence - 1;
785     while (lo <= hi) {
786     int mid = (lo + hi) >>> 1;
787     int c = comparator.compare(target, a[mid]);
788     if (c == 0)
789     return mid;
790     else if (c < 0)
791     hi = mid - 1;
792     else
793     lo = mid + 1;
794     }
795     return -1;
796     }
797    
798     public ParallelDoubleArrayWithBounds cumulate(DoubleReducer reducer,
799     double base) {
800     PAS.FJDCumulateOp op = new PAS.FJDCumulateOp(this, reducer, base);
801     PAS.FJDScan r = new PAS.FJDScan(null, op, origin, fence);
802     ex.invoke(r);
803     return this;
804     }
805    
806     public ParallelDoubleArrayWithBounds cumulateSum() {
807     PAS.FJDCumulatePlusOp op = new PAS.FJDCumulatePlusOp(this);
808     PAS.FJDScan r = new PAS.FJDScan(null, op, origin, fence);
809     ex.invoke(r);
810     return this;
811     }
812    
813     public double precumulate(DoubleReducer reducer, double base) {
814     PAS.FJDPrecumulateOp op = new PAS.FJDPrecumulateOp(this, reducer, base);
815     PAS.FJDScan r = new PAS.FJDScan(null, op, origin, fence);
816     ex.invoke(r);
817     return r.out;
818     }
819    
820     public double precumulateSum() {
821     PAS.FJDPrecumulatePlusOp op = new PAS.FJDPrecumulatePlusOp(this);
822     PAS.FJDScan r = new PAS.FJDScan(null, op, origin, fence);
823     ex.invoke(r);
824     return r.out;
825     }
826    
827     public ParallelDoubleArrayWithBounds sort(DoubleComparator cmp) {
828     ex.invoke(new PAS.FJDSorter
829     (cmp, this.array, new double[fence],
830     origin, fence - origin, getThreshold()));
831     return this;
832     }
833    
834     public ParallelDoubleArrayWithBounds sort() {
835     ex.invoke(new PAS.FJDCSorter
836     (this.array, new double[fence],
837     origin, fence - origin, getThreshold()));
838     return this;
839     }
840    
841     final void leafApply(int lo, int hi, DoubleProcedure procedure) {
842     final double[] a = this.array;
843     for (int i = lo; i < hi; ++i)
844     procedure.op(a[i]);
845     }
846    
847     final double leafReduce(int lo, int hi, DoubleReducer reducer,
848     double base) {
849     if (lo >= hi)
850     return base;
851     final double[] a = this.array;
852     double r = a[lo];
853     for (int i = lo+1; i < hi; ++i)
854     r = reducer.op(r, a[i]);
855     return r;
856     }
857    
858     final void leafTransform(int l, int h, DoubleOp op) {
859     final double[] a = this.array;
860     for (int i = l; i < h; ++i)
861     a[i] = op.op(a[i]);
862     }
863    
864     final void leafIndexMap(int l, int h, IntToDouble op) {
865     final double[] a = this.array;
866     for (int i = l; i < h; ++i)
867     a[i] = op.op(i);
868     }
869    
870     final void leafBinaryIndexMap(int l, int h, IntAndDoubleToDouble op) {
871     final double[] a = this.array;
872     for (int i = l; i < h; ++i)
873     a[i] = op.op(i, a[i]);
874     }
875    
876     final void leafGenerate(int l, int h, DoubleGenerator generator) {
877     final double[] a = this.array;
878     for (int i = l; i < h; ++i)
879     a[i] = generator.op();
880     }
881    
882     final void leafFill(int l, int h, double value) {
883     final double[] a = this.array;
884     for (int i = l; i < h; ++i)
885     a[i] = value;
886     }
887    
888     final void leafCombineInPlace
889     (int l, int h, double[] other,
890     int otherOffset, BinaryDoubleOp combiner) {
891     final double[] a = this.array;
892     int k = l + otherOffset;
893     for (int i = l; i < h; ++i)
894     a[i] = combiner.op(a[i], other[k++]);
895     }
896    
897     final void leafCombineInPlace
898     (int l, int h,
899     ParallelDoubleArrayWithDoubleMapping other,
900     int otherOffset, BinaryDoubleOp combiner) {
901     final double[] a = this.array;
902     int k = l + otherOffset;
903     if (other.hasFilter()) {
904     for (int i = l; i < h; ++i) {
905     if (other.isSelected(k))
906     a[i] = combiner.op(a[i], other.dget(k));
907     k++;
908     }
909     }
910     else if (other.hasMap()) {
911     for (int i = l; i < h; ++i)
912     a[i] = combiner.op(a[i], other.dget(k++));
913     }
914     else {
915     double[] b = other.array;
916     for (int i = l; i < h; ++i)
917     a[i] = combiner.op(a[i], b[k++]);
918     }
919    
920     }
921     }
922    
923     static class LUPap extends ParallelLongArrayWithBounds {
924     LUPap(ForkJoinPool ex, int origin, int fence,
925     long[] array) {
926     super(ex, origin, fence, array);
927     }
928    
929     public ParallelLongArrayWithBounds withBounds(int lo, int hi) {
930     boundsCheck(lo, hi);
931     return new LUPap(ex, origin + lo, origin + hi, array);
932     }
933    
934     public ParallelLongArrayWithFilter withFilter(LongPredicate selector) {
935     return new LFPap(ex, origin, fence, array, selector);
936     }
937    
938     public ParallelLongArrayWithFilter withIndexedFilter
939     (IntAndLongPredicate selector) {
940     return new LRPap(ex, origin, fence, array, selector);
941     }
942    
943     public <U> ParallelLongArrayWithMapping<U> withMapping
944     (LongToObject<? extends U> op) {
945     return new LUOMPap<U>(ex, origin, fence, array, op);
946     }
947    
948     public ParallelLongArrayWithLongMapping withMapping(LongOp op) {
949     return new LULMPap(ex, origin, fence, array, op);
950     }
951    
952     public ParallelLongArrayWithDoubleMapping withMapping(LongToDouble op) {
953     return new LUDMPap(ex, origin, fence, array, op);
954     }
955    
956     public <V> ParallelLongArrayWithMapping<V> withIndexedMapping
957     (IntAndLongToObject<? extends V> mapper) {
958     return new LUOCPap<V>(ex, origin, fence, array, mapper);
959     }
960    
961     public ParallelLongArrayWithDoubleMapping withIndexedMapping
962     (IntAndLongToDouble mapper) {
963     return new LUDCPap(ex, origin, fence, array, mapper);
964     }
965    
966     public ParallelLongArrayWithLongMapping withIndexedMapping
967     (IntAndLongToLong mapper) {
968     return new LULCPap(ex, origin, fence, array, mapper);
969     }
970    
971     public int indexOf(long target) {
972     AtomicInteger result = new AtomicInteger(-1);
973     PAS.FJLIndexOf f = new PAS.FJLIndexOf
974     (this, origin, fence, null, result, target);
975     ex.invoke(f);
976     return result.get();
977     }
978    
979     public int binarySearch(long target) {
980     final long[] a = this.array;
981     int lo = origin;
982     int hi = fence - 1;
983     while (lo <= hi) {
984     int mid = (lo + hi) >>> 1;
985     long m = a[mid];
986     if (target == m)
987     return mid;
988     else if (target < m)
989     hi = mid - 1;
990     else
991     lo = mid + 1;
992     }
993     return -1;
994     }
995    
996     public int binarySearch(long target, LongComparator comparator) {
997     final long[] a = this.array;
998     int lo = origin;
999     int hi = fence - 1;
1000     while (lo <= hi) {
1001     int mid = (lo + hi) >>> 1;
1002     int c = comparator.compare(target, a[mid]);
1003     if (c == 0)
1004     return mid;
1005     else if (c < 0)
1006     hi = mid - 1;
1007     else
1008     lo = mid + 1;
1009     }
1010     return -1;
1011     }
1012    
1013     public ParallelLongArrayWithBounds cumulate(LongReducer reducer, long base) {
1014     PAS.FJLCumulateOp op = new PAS.FJLCumulateOp(this, reducer, base);
1015     PAS.FJLScan r = new PAS.FJLScan(null, op, origin, fence);
1016     ex.invoke(r);
1017     return this;
1018     }
1019    
1020     public ParallelLongArrayWithBounds cumulateSum() {
1021     PAS.FJLCumulatePlusOp op = new PAS.FJLCumulatePlusOp(this);
1022     PAS.FJLScan r = new PAS.FJLScan(null, op, origin, fence);
1023     ex.invoke(r);
1024     return this;
1025     }
1026    
1027     public long precumulate(LongReducer reducer, long base) {
1028     PAS.FJLPrecumulateOp op = new PAS.FJLPrecumulateOp
1029     (this, reducer, base);
1030     PAS.FJLScan r = new PAS.FJLScan(null, op, origin, fence);
1031     ex.invoke(r);
1032     return r.out;
1033     }
1034    
1035     public long precumulateSum() {
1036     PAS.FJLPrecumulatePlusOp op = new PAS.FJLPrecumulatePlusOp(this);
1037     PAS.FJLScan r = new PAS.FJLScan(null, op, origin, fence);
1038     ex.invoke(r);
1039     return r.out;
1040     }
1041    
1042     public ParallelLongArrayWithBounds sort(LongComparator cmp) {
1043     ex.invoke(new PAS.FJLSorter
1044     (cmp, this.array, new long[fence],
1045     origin, fence - origin, getThreshold()));
1046     return this;
1047     }
1048    
1049     public ParallelLongArrayWithBounds sort() {
1050     ex.invoke(new PAS.FJLCSorter
1051     (this.array, new long[fence],
1052     origin, fence - origin, getThreshold()));
1053     return this;
1054     }
1055    
1056     final void leafApply(int lo, int hi, LongProcedure procedure) {
1057     final long[] a = this.array;
1058     for (int i = lo; i < hi; ++i)
1059     procedure.op(a[i]);
1060     }
1061    
1062     final long leafReduce(int lo, int hi, LongReducer reducer, long base) {
1063     if (lo >= hi)
1064     return base;
1065     final long[] a = this.array;
1066     long r = a[lo];
1067     for (int i = lo+1; i < hi; ++i)
1068     r = reducer.op(r, a[i]);
1069     return r;
1070     }
1071    
1072     final void leafTransform(int l, int h, LongOp op) {
1073     final long[] a = this.array;
1074     for (int i = l; i < h; ++i)
1075     a[i] = op.op(a[i]);
1076     }
1077    
1078     final void leafIndexMap(int l, int h, IntToLong op) {
1079     final long[] a = this.array;
1080     for (int i = l; i < h; ++i)
1081     a[i] = op.op(i);
1082     }
1083    
1084     final void leafBinaryIndexMap(int l, int h, IntAndLongToLong op) {
1085     final long[] a = this.array;
1086     for (int i = l; i < h; ++i)
1087     a[i] = op.op(i, a[i]);
1088     }
1089    
1090     final void leafGenerate(int l, int h, LongGenerator generator) {
1091     final long[] a = this.array;
1092     for (int i = l; i < h; ++i)
1093     a[i] = generator.op();
1094     }
1095    
1096     final void leafFill(int l, int h, long value) {
1097     final long[] a = this.array;
1098     for (int i = l; i < h; ++i)
1099     a[i] = value;
1100     }
1101    
1102     final void leafCombineInPlace
1103     (int l, int h, long[] other,
1104     int otherOffset, BinaryLongOp combiner) {
1105     final long[] a = this.array;
1106     int k = l + otherOffset;
1107     for (int i = l; i < h; ++i)
1108     a[i] = combiner.op(a[i], other[k++]);
1109     }
1110    
1111     final void leafCombineInPlace
1112     (int l, int h,
1113     ParallelLongArrayWithLongMapping other,
1114     int otherOffset, BinaryLongOp combiner) {
1115     final long[] a = this.array;
1116     int k = l + otherOffset;
1117     if (other.hasFilter()) {
1118     for (int i = l; i < h; ++i) {
1119     if (other.isSelected(k))
1120     a[i] = combiner.op(a[i], other.lget(k));
1121     k++;
1122     }
1123     }
1124     else if (other.hasMap()) {
1125     for (int i = l; i < h; ++i)
1126     a[i] = combiner.op(a[i], other.lget(k++));
1127     }
1128     else {
1129     long[] b = other.array;
1130     for (int i = l; i < h; ++i)
1131     a[i] = combiner.op(a[i], b[k++]);
1132     }
1133     }
1134     }
1135    
1136 dl 1.7 static final class AndPredicate<T> implements Predicate<T> {
1137     final Predicate<? super T> first;
1138     final Predicate<? super T> second;
1139 jsr166 1.8 AndPredicate(Predicate<? super T> first,
1140 dl 1.7 Predicate<? super T> second) {
1141     this.first = first; this.second = second;
1142     }
1143     public final boolean op(T x) { return first.op(x) && second.op(x); }
1144     }
1145    
1146 dl 1.1 // Filtered (but unmapped) classes
1147     static final class OFPap<T> extends ParallelArrayWithFilter<T> {
1148     final Predicate<? super T> selector;
1149     OFPap(ForkJoinPool ex, int origin, int fence,
1150     T[] array,
1151     Predicate<? super T> selector) {
1152     super(ex, origin, fence, array);
1153     this.selector = selector;
1154     }
1155    
1156     boolean hasFilter() { return true; }
1157     boolean isSelected(int i) { return selector.op(this.array[i]); }
1158    
1159     public ParallelArrayWithFilter<T> withFilter
1160     (Predicate<? super T> selector) {
1161     return new OFPap<T>(ex, origin, fence, array,
1162 dl 1.7 new AndPredicate(this.selector, selector));
1163 dl 1.1 }
1164    
1165     public ParallelArrayWithFilter<T> withIndexedFilter
1166     (IntAndObjectPredicate<? super T> selector) {
1167     return new ORPap<T>
1168     (ex, origin, fence, array,
1169     compoundIndexedSelector(this.selector, selector));
1170     }
1171    
1172     public <U> ParallelArrayWithMapping<T, U> withMapping
1173     (Op<? super T, ? extends U> op) {
1174     return new OFOMPap<T,U>(ex, origin, fence, array, selector, op);
1175     }
1176    
1177     public ParallelArrayWithDoubleMapping<T> withMapping
1178     (ObjectToDouble<? super T> op) {
1179     return new OFDMPap<T>(ex, origin, fence, array, selector, op);
1180     }
1181    
1182     public ParallelArrayWithLongMapping<T> withMapping
1183     (ObjectToLong<? super T> op) {
1184     return new OFLMPap<T>(ex, origin, fence, array, selector, op);
1185     }
1186    
1187     public <V> ParallelArrayWithMapping<T,V> withIndexedMapping
1188     (IntAndObjectToObject<? super T, ? extends V> mapper) {
1189     return new OFOCPap<T,V>(ex, origin, fence, array, selector, mapper);
1190     }
1191    
1192     public ParallelArrayWithDoubleMapping<T> withIndexedMapping
1193     (IntAndObjectToDouble<? super T> mapper) {
1194     return new OFDCPap<T>(ex, origin, fence, array, selector, mapper);
1195     }
1196    
1197     public ParallelArrayWithLongMapping<T> withIndexedMapping
1198     (IntAndObjectToLong<? super T> mapper) {
1199     return new OFLCPap<T>(ex, origin, fence, array, selector, mapper);
1200     }
1201    
1202     void leafApply(int lo, int hi, Procedure procedure) {
1203     final Predicate s = selector;
1204     final Object[] a = this.array;
1205     for (int i = lo; i < hi; ++i) {
1206     Object x = a[i];
1207     if (s.op(x))
1208     procedure.op(x);
1209     }
1210     }
1211    
1212     Object leafReduce(int lo, int hi, Reducer reducer, Object base) {
1213     final Predicate s = selector;
1214     boolean gotFirst = false;
1215     Object r = base;
1216     final Object[] a = this.array;
1217     for (int i = lo; i < hi; ++i) {
1218     Object x = a[i];
1219     if (s.op(x)) {
1220     if (!gotFirst) {
1221     gotFirst = true;
1222     r = x;
1223     }
1224     else
1225     r = reducer.op(r, x);
1226     }
1227     }
1228     return r;
1229     }
1230    
1231     final void leafTransform(int l, int h, Op op) {
1232     final Object[] a = this.array;
1233     final Predicate s = selector;
1234     for (int i = l; i < h; ++i) {
1235     Object x = a[i];
1236     if (s.op(x))
1237     a[i] = op.op(x);
1238     }
1239     }
1240    
1241     final void leafIndexMap(int l, int h, IntToObject op) {
1242     final Object[] a = this.array;
1243     final Predicate s = selector;
1244     for (int i = l; i < h; ++i) {
1245     Object x = a[i];
1246     if (s.op(x))
1247     a[i] = op.op(i);
1248     }
1249     }
1250    
1251     final void leafBinaryIndexMap(int l, int h, IntAndObjectToObject op) {
1252     final Object[] a = this.array;
1253     final Predicate s = selector;
1254     for (int i = l; i < h; ++i) {
1255     Object x = a[i];
1256     if (s.op(x))
1257     a[i] = op.op(i, x);
1258     }
1259     }
1260    
1261     final void leafGenerate(int l, int h, Generator generator) {
1262     final Object[] a = this.array;
1263     final Predicate s = selector;
1264     for (int i = l; i < h; ++i) {
1265     if (s.op(a[i]))
1266     a[i] = generator.op();
1267     }
1268     }
1269    
1270     final void leafFill(int l, int h, Object value) {
1271     final Object[] a = this.array;
1272     final Predicate s = selector;
1273     for (int i = l; i < h; ++i) {
1274     if (s.op(a[i]))
1275     a[i] = value;
1276     }
1277     }
1278    
1279     final void leafCombineInPlace
1280     (int l, int h, Object[] other,
1281     int otherOffset, BinaryOp combiner) {
1282     final Object[] a = this.array;
1283     final Predicate s = selector;
1284     int k = l + otherOffset;
1285     for (int i = l; i < h; ++i) {
1286     Object x = a[i];
1287     if (s.op(x))
1288     a[i] = combiner.op(x, other[k]);
1289     k++;
1290     }
1291     }
1292    
1293     final void leafCombineInPlace
1294     (int l, int h,
1295     ParallelArrayWithMapping other,
1296     int otherOffset, BinaryOp combiner) {
1297     final Object[] a = this.array;
1298     final Predicate s = selector;
1299     int k = l + otherOffset;
1300     if (other.hasFilter()) {
1301     for (int i = l; i < h; ++i) {
1302     Object x = a[i];
1303     if (s.op(x) && other.isSelected(k))
1304     a[i] = combiner.op(x, other.oget(k));
1305     k++;
1306     }
1307     }
1308     else if (other.hasMap()) {
1309     for (int i = l; i < h; ++i) {
1310     Object x = a[i];
1311     if (s.op(x))
1312     a[i] = combiner.op(x, other.oget(k));
1313     k++;
1314     }
1315     }
1316     else {
1317     Object[] b = other.array;
1318     for (int i = l; i < h; ++i) {
1319     Object x = a[i];
1320     if (s.op(x))
1321     a[i] = combiner.op(x, b[k]);
1322     k++;
1323     }
1324     }
1325     }
1326     }
1327    
1328     static final class DFPap extends ParallelDoubleArrayWithFilter {
1329     final DoublePredicate selector;
1330     DFPap(ForkJoinPool ex, int origin, int fence,
1331     double[] array,
1332     DoublePredicate selector) {
1333     super(ex, origin, fence, array);
1334     this.selector = selector;
1335     }
1336    
1337     boolean hasFilter() { return true; }
1338     boolean isSelected(int i) { return selector.op(this.array[i]); }
1339    
1340     public ParallelDoubleArrayWithFilter withFilter(DoublePredicate selector) {
1341     return new DFPap(ex, origin, fence, array,
1342     CommonOps.andPredicate(this.selector, selector));
1343     }
1344    
1345     public ParallelDoubleArrayWithFilter withIndexedFilter
1346     (IntAndDoublePredicate selector) {
1347     return new DRPap
1348     (ex, origin, fence, array,
1349     compoundIndexedSelector(this.selector, selector));
1350     }
1351    
1352     public <U> ParallelDoubleArrayWithMapping<U> withMapping
1353     (DoubleToObject<? extends U> op) {
1354     return new DFOMPap<U>(ex, origin, fence, array, selector, op);
1355     }
1356    
1357     public ParallelDoubleArrayWithDoubleMapping withMapping(DoubleOp op) {
1358     return new DFDMPap(ex, origin, fence, array, selector, op);
1359     }
1360    
1361     public ParallelDoubleArrayWithLongMapping withMapping(DoubleToLong op) {
1362     return new DFLMPap(ex, origin, fence, array, selector, op);
1363     }
1364    
1365     public <V> ParallelDoubleArrayWithMapping<V> withIndexedMapping
1366     (IntAndDoubleToObject<? extends V> mapper) {
1367     return new DFOCPap<V>(ex, origin, fence, array, selector, mapper);
1368     }
1369    
1370     public ParallelDoubleArrayWithDoubleMapping withIndexedMapping
1371     (IntAndDoubleToDouble mapper) {
1372     return new DFDCPap(ex, origin, fence, array, selector, mapper);
1373     }
1374    
1375     public ParallelDoubleArrayWithLongMapping withIndexedMapping
1376     (IntAndDoubleToLong mapper) {
1377     return new DFLCPap(ex, origin, fence, array, selector, mapper);
1378     }
1379    
1380     final void leafApply(int lo, int hi, DoubleProcedure procedure) {
1381     final DoublePredicate s = selector;
1382     final double[] a = this.array;
1383     for (int i = lo; i < hi; ++i) {
1384     double x = a[i];
1385     if (s.op(x))
1386     procedure.op(x);
1387     }
1388     }
1389    
1390     final double leafReduce(int lo, int hi, DoubleReducer reducer, double base) {
1391     final DoublePredicate s = selector;
1392     boolean gotFirst = false;
1393     double r = base;
1394     final double[] a = this.array;
1395     for (int i = lo; i < hi; ++i) {
1396     double x = a[i];
1397     if (s.op(x)) {
1398     if (!gotFirst) {
1399     gotFirst = true;
1400     r = x;
1401     }
1402     else
1403     r = reducer.op(r, x);
1404     }
1405     }
1406     return r;
1407     }
1408    
1409     final void leafTransform(int l, int h, DoubleOp op) {
1410     final double[] a = this.array;
1411     final DoublePredicate s = selector;
1412     for (int i = l; i < h; ++i) {
1413     double x = a[i];
1414     if (s.op(x))
1415     a[i] = op.op(x);
1416     }
1417     }
1418    
1419     final void leafIndexMap(int l, int h, IntToDouble op) {
1420     final double[] a = this.array;
1421     final DoublePredicate s = selector;
1422     for (int i = l; i < h; ++i) {
1423     double x = a[i];
1424     if (s.op(x))
1425     a[i] = op.op(i);
1426     }
1427     }
1428    
1429     final void leafBinaryIndexMap(int l, int h, IntAndDoubleToDouble op) {
1430     final double[] a = this.array;
1431     final DoublePredicate s = selector;
1432     for (int i = l; i < h; ++i) {
1433     double x = a[i];
1434     if (s.op(x))
1435     a[i] = op.op(i, x);
1436     }
1437     }
1438    
1439     final void leafGenerate(int l, int h, DoubleGenerator generator) {
1440     final double[] a = this.array;
1441     final DoublePredicate s = selector;
1442     for (int i = l; i < h; ++i) {
1443     if (s.op(a[i]))
1444     a[i] = generator.op();
1445     }
1446     }
1447    
1448     final void leafFill(int l, int h, double value) {
1449     final double[] a = this.array;
1450     final DoublePredicate s = selector;
1451     for (int i = l; i < h; ++i) {
1452     if (s.op(a[i]))
1453     a[i] = value;
1454     }
1455     }
1456    
1457     final void leafCombineInPlace
1458     (int l, int h, double[] other,
1459     int otherOffset, BinaryDoubleOp combiner) {
1460     final double[] a = this.array;
1461     final DoublePredicate s = selector;
1462     int k = l + otherOffset;
1463     for (int i = l; i < h; ++i) {
1464     double x = a[i];
1465     if (s.op(x))
1466     a[i] = combiner.op(x, other[k]);
1467     k++;
1468     }
1469     }
1470    
1471     final void leafCombineInPlace
1472     (int l, int h,
1473     ParallelDoubleArrayWithDoubleMapping other,
1474     int otherOffset, BinaryDoubleOp combiner) {
1475     final double[] a = this.array;
1476     final DoublePredicate s = selector;
1477     int k = l + otherOffset;
1478     if (other.hasFilter()) {
1479     for (int i = l; i < h; ++i) {
1480     double x = a[i];
1481     if (s.op(x) && other.isSelected(k))
1482     a[i] = combiner.op(x, other.dget(k));
1483     k++;
1484     }
1485     }
1486     else if (other.hasMap()) {
1487     for (int i = l; i < h; ++i) {
1488     double x = a[i];
1489     if (s.op(x))
1490     a[i] = combiner.op(x, other.dget(k));
1491     k++;
1492     }
1493     }
1494     else {
1495     double[] b = other.array;
1496     for (int i = l; i < h; ++i) {
1497     double x = a[i];
1498     if (s.op(x))
1499     a[i] = combiner.op(x, b[k]);
1500     k++;
1501     }
1502     }
1503     }
1504     }
1505    
1506     static final class LFPap extends ParallelLongArrayWithFilter {
1507     final LongPredicate selector;
1508     LFPap(ForkJoinPool ex, int origin, int fence,
1509     long[] array,
1510     LongPredicate selector) {
1511     super(ex, origin, fence, array);
1512     this.selector = selector;
1513     }
1514    
1515     boolean hasFilter() { return true; }
1516     boolean isSelected(int i) { return selector.op(this.array[i]); }
1517    
1518     public ParallelLongArrayWithFilter withFilter(LongPredicate selector) {
1519     return new LFPap(ex, origin, fence, array,
1520     CommonOps.andPredicate(this.selector, selector));
1521     }
1522    
1523     public ParallelLongArrayWithFilter withIndexedFilter
1524     (IntAndLongPredicate selector) {
1525     return new LRPap
1526     (ex, origin, fence, array,
1527     compoundIndexedSelector(this.selector, selector));
1528     }
1529    
1530     public <U> ParallelLongArrayWithMapping<U> withMapping
1531     (LongToObject<? extends U> op) {
1532     return new LFOMPap<U>(ex, origin, fence, array, selector, op);
1533     }
1534    
1535     public ParallelLongArrayWithLongMapping withMapping
1536     (LongOp op) {
1537     return new LFLMPap(ex, origin, fence, array, selector, op);
1538     }
1539    
1540     public ParallelLongArrayWithDoubleMapping withMapping
1541     (LongToDouble op) {
1542     return new LFDMPap(ex, origin, fence, array, selector, op);
1543     }
1544    
1545     public <V> ParallelLongArrayWithMapping<V> withIndexedMapping
1546     (IntAndLongToObject<? extends V> mapper) {
1547     return new LFOCPap<V>(ex, origin, fence, array, selector, mapper);
1548     }
1549    
1550     public ParallelLongArrayWithDoubleMapping withIndexedMapping
1551     (IntAndLongToDouble mapper) {
1552     return new LFDCPap(ex, origin, fence, array, selector, mapper);
1553     }
1554    
1555     public ParallelLongArrayWithLongMapping withIndexedMapping
1556     (IntAndLongToLong mapper) {
1557     return new LFLCPap(ex, origin, fence, array, selector, mapper);
1558     }
1559    
1560     final void leafApply(int lo, int hi, LongProcedure procedure) {
1561     final LongPredicate s = selector;
1562     final long[] a = this.array;
1563     for (int i = lo; i < hi; ++i) {
1564     long x = a[i];
1565     if (s.op(x))
1566     procedure.op(x);
1567     }
1568     }
1569    
1570     final long leafReduce(int lo, int hi, LongReducer reducer, long base) {
1571     final LongPredicate s = selector;
1572     boolean gotFirst = false;
1573     long r = base;
1574     final long[] a = this.array;
1575     for (int i = lo; i < hi; ++i) {
1576     long x = a[i];
1577     if (s.op(x)) {
1578     if (!gotFirst) {
1579     gotFirst = true;
1580     r = x;
1581     }
1582     else
1583     r = reducer.op(r, x);
1584     }
1585     }
1586     return r;
1587     }
1588    
1589     final void leafTransform(int l, int h, LongOp op) {
1590     final long[] a = this.array;
1591     final LongPredicate s = selector;
1592     for (int i = l; i < h; ++i) {
1593     long x = a[i];
1594     if (s.op(x))
1595     a[i] = op.op(x);
1596     }
1597     }
1598    
1599     final void leafIndexMap(int l, int h, IntToLong op) {
1600     final long[] a = this.array;
1601     final LongPredicate s = selector;
1602     for (int i = l; i < h; ++i) {
1603     long x = a[i];
1604     if (s.op(x))
1605     a[i] = op.op(i);
1606     }
1607     }
1608    
1609     final void leafBinaryIndexMap(int l, int h, IntAndLongToLong op) {
1610     final long[] a = this.array;
1611     final LongPredicate s = selector;
1612     for (int i = l; i < h; ++i) {
1613     long x = a[i];
1614     if (s.op(x))
1615     a[i] = op.op(i, x);
1616     }
1617     }
1618    
1619     final void leafGenerate(int l, int h, LongGenerator generator) {
1620     final long[] a = this.array;
1621     final LongPredicate s = selector;
1622     for (int i = l; i < h; ++i) {
1623     if (s.op(a[i]))
1624     a[i] = generator.op();
1625     }
1626     }
1627    
1628     final void leafFill(int l, int h, long value) {
1629     final long[] a = this.array;
1630     final LongPredicate s = selector;
1631     for (int i = l; i < h; ++i) {
1632     if (s.op(a[i]))
1633     a[i] = value;
1634     }
1635     }
1636    
1637     final void leafCombineInPlace
1638     (int l, int h, long[] other,
1639     int otherOffset, BinaryLongOp combiner) {
1640     final long[] a = this.array;
1641     final LongPredicate s = selector;
1642     int k = l + otherOffset;
1643     for (int i = l; i < h; ++i) {
1644     long x = a[i];
1645     if (s.op(x))
1646     a[i] = combiner.op(x, other[k]);
1647     k++;
1648     }
1649     }
1650    
1651     final void leafCombineInPlace
1652     (int l, int h,
1653     ParallelLongArrayWithLongMapping other,
1654     int otherOffset, BinaryLongOp combiner) {
1655     final long[] a = this.array;
1656     final LongPredicate s = selector;
1657     int k = l + otherOffset;
1658     if (other.hasFilter()) {
1659     for (int i = l; i < h; ++i) {
1660     long x = a[i];
1661     if (s.op(x) && other.isSelected(k))
1662     a[i] = combiner.op(x, other.lget(k));
1663     k++;
1664     }
1665     }
1666     else if (other.hasMap()) {
1667     for (int i = l; i < h; ++i) {
1668     long x = a[i];
1669     if (s.op(x))
1670     a[i] = combiner.op(x, other.lget(k));
1671     k++;
1672     }
1673     }
1674     else {
1675     long[] b = other.array;
1676     for (int i = l; i < h; ++i) {
1677     long x = a[i];
1678     if (s.op(x))
1679     a[i] = combiner.op(x, b[k]);
1680     k++;
1681     }
1682     }
1683     }
1684     }
1685    
1686     // Relationally Filtered (but unmapped) classes
1687     static final class ORPap<T> extends ParallelArrayWithFilter<T> {
1688     final IntAndObjectPredicate<? super T> selector;
1689     ORPap(ForkJoinPool ex, int origin, int fence,
1690     T[] array,
1691     IntAndObjectPredicate<? super T> selector) {
1692     super(ex, origin, fence, array);
1693     this.selector = selector;
1694     }
1695    
1696     boolean hasFilter() { return true; }
1697     boolean isSelected(int i) { return selector.op(i, this.array[i]); }
1698    
1699     public ParallelArrayWithFilter<T> withFilter
1700     (Predicate<? super T> selector) {
1701     return new ORPap<T>
1702     (ex, origin, fence, array,
1703     compoundIndexedSelector(this.selector, selector));
1704     }
1705    
1706     public ParallelArrayWithFilter<T> withIndexedFilter
1707     (IntAndObjectPredicate<? super T> selector) {
1708     return new ORPap<T>
1709     (ex, origin, fence, array,
1710     compoundIndexedSelector(this.selector, selector));
1711     }
1712    
1713     public <U> ParallelArrayWithMapping<T, U> withMapping
1714     (Op<? super T, ? extends U> op) {
1715     return new OROMPap<T,U>(ex, origin, fence, array, selector, op);
1716     }
1717    
1718     public ParallelArrayWithDoubleMapping<T> withMapping
1719     (ObjectToDouble<? super T> op) {
1720     return new ORDMPap<T>(ex, origin, fence, array, selector, op);
1721     }
1722    
1723     public ParallelArrayWithLongMapping<T> withMapping
1724     (ObjectToLong<? super T> op) {
1725     return new ORLMPap<T>(ex, origin, fence, array, selector, op);
1726     }
1727    
1728     public <V> ParallelArrayWithMapping<T,V> withIndexedMapping
1729     (IntAndObjectToObject<? super T, ? extends V> mapper) {
1730     return new OROCPap<T,V>(ex, origin, fence, array, selector, mapper);
1731     }
1732    
1733     public ParallelArrayWithDoubleMapping<T> withIndexedMapping
1734     (IntAndObjectToDouble<? super T> mapper) {
1735     return new ORDCPap<T>(ex, origin, fence, array, selector, mapper);
1736     }
1737    
1738     public ParallelArrayWithLongMapping<T> withIndexedMapping
1739     (IntAndObjectToLong<? super T> mapper) {
1740     return new ORLCPap<T>(ex, origin, fence, array, selector, mapper);
1741     }
1742    
1743     void leafApply(int lo, int hi, Procedure procedure) {
1744     final IntAndObjectPredicate s = selector;
1745     final Object[] a = this.array;
1746     for (int i = lo; i < hi; ++i) {
1747     Object x = a[i];
1748     if (s.op(i, x))
1749     procedure.op(x);
1750     }
1751     }
1752    
1753     Object leafReduce(int lo, int hi, Reducer reducer, Object base) {
1754     final IntAndObjectPredicate s = selector;
1755     boolean gotFirst = false;
1756     Object r = base;
1757     final Object[] a = this.array;
1758     for (int i = lo; i < hi; ++i) {
1759     Object x = a[i];
1760     if (s.op(i, x)) {
1761     if (!gotFirst) {
1762     gotFirst = true;
1763     r = x;
1764     }
1765     else
1766     r = reducer.op(r, x);
1767     }
1768     }
1769     return r;
1770     }
1771    
1772     final void leafTransform(int l, int h, Op op) {
1773     final Object[] a = this.array;
1774     final IntAndObjectPredicate s = selector;
1775     for (int i = l; i < h; ++i) {
1776     Object x = a[i];
1777     if (s.op(i, x))
1778     a[i] = op.op(x);
1779     }
1780     }
1781    
1782     final void leafIndexMap(int l, int h, IntToObject op) {
1783     final Object[] a = this.array;
1784     final IntAndObjectPredicate s = selector;
1785     for (int i = l; i < h; ++i) {
1786     Object x = a[i];
1787     if (s.op(i, x))
1788     a[i] = op.op(i);
1789     }
1790     }
1791    
1792     final void leafBinaryIndexMap(int l, int h, IntAndObjectToObject op) {
1793     final Object[] a = this.array;
1794     final IntAndObjectPredicate s = selector;
1795     for (int i = l; i < h; ++i) {
1796     Object x = a[i];
1797     if (s.op(i, x))
1798     a[i] = op.op(i, x);
1799     }
1800     }
1801    
1802     final void leafGenerate(int l, int h, Generator generator) {
1803     final Object[] a = this.array;
1804     final IntAndObjectPredicate s = selector;
1805     for (int i = l; i < h; ++i) {
1806     if (s.op(i, a[i]))
1807     a[i] = generator.op();
1808     }
1809     }
1810    
1811     final void leafFill(int l, int h, Object value) {
1812     final Object[] a = this.array;
1813     final IntAndObjectPredicate s = selector;
1814     for (int i = l; i < h; ++i) {
1815     if (s.op(i, a[i]))
1816     a[i] = value;
1817     }
1818     }
1819    
1820     final void leafCombineInPlace
1821     (int l, int h, Object[] other,
1822     int otherOffset, BinaryOp combiner) {
1823     final Object[] a = this.array;
1824     final IntAndObjectPredicate s = selector;
1825     int k = l + otherOffset;
1826     for (int i = l; i < h; ++i) {
1827     Object x = a[i];
1828     if (s.op(i, x))
1829     a[i] = combiner.op(x, other[k]);
1830     k++;
1831     }
1832     }
1833    
1834     final void leafCombineInPlace
1835     (int l, int h,
1836     ParallelArrayWithMapping other,
1837     int otherOffset, BinaryOp combiner) {
1838     final Object[] a = this.array;
1839     final IntAndObjectPredicate s = selector;
1840     int k = l + otherOffset;
1841     if (other.hasFilter()) {
1842     for (int i = l; i < h; ++i) {
1843     Object x = a[i];
1844     if (s.op(i, x) && other.isSelected(k))
1845     a[i] = combiner.op(x, other.oget(k));
1846     k++;
1847     }
1848     }
1849     else if (other.hasMap()) {
1850     for (int i = l; i < h; ++i) {
1851     Object x = a[i];
1852     if (s.op(i, x))
1853     a[i] = combiner.op(x, other.oget(k));
1854     k++;
1855     }
1856     }
1857     else {
1858     Object[] b = other.array;
1859     for (int i = l; i < h; ++i) {
1860     Object x = a[i];
1861     if (s.op(i, x))
1862     a[i] = combiner.op(x, b[k]);
1863     k++;
1864     }
1865     }
1866     }
1867     }
1868    
1869     static final class DRPap extends ParallelDoubleArrayWithFilter {
1870     final IntAndDoublePredicate selector;
1871     DRPap(ForkJoinPool ex, int origin, int fence,
1872     double[] array,
1873     IntAndDoublePredicate selector) {
1874     super(ex, origin, fence, array);
1875     this.selector = selector;
1876     }
1877    
1878     boolean hasFilter() { return true; }
1879     boolean isSelected(int i) { return selector.op(i, this.array[i]); }
1880    
1881     public ParallelDoubleArrayWithFilter withFilter
1882     (DoublePredicate selector) {
1883     return new DRPap
1884     (ex, origin, fence, array,
1885     compoundIndexedSelector(this.selector, selector));
1886     }
1887    
1888     public ParallelDoubleArrayWithFilter withIndexedFilter
1889     (IntAndDoublePredicate selector) {
1890     return new DRPap
1891     (ex, origin, fence, array,
1892     compoundIndexedSelector(this.selector, selector));
1893     }
1894    
1895     public <U> ParallelDoubleArrayWithMapping<U> withMapping
1896     (DoubleToObject<? extends U> op) {
1897     return new DROMPap<U>(ex, origin, fence, array, selector, op);
1898     }
1899    
1900     public ParallelDoubleArrayWithDoubleMapping withMapping(DoubleOp op) {
1901     return new DRDMPap(ex, origin, fence, array, selector, op);
1902     }
1903    
1904     public ParallelDoubleArrayWithLongMapping withMapping(DoubleToLong op) {
1905     return new DRLMPap(ex, origin, fence, array, selector, op);
1906     }
1907    
1908     public <V> ParallelDoubleArrayWithMapping<V> withIndexedMapping
1909     (IntAndDoubleToObject<? extends V> mapper) {
1910     return new DROCPap<V>(ex, origin, fence, array, selector, mapper);
1911     }
1912    
1913     public ParallelDoubleArrayWithDoubleMapping withIndexedMapping
1914     (IntAndDoubleToDouble mapper) {
1915     return new DRDCPap(ex, origin, fence, array, selector, mapper);
1916     }
1917    
1918     public ParallelDoubleArrayWithLongMapping withIndexedMapping
1919     (IntAndDoubleToLong mapper) {
1920     return new DRLCPap(ex, origin, fence, array, selector, mapper);
1921     }
1922    
1923     final void leafApply(int lo, int hi, DoubleProcedure procedure) {
1924     final IntAndDoublePredicate s = selector;
1925     final double[] a = this.array;
1926     for (int i = lo; i < hi; ++i) {
1927     double x = a[i];
1928     if (s.op(i, x))
1929     procedure.op(x);
1930     }
1931     }
1932    
1933     final double leafReduce(int lo, int hi, DoubleReducer reducer, double base) {
1934     final IntAndDoublePredicate s = selector;
1935     boolean gotFirst = false;
1936     double r = base;
1937     final double[] a = this.array;
1938     for (int i = lo; i < hi; ++i) {
1939     double x = a[i];
1940     if (s.op(i, x)) {
1941     if (!gotFirst) {
1942     gotFirst = true;
1943     r = x;
1944     }
1945     else
1946     r = reducer.op(r, x);
1947     }
1948     }
1949     return r;
1950     }
1951    
1952     final void leafTransform(int l, int h, DoubleOp op) {
1953     final double[] a = this.array;
1954     final IntAndDoublePredicate s = selector;
1955     for (int i = l; i < h; ++i) {
1956     double x = a[i];
1957     if (s.op(i, x))
1958     a[i] = op.op(x);
1959     }
1960     }
1961    
1962     final void leafIndexMap(int l, int h, IntToDouble op) {
1963     final double[] a = this.array;
1964     final IntAndDoublePredicate s = selector;
1965     for (int i = l; i < h; ++i) {
1966     double x = a[i];
1967     if (s.op(i, x))
1968     a[i] = op.op(i);
1969     }
1970     }
1971    
1972     final void leafBinaryIndexMap(int l, int h, IntAndDoubleToDouble op) {
1973     final double[] a = this.array;
1974     final IntAndDoublePredicate s = selector;
1975     for (int i = l; i < h; ++i) {
1976     double x = a[i];
1977     if (s.op(i, x))
1978     a[i] = op.op(i, x);
1979     }
1980     }
1981    
1982     final void leafGenerate(int l, int h, DoubleGenerator generator) {
1983     final double[] a = this.array;
1984     final IntAndDoublePredicate s = selector;
1985     for (int i = l; i < h; ++i) {
1986     if (s.op(i, a[i]))
1987     a[i] = generator.op();
1988     }
1989     }
1990    
1991     final void leafFill(int l, int h, double value) {
1992     final double[] a = this.array;
1993     final IntAndDoublePredicate s = selector;
1994     for (int i = l; i < h; ++i) {
1995     if (s.op(i, a[i]))
1996     a[i] = value;
1997     }
1998     }
1999    
2000     final void leafCombineInPlace
2001     (int l, int h, double[] other,
2002     int otherOffset, BinaryDoubleOp combiner) {
2003     final double[] a = this.array;
2004     final IntAndDoublePredicate s = selector;
2005     int k = l + otherOffset;
2006     for (int i = l; i < h; ++i) {
2007     double x = a[i];
2008     if (s.op(i, x))
2009     a[i] = combiner.op(x, other[k]);
2010     k++;
2011     }
2012     }
2013    
2014     final void leafCombineInPlace
2015     (int l, int h,
2016     ParallelDoubleArrayWithDoubleMapping other,
2017     int otherOffset, BinaryDoubleOp combiner) {
2018     final double[] a = this.array;
2019     final IntAndDoublePredicate s = selector;
2020     int k = l + otherOffset;
2021     if (other.hasFilter()) {
2022     for (int i = l; i < h; ++i) {
2023     double x = a[i];
2024     if (s.op(i, x) && other.isSelected(k))
2025     a[i] = combiner.op(x, other.dget(k));
2026     k++;
2027     }
2028     }
2029     else if (other.hasMap()) {
2030     for (int i = l; i < h; ++i) {
2031     double x = a[i];
2032     if (s.op(i, x))
2033     a[i] = combiner.op(x, other.dget(k));
2034     k++;
2035     }
2036     }
2037     else {
2038     double[] b = other.array;
2039     for (int i = l; i < h; ++i) {
2040     double x = a[i];
2041     if (s.op(i, x))
2042     a[i] = combiner.op(x, b[k]);
2043     k++;
2044     }
2045     }
2046     }
2047     }
2048    
2049     static final class LRPap extends ParallelLongArrayWithFilter {
2050     final IntAndLongPredicate selector;
2051     LRPap(ForkJoinPool ex, int origin, int fence,
2052     long[] array,
2053     IntAndLongPredicate selector) {
2054     super(ex, origin, fence, array);
2055     this.selector = selector;
2056     }
2057    
2058     boolean hasFilter() { return true; }
2059     boolean isSelected(int i) { return selector.op(i, this.array[i]); }
2060    
2061     public ParallelLongArrayWithFilter withFilter(LongPredicate selector) {
2062     return new LRPap(ex, origin, fence, array,
2063     compoundIndexedSelector(this.selector, selector));
2064     }
2065    
2066     public ParallelLongArrayWithFilter withIndexedFilter
2067     (IntAndLongPredicate selector) {
2068     return new LRPap
2069     (ex, origin, fence, array,
2070     compoundIndexedSelector(this.selector, selector));
2071     }
2072    
2073     public <U> ParallelLongArrayWithMapping<U> withMapping
2074     (LongToObject<? extends U> op) {
2075     return new LROMPap<U>(ex, origin, fence, array, selector, op);
2076     }
2077    
2078     public ParallelLongArrayWithLongMapping withMapping
2079     (LongOp op) {
2080     return new LRLMPap(ex, origin, fence, array, selector, op);
2081     }
2082    
2083     public ParallelLongArrayWithDoubleMapping withMapping
2084     (LongToDouble op) {
2085     return new LRDMPap(ex, origin, fence, array, selector, op);
2086     }
2087    
2088     public <V> ParallelLongArrayWithMapping<V> withIndexedMapping
2089     (IntAndLongToObject<? extends V> mapper) {
2090     return new LROCPap<V>(ex, origin, fence, array, selector, mapper);
2091     }
2092    
2093     public ParallelLongArrayWithDoubleMapping withIndexedMapping
2094     (IntAndLongToDouble mapper) {
2095     return new LRDCPap(ex, origin, fence, array, selector, mapper);
2096     }
2097    
2098     public ParallelLongArrayWithLongMapping withIndexedMapping
2099     (IntAndLongToLong mapper) {
2100     return new LRLCPap(ex, origin, fence, array, selector, mapper);
2101     }
2102    
2103     final void leafApply(int lo, int hi, LongProcedure procedure) {
2104     final IntAndLongPredicate s = selector;
2105     final long[] a = this.array;
2106     for (int i = lo; i < hi; ++i) {
2107     long x = a[i];
2108     if (s.op(i, x))
2109     procedure.op(x);
2110     }
2111     }
2112    
2113     final long leafReduce(int lo, int hi, LongReducer reducer, long base) {
2114     final IntAndLongPredicate s = selector;
2115     boolean gotFirst = false;
2116     long r = base;
2117     final long[] a = this.array;
2118     for (int i = lo; i < hi; ++i) {
2119     long x = a[i];
2120     if (s.op(i, x)) {
2121     if (!gotFirst) {
2122     gotFirst = true;
2123     r = x;
2124     }
2125     else
2126     r = reducer.op(r, x);
2127     }
2128     }
2129     return r;
2130     }
2131    
2132     final void leafTransform(int l, int h, LongOp op) {
2133     final long[] a = this.array;
2134     final IntAndLongPredicate s = selector;
2135     for (int i = l; i < h; ++i) {
2136     long x = a[i];
2137     if (s.op(i, x))
2138     a[i] = op.op(x);
2139     }
2140     }
2141    
2142     final void leafIndexMap(int l, int h, IntToLong op) {
2143     final long[] a = this.array;
2144     final IntAndLongPredicate s = selector;
2145     for (int i = l; i < h; ++i) {
2146     long x = a[i];
2147     if (s.op(i, x))
2148     a[i] = op.op(i);
2149     }
2150     }
2151    
2152     final void leafBinaryIndexMap(int l, int h, IntAndLongToLong op) {
2153     final long[] a = this.array;
2154     final IntAndLongPredicate s = selector;
2155     for (int i = l; i < h; ++i) {
2156     long x = a[i];
2157     if (s.op(i, x))
2158     a[i] = op.op(i, x);
2159     }
2160     }
2161    
2162     final void leafGenerate(int l, int h, LongGenerator generator) {
2163     final long[] a = this.array;
2164     final IntAndLongPredicate s = selector;
2165     for (int i = l; i < h; ++i) {
2166     if (s.op(i, a[i]))
2167     a[i] = generator.op();
2168     }
2169     }
2170    
2171     final void leafFill(int l, int h, long value) {
2172     final long[] a = this.array;
2173     final IntAndLongPredicate s = selector;
2174     for (int i = l; i < h; ++i) {
2175     if (s.op(i, a[i]))
2176     a[i] = value;
2177     }
2178     }
2179    
2180     final void leafCombineInPlace
2181     (int l, int h, long[] other,
2182     int otherOffset, BinaryLongOp combiner) {
2183     final long[] a = this.array;
2184     final IntAndLongPredicate s = selector;
2185     int k = l + otherOffset;
2186     for (int i = l; i < h; ++i) {
2187     long x = a[i];
2188     if (s.op(i, x))
2189     a[i] = combiner.op(x, other[k]);
2190     k++;
2191     }
2192     }
2193    
2194     final void leafCombineInPlace
2195     (int l, int h,
2196     ParallelLongArrayWithLongMapping other,
2197     int otherOffset, BinaryLongOp combiner) {
2198     final long[] a = this.array;
2199     final IntAndLongPredicate s = selector;
2200     int k = l + otherOffset;
2201     if (other.hasFilter()) {
2202     for (int i = l; i < h; ++i) {
2203     long x = a[i];
2204     if (s.op(i, x) && other.isSelected(k))
2205     a[i] = combiner.op(x, other.lget(k));
2206     k++;
2207     }
2208     }
2209     else if (other.hasMap()) {
2210     for (int i = l; i < h; ++i) {
2211     long x = a[i];
2212     if (s.op(i, x))
2213     a[i] = combiner.op(x, other.lget(k));
2214     k++;
2215     }
2216     }
2217     else {
2218     long[] b = other.array;
2219     for (int i = l; i < h; ++i) {
2220     long x = a[i];
2221     if (s.op(i, x))
2222     a[i] = combiner.op(x, b[k]);
2223     k++;
2224     }
2225     }
2226     }
2227     }
2228    
2229     // Object-mapped
2230    
2231     static abstract class OOMPap<T,U> extends ParallelArrayWithMapping<T,U> {
2232     final Op<? super T, ? extends U> op;
2233     OOMPap(ForkJoinPool ex, int origin, int fence,
2234     T[] array,
2235     Op<? super T, ? extends U> op) {
2236     super(ex, origin, fence, array);
2237     this.op = op;
2238     }
2239    
2240     final boolean hasMap() { return true; }
2241     final Object oget(int i) { return op.op(this.array[i]); }
2242     final double dget(int i) { return ((Number)oget(i)).doubleValue(); }
2243     final long lget(int i) { return ((Number)oget(i)).longValue(); }
2244    
2245     final void leafTransfer(int lo, int hi, Object[] dest, int offset) {
2246     final Op f = op;
2247     final Object[] a = this.array;
2248     for (int i = lo; i < hi; ++i)
2249     dest[offset++] = f.op(a[i]);
2250     }
2251    
2252     final void leafTransferByIndex(int[] indices, int loIdx, int hiIdx,
2253     Object[] dest, int offset) {
2254     final Object[] a = this.array;
2255     final Op f = op;
2256     for (int i = loIdx; i < hiIdx; ++i)
2257     dest[offset++] = f.op(a[indices[i]]);
2258     }
2259     }
2260    
2261     static abstract class DOMPap<U> extends ParallelDoubleArrayWithMapping<U> {
2262     final DoubleToObject<? extends U> op;
2263     DOMPap(ForkJoinPool ex, int origin, int fence,
2264     double[] array, DoubleToObject<? extends U> op) {
2265     super(ex, origin, fence, array);
2266     this.op = op;
2267     }
2268    
2269     final boolean hasMap() { return true; }
2270     final Object oget(int i) { return op.op(this.array[i]); }
2271     final double dget(int i) { return ((Number)oget(i)).doubleValue(); }
2272     final long lget(int i) { return ((Number)oget(i)).longValue(); }
2273    
2274     final void leafTransfer(int lo, int hi, Object[] dest, int offset) {
2275     final double[] a = this.array;
2276     final DoubleToObject f = op;
2277     for (int i = lo; i < hi; ++i)
2278     dest[offset++] = f.op(a[i]);
2279     }
2280    
2281     final void leafTransferByIndex(int[] indices, int loIdx, int hiIdx,
2282     Object[] dest, int offset) {
2283     final double[] a = this.array;
2284     final DoubleToObject f = op;
2285     for (int i = loIdx; i < hiIdx; ++i)
2286     dest[offset++] = f.op(a[indices[i]]);
2287     }
2288     }
2289    
2290     static abstract class LOMPap<U> extends ParallelLongArrayWithMapping<U> {
2291     final LongToObject<? extends U> op;
2292     LOMPap(ForkJoinPool ex, int origin, int fence,
2293     long[] array, LongToObject<? extends U> op) {
2294     super(ex, origin, fence, array);
2295     this.op = op;
2296     }
2297    
2298     final boolean hasMap() { return true; }
2299     final Object oget(int i) { return op.op(this.array[i]); }
2300     final double dget(int i) { return ((Number)oget(i)).doubleValue(); }
2301     final long lget(int i) { return ((Number)oget(i)).longValue(); }
2302    
2303     final void leafTransfer(int lo, int hi, Object[] dest, int offset) {
2304     final long[] a = this.array;
2305     final LongToObject f = op;
2306     for (int i = lo; i < hi; ++i)
2307     dest[offset++] = f.op(a[i]);
2308     }
2309    
2310     final void leafTransferByIndex(int[] indices, int loIdx, int hiIdx,
2311     Object[] dest, int offset) {
2312     final long[] a = this.array;
2313     final LongToObject f = op;
2314     for (int i = loIdx; i < hiIdx; ++i)
2315     dest[offset++] = f.op(a[indices[i]]);
2316     }
2317     }
2318    
2319     // Object mapped, unfiltered
2320    
2321     static final class OUOMPap<T,U> extends OOMPap<T,U> {
2322     OUOMPap(ForkJoinPool ex, int origin, int fence,
2323     T[] array, Op<? super T, ? extends U> op) {
2324     super(ex, origin, fence, array, op);
2325     }
2326    
2327     public <V> ParallelArrayWithMapping<T, V> withMapping
2328     (Op<? super U, ? extends V> op) {
2329     return new OUOMPap<T,V>(ex, origin, fence, array,
2330     CommonOps.compoundOp(this.op, op));
2331     }
2332    
2333     public ParallelArrayWithDoubleMapping<T> withMapping
2334     (ObjectToDouble<? super U> op) {
2335     return new OUDMPap<T>(ex, origin, fence, array,
2336     CommonOps.compoundOp(this.op, op));
2337     }
2338    
2339     public ParallelArrayWithLongMapping<T> withMapping
2340     (ObjectToLong<? super U> op) {
2341     return new OULMPap<T>(ex, origin, fence, array,
2342     CommonOps.compoundOp(this.op, op));
2343     }
2344    
2345     public <V> ParallelArrayWithMapping<T,V> withIndexedMapping
2346     (IntAndObjectToObject<? super U, ? extends V> mapper) {
2347     return new OUOCPap<T,V>(ex, origin, fence, array,
2348     compoundIndexedOp(this.op, mapper));
2349     }
2350    
2351     public ParallelArrayWithDoubleMapping<T> withIndexedMapping
2352     (IntAndObjectToDouble<? super U> mapper) {
2353     return new OUDCPap<T>(ex, origin, fence, array,
2354     compoundIndexedOp(this.op, mapper));
2355     }
2356    
2357     public ParallelArrayWithLongMapping<T> withIndexedMapping
2358     (IntAndObjectToLong<? super U> mapper) {
2359     return new OULCPap<T>(ex, origin, fence, array,
2360     compoundIndexedOp(this.op, mapper));
2361     }
2362    
2363     void leafApply(int lo, int hi, Procedure procedure) {
2364     final Op f = op;
2365     final Object[] a = this.array;
2366     for (int i = lo; i < hi; ++i)
2367     procedure.op(f.op(a[i]));
2368     }
2369    
2370     Object leafReduce(int lo, int hi, Reducer reducer, Object base) {
2371     if (lo >= hi)
2372     return base;
2373     final Object[] a = this.array;
2374     final Op f = op;
2375     Object r = f.op(a[lo]);
2376     for (int i = lo+1; i < hi; ++i)
2377     r = reducer.op(r, f.op(a[i]));
2378     return r;
2379     }
2380    
2381     }
2382    
2383     static final class DUOMPap<U> extends DOMPap<U> {
2384     DUOMPap(ForkJoinPool ex, int origin, int fence,
2385     double[] array, DoubleToObject<? extends U> op) {
2386     super(ex, origin, fence, array, op);
2387     }
2388    
2389     public <V> ParallelDoubleArrayWithMapping<V> withMapping
2390     (Op<? super U, ? extends V> op) {
2391     return new DUOMPap<V>(ex, origin, fence, array,
2392     CommonOps.compoundOp(this.op, op));
2393     }
2394    
2395     public ParallelDoubleArrayWithDoubleMapping withMapping
2396 jsr166 1.3 (ObjectToDouble<? super U> op) {
2397 dl 1.1 return new DUDMPap(ex, origin, fence, array,
2398     CommonOps.compoundOp(this.op, op));
2399     }
2400    
2401     public ParallelDoubleArrayWithLongMapping withMapping
2402     (ObjectToLong<? super U> op) {
2403     return new DULMPap(ex, origin, fence, array,
2404     CommonOps.compoundOp(this.op, op));
2405     }
2406    
2407     public <V> ParallelDoubleArrayWithMapping<V> withIndexedMapping
2408     (IntAndObjectToObject<? super U, ? extends V> mapper) {
2409     return new DUOCPap<V>(ex, origin, fence, array,
2410     compoundIndexedOp(this.op, mapper));
2411     }
2412    
2413     public ParallelDoubleArrayWithDoubleMapping withIndexedMapping
2414     (IntAndObjectToDouble<? super U> mapper) {
2415     return new DUDCPap(ex, origin, fence, array,
2416     compoundIndexedOp(this.op, mapper));
2417     }
2418    
2419     public ParallelDoubleArrayWithLongMapping withIndexedMapping
2420     (IntAndObjectToLong<? super U> mapper) {
2421     return new DULCPap(ex, origin, fence, array,
2422     compoundIndexedOp(this.op, mapper));
2423     }
2424    
2425     void leafApply(int lo, int hi, Procedure procedure) {
2426     final double[] a = this.array;
2427     final DoubleToObject f = op;
2428     for (int i = lo; i < hi; ++i)
2429     procedure.op(f.op(a[i]));
2430     }
2431    
2432     Object leafReduce(int lo, int hi, Reducer reducer, Object base) {
2433     if (lo >= hi)
2434     return base;
2435     final double[] a = this.array;
2436     final DoubleToObject f = op;
2437     Object r = f.op(a[lo]);
2438     for (int i = lo+1; i < hi; ++i)
2439     r = reducer.op(r, f.op(a[i]));
2440     return r;
2441     }
2442    
2443     }
2444    
2445     static final class LUOMPap<U> extends LOMPap<U> {
2446     LUOMPap(ForkJoinPool ex, int origin, int fence,
2447     long[] array, LongToObject<? extends U> op) {
2448     super(ex, origin, fence, array, op);
2449     }
2450    
2451     public <V> ParallelLongArrayWithMapping<V> withMapping
2452     (Op<? super U, ? extends V> op) {
2453     return new LUOMPap<V>(ex, origin, fence, array,
2454     CommonOps.compoundOp(this.op, op));
2455     }
2456    
2457     public ParallelLongArrayWithLongMapping withMapping
2458     (ObjectToLong<? super U> op) {
2459     return new LULMPap(ex, origin, fence, array,
2460     CommonOps.compoundOp(this.op, op));
2461     }
2462    
2463     public ParallelLongArrayWithDoubleMapping withMapping
2464     (ObjectToDouble<? super U> op) {
2465     return new LUDMPap(ex, origin, fence, array,
2466     CommonOps.compoundOp(this.op, op));
2467     }
2468    
2469     public <V> ParallelLongArrayWithMapping<V> withIndexedMapping
2470     (IntAndObjectToObject<? super U, ? extends V> mapper) {
2471     return new LUOCPap<V>(ex, origin, fence, array,
2472     compoundIndexedOp(this.op, mapper));
2473     }
2474    
2475     public ParallelLongArrayWithDoubleMapping withIndexedMapping
2476     (IntAndObjectToDouble<? super U> mapper) {
2477     return new LUDCPap(ex, origin, fence, array,
2478     compoundIndexedOp(this.op, mapper));
2479     }
2480    
2481     public ParallelLongArrayWithLongMapping withIndexedMapping
2482     (IntAndObjectToLong<? super U> mapper) {
2483     return new LULCPap(ex, origin, fence, array,
2484     compoundIndexedOp(this.op, mapper));
2485     }
2486    
2487     void leafApply(int lo, int hi, Procedure procedure) {
2488     final long[] a = this.array;
2489     final LongToObject f = op;
2490     for (int i = lo; i < hi; ++i)
2491     procedure.op(f.op(a[i]));
2492     }
2493    
2494     Object leafReduce(int lo, int hi, Reducer reducer, Object base) {
2495     if (lo >= hi)
2496     return base;
2497     final long[] a = this.array;
2498     final LongToObject f = op;
2499     Object r = f.op(a[lo]);
2500     for (int i = lo+1; i < hi; ++i)
2501     r = reducer.op(r, f.op(a[i]));
2502     return r;
2503     }
2504    
2505     }
2506    
2507     // Object-mapped, filtered
2508     static final class OFOMPap<T,U> extends OOMPap<T,U> {
2509     final Predicate<? super T> selector;
2510    
2511     OFOMPap(ForkJoinPool ex, int origin, int fence,
2512     T[] array, Predicate<? super T> selector,
2513     Op<? super T, ? extends U> op) {
2514     super(ex, origin, fence, array, op);
2515     this.selector = selector;
2516     }
2517    
2518     boolean hasFilter() { return true; }
2519     boolean isSelected(int i) { return selector.op(this.array[i]); }
2520    
2521     public <V> ParallelArrayWithMapping<T, V> withMapping
2522     (Op<? super U, ? extends V> op) {
2523     return new OFOMPap<T,V>
2524     (ex, origin, fence, array, selector,
2525     CommonOps.compoundOp(this.op, op));
2526     }
2527    
2528     public ParallelArrayWithDoubleMapping<T> withMapping
2529     (ObjectToDouble<? super U> op) {
2530     return new OFDMPap<T>(ex, origin, fence, array, selector,
2531     CommonOps.compoundOp(this.op, op));
2532     }
2533    
2534     public ParallelArrayWithLongMapping<T> withMapping
2535     (ObjectToLong<? super U> op) {
2536     return new OFLMPap<T>(ex, origin, fence, array, selector,
2537     CommonOps.compoundOp(this.op, op));
2538     }
2539    
2540     public <V> ParallelArrayWithMapping<T,V> withIndexedMapping
2541     (IntAndObjectToObject<? super U, ? extends V> mapper) {
2542     return new OFOCPap<T,V>(ex, origin, fence, array, selector,
2543     compoundIndexedOp(this.op, mapper));
2544     }
2545    
2546     public ParallelArrayWithDoubleMapping<T> withIndexedMapping
2547     (IntAndObjectToDouble<? super U> mapper) {
2548     return new OFDCPap<T>(ex, origin, fence, array, selector,
2549     compoundIndexedOp(this.op, mapper));
2550     }
2551    
2552     public ParallelArrayWithLongMapping<T> withIndexedMapping
2553     (IntAndObjectToLong<? super U> mapper) {
2554     return new OFLCPap<T>(ex, origin, fence, array, selector,
2555     compoundIndexedOp(this.op, mapper));
2556     }
2557    
2558     void leafApply(int lo, int hi, Procedure procedure) {
2559     final Predicate s = selector;
2560     final Object[] a = this.array;
2561     final Op f = op;
2562     for (int i = lo; i < hi; ++i) {
2563     Object x = a[i];
2564     if (s.op(x))
2565     procedure.op(f.op(x));
2566     }
2567     }
2568     Object leafReduce(int lo, int hi, Reducer reducer, Object base) {
2569     final Predicate s = selector;
2570     final Object[] a = this.array;
2571     final Op f = op;
2572     boolean gotFirst = false;
2573     Object r = base;
2574     for (int i = lo; i < hi; ++i) {
2575     Object x = a[i];
2576     if (s.op(x)) {
2577     Object y = f.op(x);
2578     if (!gotFirst) {
2579     gotFirst = true;
2580     r = y;
2581     }
2582     else
2583     r = reducer.op(r, y);
2584     }
2585     }
2586     return r;
2587     }
2588    
2589     }
2590    
2591     static final class DFOMPap<U> extends DOMPap<U> {
2592     final DoublePredicate selector;
2593     DFOMPap(ForkJoinPool ex, int origin, int fence,
2594     double[] array, DoublePredicate selector,
2595     DoubleToObject<? extends U> op) {
2596     super(ex, origin, fence, array, op);
2597     this.selector = selector;
2598     }
2599    
2600     boolean hasFilter() { return true; }
2601     boolean isSelected(int i) { return selector.op(this.array[i]); }
2602    
2603     public ParallelArray<U> all(Class<? super U> elementType) {
2604     PAS.FJOSelectAllDriver r = new PAS.FJOSelectAllDriver
2605     (this, elementType);
2606     ex.invoke(r);
2607     return new ParallelArray<U>(ex, (U[])(r.results));
2608     }
2609    
2610     public <V> ParallelDoubleArrayWithMapping<V> withMapping
2611     (Op<? super U, ? extends V> op) {
2612     return new DFOMPap<V>(ex, origin, fence, array, selector,
2613     CommonOps.compoundOp(this.op, op));
2614     }
2615    
2616     public ParallelDoubleArrayWithDoubleMapping withMapping
2617     (ObjectToDouble<? super U> op) {
2618     return new DFDMPap(ex, origin, fence, array, selector,
2619     CommonOps.compoundOp(this.op, op));
2620     }
2621    
2622     public ParallelDoubleArrayWithLongMapping withMapping
2623     (ObjectToLong<? super U> op) {
2624     return new DFLMPap(ex, origin, fence, array, selector,
2625     CommonOps.compoundOp(this.op, op));
2626     }
2627    
2628     public <V> ParallelDoubleArrayWithMapping<V> withIndexedMapping
2629     (IntAndObjectToObject<? super U, ? extends V> mapper) {
2630     return new DFOCPap<V>(ex, origin, fence, array, selector,
2631     compoundIndexedOp(this.op, mapper));
2632     }
2633    
2634     public ParallelDoubleArrayWithDoubleMapping withIndexedMapping
2635     (IntAndObjectToDouble<? super U> mapper) {
2636     return new DFDCPap(ex, origin, fence, array, selector,
2637     compoundIndexedOp(this.op, mapper));
2638     }
2639    
2640     public ParallelDoubleArrayWithLongMapping withIndexedMapping
2641     (IntAndObjectToLong<? super U> mapper) {
2642     return new DFLCPap(ex, origin, fence, array, selector,
2643     compoundIndexedOp(this.op, mapper));
2644     }
2645    
2646     void leafApply(int lo, int hi, Procedure procedure) {
2647     final DoublePredicate s = selector;
2648     final DoubleToObject f = op;
2649     final double[] a = this.array;
2650     for (int i = lo; i < hi; ++i) {
2651     double x = a[i];
2652     if (s.op(x))
2653     procedure.op(f.op(x));
2654     }
2655     }
2656    
2657     Object leafReduce(int lo, int hi, Reducer reducer, Object base) {
2658     boolean gotFirst = false;
2659     Object r = base;
2660     final DoublePredicate s = selector;
2661     final DoubleToObject f = op;
2662     final double[] a = this.array;
2663     for (int i = lo; i < hi; ++i) {
2664     double x = a[i];
2665     if (s.op(x)) {
2666     Object y = f.op(x);
2667     if (!gotFirst) {
2668     gotFirst = true;
2669     r = y;
2670     }
2671     else
2672     r = reducer.op(r, y);
2673     }
2674     }
2675     return r;
2676     }
2677    
2678     }
2679    
2680     static final class LFOMPap<U> extends LOMPap<U> {
2681     final LongPredicate selector;
2682     LFOMPap(ForkJoinPool ex, int origin, int fence,
2683     long[] array, LongPredicate selector,
2684     LongToObject<? extends U> op) {
2685     super(ex, origin, fence, array, op);
2686     this.selector = selector;
2687     }
2688    
2689     boolean hasFilter() { return true; }
2690     boolean isSelected(int i) { return selector.op(this.array[i]); }
2691    
2692     public <V> ParallelLongArrayWithMapping<V> withMapping
2693     (Op<? super U, ? extends V> op) {
2694     return new LFOMPap<V>(ex, origin, fence, array, selector,
2695     CommonOps.compoundOp(this.op, op));
2696     }
2697    
2698     public ParallelLongArrayWithLongMapping withMapping
2699     (ObjectToLong<? super U> op) {
2700     return new LFLMPap(ex, origin, fence, array, selector,
2701     CommonOps.compoundOp(this.op, op));
2702     }
2703    
2704     public ParallelLongArrayWithDoubleMapping withMapping
2705     (ObjectToDouble<? super U> op) {
2706     return new LFDMPap(ex, origin, fence, array, selector,
2707     CommonOps.compoundOp(this.op, op));
2708     }
2709    
2710     public <V> ParallelLongArrayWithMapping<V> withIndexedMapping
2711     (IntAndObjectToObject<? super U, ? extends V> mapper) {
2712     return new LFOCPap<V>(ex, origin, fence, array, selector,
2713     compoundIndexedOp(this.op, mapper));
2714     }
2715    
2716     public ParallelLongArrayWithDoubleMapping withIndexedMapping
2717     (IntAndObjectToDouble<? super U> mapper) {
2718     return new LFDCPap(ex, origin, fence, array, selector,
2719     compoundIndexedOp(this.op, mapper));
2720     }
2721    
2722     public ParallelLongArrayWithLongMapping withIndexedMapping
2723     (IntAndObjectToLong<? super U> mapper) {
2724     return new LFLCPap(ex, origin, fence, array, selector,
2725     compoundIndexedOp(this.op, mapper));
2726     }
2727    
2728     void leafApply(int lo, int hi, Procedure procedure) {
2729     final LongPredicate s = selector;
2730     final LongToObject f = op;
2731     final long[] a = this.array;
2732     for (int i = lo; i < hi; ++i) {
2733     long x = a[i];
2734     if (s.op(x))
2735     procedure.op(f.op(x));
2736     }
2737     }
2738    
2739     Object leafReduce(int lo, int hi, Reducer reducer, Object base) {
2740     final LongPredicate s = selector;
2741     final LongToObject f = op;
2742     boolean gotFirst = false;
2743     Object r = base;
2744     final long[] a = this.array;
2745     for (int i = lo; i < hi; ++i) {
2746     long x = a[i];
2747     if (s.op(x)) {
2748     Object y = f.op(x);
2749     if (!gotFirst) {
2750     gotFirst = true;
2751     r = y;
2752     }
2753     else
2754     r = reducer.op(r, y);
2755     }
2756     }
2757     return r;
2758     }
2759    
2760     }
2761    
2762     // Object-mapped, relational
2763     static final class OROMPap<T,U> extends OOMPap<T,U> {
2764     final IntAndObjectPredicate<? super T> selector;
2765    
2766     OROMPap(ForkJoinPool ex, int origin, int fence,
2767     T[] array, IntAndObjectPredicate<? super T> selector,
2768     Op<? super T, ? extends U> op) {
2769     super(ex, origin, fence, array, op);
2770     this.selector = selector;
2771     }
2772    
2773     boolean hasFilter() { return true; }
2774     boolean isSelected(int i) { return selector.op(i, this.array[i]); }
2775    
2776     public <V> ParallelArrayWithMapping<T, V> withMapping
2777     (Op<? super U, ? extends V> op) {
2778     return new OROMPap<T,V>
2779     (ex, origin, fence, array, selector,
2780     CommonOps.compoundOp(this.op, op));
2781     }
2782    
2783     public ParallelArrayWithDoubleMapping<T> withMapping(ObjectToDouble<? super U> op) {
2784     return new ORDMPap<T>(ex, origin, fence, array, selector,
2785     CommonOps.compoundOp(this.op, op));
2786     }
2787    
2788     public ParallelArrayWithLongMapping<T> withMapping(ObjectToLong<? super U> op) {
2789     return new ORLMPap<T>(ex, origin, fence, array, selector,
2790     CommonOps.compoundOp(this.op, op));
2791     }
2792    
2793     public <V> ParallelArrayWithMapping<T,V> withIndexedMapping
2794     (IntAndObjectToObject<? super U, ? extends V> mapper) {
2795     return new OROCPap<T,V>(ex, origin, fence, array, selector,
2796     compoundIndexedOp(this.op, mapper));
2797     }
2798    
2799     public ParallelArrayWithDoubleMapping<T> withIndexedMapping
2800     (IntAndObjectToDouble<? super U> mapper) {
2801     return new ORDCPap<T>(ex, origin, fence, array, selector,
2802     compoundIndexedOp(this.op, mapper));
2803     }
2804    
2805     public ParallelArrayWithLongMapping<T> withIndexedMapping
2806     (IntAndObjectToLong<? super U> mapper) {
2807     return new ORLCPap<T>(ex, origin, fence, array, selector,
2808     compoundIndexedOp(this.op, mapper));
2809     }
2810    
2811     void leafApply(int lo, int hi, Procedure procedure) {
2812     final IntAndObjectPredicate s = selector;
2813     final Object[] a = this.array;
2814     final Op f = op;
2815     for (int i = lo; i < hi; ++i) {
2816     Object x = a[i];
2817     if (s.op(i, x))
2818     procedure.op(f.op(x));
2819     }
2820     }
2821     Object leafReduce(int lo, int hi, Reducer reducer, Object base) {
2822     final IntAndObjectPredicate s = selector;
2823     final Object[] a = this.array;
2824     final Op f = op;
2825     boolean gotFirst = false;
2826     Object r = base;
2827     for (int i = lo; i < hi; ++i) {
2828     Object x = a[i];
2829     if (s.op(i, x)) {
2830     Object y = f.op(x);
2831     if (!gotFirst) {
2832     gotFirst = true;
2833     r = y;
2834     }
2835     else
2836     r = reducer.op(r, y);
2837     }
2838     }
2839     return r;
2840     }
2841    
2842     }
2843    
2844     static final class DROMPap<U> extends DOMPap<U> {
2845     final IntAndDoublePredicate selector;
2846     DROMPap(ForkJoinPool ex, int origin, int fence,
2847     double[] array, IntAndDoublePredicate selector,
2848     DoubleToObject<? extends U> op) {
2849     super(ex, origin, fence, array, op);
2850     this.selector = selector;
2851     }
2852    
2853     boolean hasFilter() { return true; }
2854     boolean isSelected(int i) { return selector.op(i, this.array[i]); }
2855    
2856     public ParallelArray<U> all(Class<? super U> elementType) {
2857     PAS.FJOSelectAllDriver r = new PAS.FJOSelectAllDriver
2858     (this, elementType);
2859     ex.invoke(r);
2860     return new ParallelArray<U>(ex, (U[])(r.results));
2861     }
2862    
2863     public <V> ParallelDoubleArrayWithMapping<V> withMapping
2864     (Op<? super U, ? extends V> op) {
2865     return new DROMPap<V>(ex, origin, fence, array, selector,
2866     CommonOps.compoundOp(this.op, op));
2867     }
2868    
2869     public ParallelDoubleArrayWithDoubleMapping withMapping
2870     (ObjectToDouble<? super U> op) {
2871     return new DRDMPap(ex, origin, fence, array, selector,
2872     CommonOps.compoundOp(this.op, op));
2873     }
2874    
2875     public ParallelDoubleArrayWithLongMapping withMapping
2876     (ObjectToLong<? super U> op) {
2877     return new DRLMPap(ex, origin, fence, array, selector,
2878     CommonOps.compoundOp(this.op, op));
2879     }
2880    
2881     public <V> ParallelDoubleArrayWithMapping<V> withIndexedMapping
2882     (IntAndObjectToObject<? super U, ? extends V> mapper) {
2883     return new DROCPap<V>(ex, origin, fence, array, selector,
2884     compoundIndexedOp(this.op, mapper));
2885     }
2886    
2887     public ParallelDoubleArrayWithDoubleMapping withIndexedMapping
2888     (IntAndObjectToDouble<? super U> mapper) {
2889     return new DRDCPap(ex, origin, fence, array, selector,
2890     compoundIndexedOp(this.op, mapper));
2891     }
2892    
2893     public ParallelDoubleArrayWithLongMapping withIndexedMapping
2894     (IntAndObjectToLong<? super U> mapper) {
2895     return new DRLCPap(ex, origin, fence, array, selector,
2896     compoundIndexedOp(this.op, mapper));
2897     }
2898    
2899     void leafApply(int lo, int hi, Procedure procedure) {
2900     final IntAndDoublePredicate s = selector;
2901     final DoubleToObject f = op;
2902     final double[] a = this.array;
2903     for (int i = lo; i < hi; ++i) {
2904     double x = a[i];
2905     if (s.op(i, x))
2906     procedure.op(f.op(x));
2907     }
2908     }
2909    
2910     Object leafReduce(int lo, int hi, Reducer reducer, Object base) {
2911     boolean gotFirst = false;
2912     Object r = base;
2913     final IntAndDoublePredicate s = selector;
2914     final DoubleToObject f = op;
2915     final double[] a = this.array;
2916     for (int i = lo; i < hi; ++i) {
2917     double x = a[i];
2918     if (s.op(i, x)) {
2919     Object y = f.op(x);
2920     if (!gotFirst) {
2921     gotFirst = true;
2922     r = y;
2923     }
2924     else
2925     r = reducer.op(r, y);
2926     }
2927     }
2928     return r;
2929     }
2930    
2931     }
2932    
2933     static final class LROMPap<U> extends LOMPap<U> {
2934     final IntAndLongPredicate selector;
2935     LROMPap(ForkJoinPool ex, int origin, int fence,
2936     long[] array, IntAndLongPredicate selector,
2937     LongToObject<? extends U> op) {
2938     super(ex, origin, fence, array, op);
2939     this.selector = selector;
2940     }
2941    
2942     boolean hasFilter() { return true; }
2943     boolean isSelected(int i) { return selector.op(i, this.array[i]); }
2944    
2945     public <V> ParallelLongArrayWithMapping<V> withMapping
2946     (Op<? super U, ? extends V> op) {
2947     return new LROMPap<V>(ex, origin, fence, array, selector,
2948     CommonOps.compoundOp(this.op, op));
2949     }
2950    
2951     public ParallelLongArrayWithLongMapping withMapping
2952     (ObjectToLong<? super U> op) {
2953     return new LRLMPap(ex, origin, fence, array, selector,
2954     CommonOps.compoundOp(this.op, op));
2955     }
2956    
2957     public ParallelLongArrayWithDoubleMapping withMapping
2958     (ObjectToDouble<? super U> op) {
2959     return new LRDMPap(ex, origin, fence, array, selector,
2960     CommonOps.compoundOp(this.op, op));
2961     }
2962    
2963     public <V> ParallelLongArrayWithMapping<V> withIndexedMapping
2964     (IntAndObjectToObject<? super U, ? extends V> mapper) {
2965     return new LROCPap<V>(ex, origin, fence, array, selector,
2966     compoundIndexedOp(this.op, mapper));
2967     }
2968    
2969     public ParallelLongArrayWithDoubleMapping withIndexedMapping
2970     (IntAndObjectToDouble<? super U> mapper) {
2971     return new LRDCPap(ex, origin, fence, array, selector,
2972     compoundIndexedOp(this.op, mapper));
2973     }
2974    
2975     public ParallelLongArrayWithLongMapping withIndexedMapping
2976     (IntAndObjectToLong<? super U> mapper) {
2977     return new LRLCPap(ex, origin, fence, array, selector,
2978     compoundIndexedOp(this.op, mapper));
2979     }
2980    
2981     void leafApply(int lo, int hi, Procedure procedure) {
2982     final IntAndLongPredicate s = selector;
2983     final LongToObject f = op;
2984     final long[] a = this.array;
2985     for (int i = lo; i < hi; ++i) {
2986     long x = a[i];
2987     if (s.op(i, x))
2988     procedure.op(f.op(x));
2989     }
2990     }
2991    
2992     Object leafReduce(int lo, int hi, Reducer reducer, Object base) {
2993     final IntAndLongPredicate s = selector;
2994     final LongToObject f = op;
2995     boolean gotFirst = false;
2996     Object r = base;
2997     final long[] a = this.array;
2998     for (int i = lo; i < hi; ++i) {
2999     long x = a[i];
3000     if (s.op(i, x)) {
3001     Object y = f.op(x);
3002     if (!gotFirst) {
3003     gotFirst = true;
3004     r = y;
3005     }
3006     else
3007     r = reducer.op(r, y);
3008     }
3009     }
3010     return r;
3011     }
3012     }
3013    
3014     // Object-combined
3015    
3016     static abstract class OOCPap<T,U> extends ParallelArrayWithMapping<T,U> {
3017     final IntAndObjectToObject<? super T, ? extends U> op;
3018     OOCPap(ForkJoinPool ex, int origin, int fence,
3019     T[] array,
3020     IntAndObjectToObject<? super T, ? extends U> op) {
3021     super(ex, origin, fence, array);
3022     this.op = op;
3023     }
3024    
3025     final boolean hasMap() { return true; }
3026     final Object oget(int i) { return op.op(i, this.array[i]); }
3027     final double dget(int i) { return ((Number)oget(i)).doubleValue(); }
3028     final long lget(int i) { return ((Number)oget(i)).longValue(); }
3029    
3030     final void leafTransfer(int lo, int hi, Object[] dest, int offset) {
3031     final IntAndObjectToObject f = op;
3032     final Object[] a = this.array;
3033     for (int i = lo; i < hi; ++i)
3034     dest[offset++] = f.op(i, a[i]);
3035     }
3036    
3037     final void leafTransferByIndex(int[] indices, int loIdx, int hiIdx,
3038     Object[] dest, int offset) {
3039     final Object[] a = this.array;
3040     final IntAndObjectToObject f = op;
3041     for (int i = loIdx; i < hiIdx; ++i) {
3042     int idx = indices[i];
3043     dest[offset++] = f.op(idx, a[idx]);
3044     }
3045     }
3046     }
3047    
3048     static abstract class DOCPap<U> extends ParallelDoubleArrayWithMapping<U> {
3049     final IntAndDoubleToObject<? extends U> op;
3050     DOCPap(ForkJoinPool ex, int origin, int fence,
3051     double[] array, IntAndDoubleToObject<? extends U> op) {
3052     super(ex, origin, fence, array);
3053     this.op = op;
3054     }
3055    
3056     final boolean hasMap() { return true; }
3057     final Object oget(int i) { return op.op(i, this.array[i]); }
3058     final double dget(int i) { return ((Number)oget(i)).doubleValue(); }
3059     final long lget(int i) { return ((Number)oget(i)).longValue(); }
3060    
3061     final void leafTransfer(int lo, int hi, Object[] dest, int offset) {
3062     final IntAndDoubleToObject f = op;
3063     final double[] a = this.array;
3064     for (int i = lo; i < hi; ++i)
3065     dest[offset++] = f.op(i, a[i]);
3066     }
3067    
3068     final void leafTransferByIndex(int[] indices, int loIdx, int hiIdx,
3069     Object[] dest, int offset) {
3070     final double[] a = this.array;
3071     final IntAndDoubleToObject f = op;
3072     for (int i = loIdx; i < hiIdx; ++i) {
3073     int idx = indices[i];
3074     dest[offset++] = f.op(idx, a[idx]);
3075     }
3076     }
3077     }
3078    
3079     static abstract class LOCPap<U> extends ParallelLongArrayWithMapping<U> {
3080     final IntAndLongToObject<? extends U> op;
3081     LOCPap(ForkJoinPool ex, int origin, int fence,
3082     long[] array, IntAndLongToObject<? extends U> op) {
3083     super(ex, origin, fence, array);
3084     this.op = op;
3085     }
3086    
3087     final boolean hasMap() { return true; }
3088     final Object oget(int i) { return op.op(i, this.array[i]); }
3089     final double dget(int i) { return ((Number)oget(i)).doubleValue(); }
3090     final long lget(int i) { return ((Number)oget(i)).longValue(); }
3091    
3092     final void leafTransfer(int lo, int hi, Object[] dest, int offset) {
3093     final IntAndLongToObject f = op;
3094     final long[] a = this.array;
3095     for (int i = lo; i < hi; ++i)
3096     dest[offset++] = f.op(i, a[i]);
3097     }
3098    
3099     final void leafTransferByIndex(int[] indices, int loIdx, int hiIdx,
3100     Object[] dest, int offset) {
3101     final long[] a = this.array;
3102     final IntAndLongToObject f = op;
3103     for (int i = loIdx; i < hiIdx; ++i) {
3104     int idx = indices[i];
3105     dest[offset++] = f.op(idx, a[idx]);
3106     }
3107     }
3108     }
3109    
3110     // Object-combined, unfiltered
3111    
3112     static final class OUOCPap<T,U> extends OOCPap<T,U> {
3113     OUOCPap(ForkJoinPool ex, int origin, int fence,
3114     T[] array, IntAndObjectToObject<? super T, ? extends U> op) {
3115     super(ex, origin, fence, array, op);
3116     }
3117    
3118     public <V> ParallelArrayWithMapping<T, V> withMapping
3119     (Op<? super U, ? extends V> op) {
3120     return new OUOCPap<T,V>(ex, origin, fence, array,
3121     compoundIndexedOp(this.op, op));
3122     }
3123    
3124     public ParallelArrayWithDoubleMapping<T> withMapping
3125     (ObjectToDouble<? super U> op) {
3126     return new OUDCPap<T>(ex, origin, fence, array,
3127     compoundIndexedOp(this.op, op));
3128     }
3129    
3130     public ParallelArrayWithLongMapping<T> withMapping
3131     (ObjectToLong<? super U> op) {
3132     return new OULCPap<T>(ex, origin, fence, array,
3133     compoundIndexedOp(this.op, op));
3134     }
3135    
3136     public <V> ParallelArrayWithMapping<T,V> withIndexedMapping
3137     (IntAndObjectToObject<? super U, ? extends V> mapper) {
3138     return new OUOCPap<T,V>(ex, origin, fence, array,
3139     compoundIndexedOp(this.op, mapper));
3140     }
3141    
3142     public ParallelArrayWithDoubleMapping<T> withIndexedMapping
3143     (IntAndObjectToDouble<? super U> mapper) {
3144     return new OUDCPap<T>(ex, origin, fence, array,
3145     compoundIndexedOp(this.op, mapper));
3146     }
3147    
3148     public ParallelArrayWithLongMapping<T> withIndexedMapping
3149     (IntAndObjectToLong<? super U> mapper) {
3150     return new OULCPap<T>(ex, origin, fence, array,
3151     compoundIndexedOp(this.op, mapper));
3152     }
3153    
3154     void leafApply(int lo, int hi, Procedure procedure) {
3155     final IntAndObjectToObject f = op;
3156     final Object[] a = this.array;
3157     for (int i = lo; i < hi; ++i)
3158     procedure.op(f.op(i, a[i]));
3159     }
3160    
3161     Object leafReduce(int lo, int hi, Reducer reducer, Object base) {
3162     if (lo >= hi)
3163     return base;
3164     final Object[] a = this.array;
3165     final IntAndObjectToObject f = op;
3166     Object r = f.op(lo, a[lo]);
3167     for (int i = lo+1; i < hi; ++i)
3168     r = reducer.op(r, f.op(i, a[i]));
3169     return r;
3170     }
3171    
3172     }
3173    
3174     static final class DUOCPap<U> extends DOCPap<U> {
3175     DUOCPap(ForkJoinPool ex, int origin, int fence,
3176     double[] array, IntAndDoubleToObject<? extends U> op) {
3177     super(ex, origin, fence, array, op);
3178     }
3179    
3180     public <V> ParallelDoubleArrayWithMapping< V> withMapping
3181     (Op<? super U, ? extends V> op) {
3182     return new DUOCPap<V>(ex, origin, fence, array,
3183     compoundIndexedOp(this.op, op));
3184     }
3185    
3186     public ParallelDoubleArrayWithDoubleMapping withMapping
3187     (ObjectToDouble<? super U> op) {
3188     return new DUDCPap(ex, origin, fence, array,
3189     compoundIndexedOp(this.op, op));
3190     }
3191    
3192     public ParallelDoubleArrayWithLongMapping withMapping
3193     (ObjectToLong<? super U> op) {
3194     return new DULCPap(ex, origin, fence, array,
3195     compoundIndexedOp(this.op, op));
3196     }
3197    
3198     public <V> ParallelDoubleArrayWithMapping<V> withIndexedMapping
3199     (IntAndObjectToObject<? super U, ? extends V> mapper) {
3200     return new DUOCPap<V>(ex, origin, fence, array,
3201     compoundIndexedOp(this.op, mapper));
3202     }
3203    
3204     public ParallelDoubleArrayWithDoubleMapping withIndexedMapping
3205     (IntAndObjectToDouble<? super U> mapper) {
3206     return new DUDCPap(ex, origin, fence, array,
3207     compoundIndexedOp(this.op, mapper));
3208     }
3209    
3210     public ParallelDoubleArrayWithLongMapping withIndexedMapping
3211     (IntAndObjectToLong<? super U> mapper) {
3212     return new DULCPap(ex, origin, fence, array,
3213     compoundIndexedOp(this.op, mapper));
3214     }
3215    
3216     void leafApply(int lo, int hi, Procedure procedure) {
3217     final IntAndDoubleToObject f = op;
3218     final double[] a = this.array;
3219     for (int i = lo; i < hi; ++i)
3220     procedure.op(f.op(i, a[i]));
3221     }
3222    
3223     Object leafReduce(int lo, int hi, Reducer reducer, Object base) {
3224     if (lo >= hi)
3225     return base;
3226     final double[] a = this.array;
3227     final IntAndDoubleToObject f = op;
3228     Object r = f.op(lo, a[lo]);
3229     for (int i = lo+1; i < hi; ++i)
3230     r = reducer.op(r, f.op(i, a[i]));
3231     return r;
3232     }
3233    
3234     }
3235    
3236     static final class LUOCPap<U> extends LOCPap<U> {
3237     LUOCPap(ForkJoinPool ex, int origin, int fence,
3238     long[] array, IntAndLongToObject<? extends U> op) {
3239     super(ex, origin, fence, array, op);
3240     }
3241    
3242     public <V> ParallelLongArrayWithMapping< V> withMapping
3243     (Op<? super U, ? extends V> op) {
3244     return new LUOCPap<V>(ex, origin, fence, array,
3245     compoundIndexedOp(this.op, op));
3246     }
3247    
3248     public ParallelLongArrayWithDoubleMapping withMapping
3249     (ObjectToDouble<? super U> op) {
3250     return new LUDCPap(ex, origin, fence, array,
3251     compoundIndexedOp(this.op, op));
3252     }
3253    
3254     public ParallelLongArrayWithLongMapping withMapping
3255     (ObjectToLong<? super U> op) {
3256     return new LULCPap(ex, origin, fence, array,
3257     compoundIndexedOp(this.op, op));
3258     }
3259    
3260     public <V> ParallelLongArrayWithMapping<V> withIndexedMapping
3261     (IntAndObjectToObject<? super U, ? extends V> mapper) {
3262     return new LUOCPap<V>(ex, origin, fence, array,
3263     compoundIndexedOp(this.op, mapper));
3264     }
3265    
3266     public ParallelLongArrayWithDoubleMapping withIndexedMapping
3267     (IntAndObjectToDouble<? super U> mapper) {
3268     return new LUDCPap(ex, origin, fence, array,
3269     compoundIndexedOp(this.op, mapper));
3270     }
3271    
3272     public ParallelLongArrayWithLongMapping withIndexedMapping
3273     (IntAndObjectToLong<? super U> mapper) {
3274     return new LULCPap(ex, origin, fence, array,
3275     compoundIndexedOp(this.op, mapper));
3276     }
3277    
3278     void leafApply(int lo, int hi, Procedure procedure) {
3279     final IntAndLongToObject f = op;
3280     final long[] a = this.array;
3281     for (int i = lo; i < hi; ++i)
3282     procedure.op(f.op(i, a[i]));
3283     }
3284    
3285     Object leafReduce(int lo, int hi, Reducer reducer, Object base) {
3286     if (lo >= hi)
3287     return base;
3288     final long[] a = this.array;
3289     final IntAndLongToObject f = op;
3290     Object r = f.op(lo, a[lo]);
3291     for (int i = lo+1; i < hi; ++i)
3292     r = reducer.op(r, f.op(i, a[i]));
3293     return r;
3294     }
3295    
3296     }
3297    
3298     // object-combined filtered
3299    
3300     static final class OFOCPap<T,U> extends OOCPap<T,U> {
3301     final Predicate<? super T> selector;
3302     OFOCPap(ForkJoinPool ex, int origin, int fence,
3303     T[] array, Predicate<? super T> selector,
3304     IntAndObjectToObject<? super T, ? extends U> op) {
3305     super(ex, origin, fence, array, op);
3306     this.selector = selector;
3307     }
3308    
3309     boolean hasFilter() { return true; }
3310     boolean isSelected(int i) { return selector.op(this.array[i]); }
3311    
3312     public <V> ParallelArrayWithMapping<T, V> withMapping
3313     (Op<? super U, ? extends V> op) {
3314     return new OFOCPap<T,V>(ex, origin, fence, array, selector,
3315     compoundIndexedOp(this.op, op));
3316     }
3317    
3318     public ParallelArrayWithDoubleMapping<T> withMapping
3319     (ObjectToDouble<? super U> op) {
3320     return new OFDCPap<T>(ex, origin, fence, array, selector,
3321     compoundIndexedOp(this.op, op));
3322     }
3323    
3324     public ParallelArrayWithLongMapping<T> withMapping
3325     (ObjectToLong<? super U> op) {
3326     return new OFLCPap<T>(ex, origin, fence, array, selector,
3327     compoundIndexedOp(this.op, op));
3328     }
3329    
3330     public <V> ParallelArrayWithMapping<T,V> withIndexedMapping
3331     (IntAndObjectToObject<? super U, ? extends V> mapper) {
3332     return new OFOCPap<T,V>(ex, origin, fence, array, selector,
3333     compoundIndexedOp(this.op, mapper));
3334     }
3335    
3336     public ParallelArrayWithDoubleMapping<T> withIndexedMapping
3337     (IntAndObjectToDouble<? super U> mapper) {
3338     return new OFDCPap<T>(ex, origin, fence, array, selector,
3339     compoundIndexedOp(this.op, mapper));
3340     }
3341    
3342     public ParallelArrayWithLongMapping<T> withIndexedMapping
3343     (IntAndObjectToLong<? super U> mapper) {
3344     return new OFLCPap<T>
3345     (ex, origin, fence, array, selector,
3346     compoundIndexedOp
3347     (this.op, mapper));
3348     }
3349    
3350     void leafApply(int lo, int hi, Procedure procedure) {
3351     final Predicate s = selector;
3352     final Object[] a = this.array;
3353     final IntAndObjectToObject f = op;
3354     for (int i = lo; i < hi; ++i) {
3355     Object x = a[i];
3356     if (s.op(x))
3357     procedure.op(f.op(i, x));
3358     }
3359     }
3360     Object leafReduce(int lo, int hi, Reducer reducer, Object base) {
3361     final Predicate s = selector;
3362     final Object[] a = this.array;
3363     final IntAndObjectToObject f = op;
3364     boolean gotFirst = false;
3365     Object r = base;
3366     for (int i = lo; i < hi; ++i) {
3367     Object x = a[i];
3368     if (s.op(x)) {
3369     Object y = f.op(i, x);
3370     if (!gotFirst) {
3371     gotFirst = true;
3372     r = y;
3373     }
3374     else
3375     r = reducer.op(r, y);
3376     }
3377     }
3378     return r;
3379     }
3380     }
3381    
3382     static final class DFOCPap<U> extends DOCPap<U> {
3383     final DoublePredicate selector;
3384     DFOCPap(ForkJoinPool ex, int origin, int fence,
3385     double[] array, DoublePredicate selector,
3386     IntAndDoubleToObject<? extends U> op) {
3387     super(ex, origin, fence, array, op);
3388     this.selector = selector;
3389     }
3390    
3391     boolean hasFilter() { return true; }
3392     boolean isSelected(int i) { return selector.op(this.array[i]); }
3393    
3394     public <V> ParallelDoubleArrayWithMapping< V> withMapping
3395     (Op<? super U, ? extends V> op) {
3396     return new DFOCPap<V>(ex, origin, fence, array, selector,
3397     compoundIndexedOp(this.op, op));
3398     }
3399    
3400     public ParallelDoubleArrayWithDoubleMapping withMapping
3401     (ObjectToDouble<? super U> op) {
3402     return new DFDCPap(ex, origin, fence, array, selector,
3403     compoundIndexedOp(this.op, op));
3404     }
3405    
3406     public ParallelDoubleArrayWithLongMapping withMapping
3407     (ObjectToLong<? super U> op) {
3408     return new DFLCPap(ex, origin, fence, array, selector,
3409     compoundIndexedOp(this.op, op));
3410     }
3411    
3412     public <V> ParallelDoubleArrayWithMapping<V> withIndexedMapping
3413     (IntAndObjectToObject<? super U, ? extends V> mapper) {
3414     return new DFOCPap<V>(ex, origin, fence, array, selector,
3415     compoundIndexedOp(this.op, mapper));
3416     }
3417    
3418     public ParallelDoubleArrayWithDoubleMapping withIndexedMapping
3419     (IntAndObjectToDouble<? super U> mapper) {
3420     return new DFDCPap(ex, origin, fence, array, selector,
3421     compoundIndexedOp(this.op, mapper));
3422     }
3423    
3424     public ParallelDoubleArrayWithLongMapping withIndexedMapping
3425     (IntAndObjectToLong<? super U> mapper) {
3426     return new DFLCPap(ex, origin, fence, array, selector,
3427     compoundIndexedOp(this.op, mapper));
3428     }
3429    
3430     void leafApply(int lo, int hi, Procedure procedure) {
3431     final DoublePredicate s = selector;
3432     final double[] a = this.array;
3433     final IntAndDoubleToObject f = op;
3434     for (int i = lo; i < hi; ++i) {
3435     double x = a[i];
3436     if (s.op(x))
3437     procedure.op(f.op(i, x));
3438     }
3439     }
3440     Object leafReduce(int lo, int hi, Reducer reducer, Object base) {
3441     final DoublePredicate s = selector;
3442     final double[] a = this.array;
3443     final IntAndDoubleToObject f = op;
3444     boolean gotFirst = false;
3445     Object r = base;
3446     for (int i = lo; i < hi; ++i) {
3447     double x = a[i];
3448     if (s.op(x)) {
3449     Object y = f.op(i, x);
3450     if (!gotFirst) {
3451     gotFirst = true;
3452     r = y;
3453     }
3454     else
3455     r = reducer.op(r, y);
3456     }
3457     }
3458     return r;
3459     }
3460     }
3461    
3462     static final class LFOCPap<U> extends LOCPap<U> {
3463     final LongPredicate selector;
3464     LFOCPap(ForkJoinPool ex, int origin, int fence,
3465     long[] array, LongPredicate selector,
3466     IntAndLongToObject<? extends U> op) {
3467     super(ex, origin, fence, array, op);
3468     this.selector = selector;
3469     }
3470    
3471     boolean hasFilter() { return true; }
3472     boolean isSelected(int i) { return selector.op(this.array[i]); }
3473    
3474     public <V> ParallelLongArrayWithMapping< V> withMapping
3475     (Op<? super U, ? extends V> op) {
3476     return new LFOCPap<V>(ex, origin, fence, array, selector,
3477     compoundIndexedOp(this.op, op));
3478     }
3479    
3480     public ParallelLongArrayWithDoubleMapping withMapping
3481     (ObjectToDouble<? super U> op) {
3482     return new LFDCPap(ex, origin, fence, array, selector,
3483     compoundIndexedOp(this.op, op));
3484     }
3485    
3486     public ParallelLongArrayWithLongMapping withMapping
3487     (ObjectToLong<? super U> op) {
3488     return new LFLCPap(ex, origin, fence, array, selector,
3489     compoundIndexedOp(this.op, op));
3490     }
3491    
3492     public <V> ParallelLongArrayWithMapping<V> withIndexedMapping
3493     (IntAndObjectToObject<? super U, ? extends V> mapper) {
3494     return new LFOCPap<V>(ex, origin, fence, array, selector,
3495     compoundIndexedOp(this.op, mapper));
3496     }
3497    
3498     public ParallelLongArrayWithDoubleMapping withIndexedMapping
3499     (IntAndObjectToDouble<? super U> mapper) {
3500     return new LFDCPap(ex, origin, fence, array, selector,
3501     compoundIndexedOp(this.op, mapper));
3502     }
3503    
3504     public ParallelLongArrayWithLongMapping withIndexedMapping
3505     (IntAndObjectToLong<? super U> mapper) {
3506     return new LFLCPap(ex, origin, fence, array, selector,
3507     compoundIndexedOp(this.op, mapper));
3508     }
3509    
3510     void leafApply(int lo, int hi, Procedure procedure) {
3511     final LongPredicate s = selector;
3512     final long[] a = this.array;
3513     final IntAndLongToObject f = op;
3514     for (int i = lo; i < hi; ++i) {
3515     long x = a[i];
3516     if (s.op(x))
3517     procedure.op(f.op(i, x));
3518     }
3519     }
3520     Object leafReduce(int lo, int hi, Reducer reducer, Object base) {
3521     final LongPredicate s = selector;
3522     final long[] a = this.array;
3523     final IntAndLongToObject f = op;
3524     boolean gotFirst = false;
3525     Object r = base;
3526     for (int i = lo; i < hi; ++i) {
3527     long x = a[i];
3528     if (s.op(x)) {
3529     Object y = f.op(i, x);
3530     if (!gotFirst) {
3531     gotFirst = true;
3532     r = y;
3533     }
3534     else
3535     r = reducer.op(r, y);
3536     }
3537     }
3538     return r;
3539     }
3540     }
3541    
3542     // Object-combined, relational
3543     static final class OROCPap<T,U> extends OOCPap<T,U> {
3544     final IntAndObjectPredicate<? super T> selector;
3545     OROCPap(ForkJoinPool ex, int origin, int fence,
3546     T[] array, IntAndObjectPredicate<? super T> selector,
3547     IntAndObjectToObject<? super T, ? extends U> op) {
3548     super(ex, origin, fence, array, op);
3549     this.selector = selector;
3550     }
3551    
3552     boolean hasFilter() { return true; }
3553     boolean isSelected(int i) { return selector.op(i, this.array[i]); }
3554    
3555     public <V> ParallelArrayWithMapping<T, V> withMapping
3556     (Op<? super U, ? extends V> op) {
3557     return new OROCPap<T,V>(ex, origin, fence, array, selector,
3558     compoundIndexedOp(this.op, op));
3559     }
3560    
3561     public ParallelArrayWithDoubleMapping<T> withMapping
3562     (ObjectToDouble<? super U> op) {
3563     return new ORDCPap<T>(ex, origin, fence, array, selector,
3564     compoundIndexedOp(this.op, op));
3565     }
3566    
3567     public ParallelArrayWithLongMapping<T> withMapping
3568     (ObjectToLong<? super U> op) {
3569     return new ORLCPap<T>(ex, origin, fence, array, selector,
3570     compoundIndexedOp(this.op, op));
3571     }
3572    
3573     public <V> ParallelArrayWithMapping<T,V> withIndexedMapping
3574     (IntAndObjectToObject<? super U, ? extends V> mapper) {
3575     return new OROCPap<T,V>(ex, origin, fence, array, selector,
3576     compoundIndexedOp(this.op, mapper));
3577     }
3578    
3579     public ParallelArrayWithDoubleMapping<T> withIndexedMapping
3580     (IntAndObjectToDouble<? super U> mapper) {
3581     return new ORDCPap<T>(ex, origin, fence, array, selector,
3582     compoundIndexedOp(this.op, mapper));
3583     }
3584    
3585     public ParallelArrayWithLongMapping<T> withIndexedMapping
3586     (IntAndObjectToLong<? super U> mapper) {
3587     return new ORLCPap<T>
3588     (ex, origin, fence, array, selector,
3589     compoundIndexedOp
3590     (this.op, mapper));
3591     }
3592    
3593     void leafApply(int lo, int hi, Procedure procedure) {
3594     final IntAndObjectPredicate s = selector;
3595     final Object[] a = this.array;
3596     final IntAndObjectToObject f = op;
3597     for (int i = lo; i < hi; ++i) {
3598     Object x = a[i];
3599     if (s.op(i, x))
3600     procedure.op(f.op(i, x));
3601     }
3602     }
3603     Object leafReduce(int lo, int hi, Reducer reducer, Object base) {
3604     final IntAndObjectPredicate s = selector;
3605     final Object[] a = this.array;
3606     final IntAndObjectToObject f = op;
3607     boolean gotFirst = false;
3608     Object r = base;
3609     for (int i = lo; i < hi; ++i) {
3610     Object x = a[i];
3611     if (s.op(i, x)) {
3612     Object y = f.op(i, x);
3613     if (!gotFirst) {
3614     gotFirst = true;
3615     r = y;
3616     }
3617     else
3618     r = reducer.op(r, y);
3619     }
3620     }
3621     return r;
3622     }
3623     }
3624    
3625     static final class DROCPap<U> extends DOCPap<U> {
3626     final IntAndDoublePredicate selector;
3627     DROCPap(ForkJoinPool ex, int origin, int fence,
3628     double[] array, IntAndDoublePredicate selector,
3629     IntAndDoubleToObject<? extends U> op) {
3630     super(ex, origin, fence, array, op);
3631     this.selector = selector;
3632     }
3633    
3634     boolean hasFilter() { return true; }
3635     boolean isSelected(int i) { return selector.op(i, this.array[i]); }
3636    
3637     public <V> ParallelDoubleArrayWithMapping< V> withMapping
3638     (Op<? super U, ? extends V> op) {
3639     return new DROCPap<V>(ex, origin, fence, array, selector,
3640     compoundIndexedOp(this.op, op));
3641     }
3642    
3643     public ParallelDoubleArrayWithDoubleMapping withMapping
3644     (ObjectToDouble<? super U> op) {
3645     return new DRDCPap(ex, origin, fence, array, selector,
3646     compoundIndexedOp(this.op, op));
3647     }
3648    
3649     public ParallelDoubleArrayWithLongMapping withMapping
3650     (ObjectToLong<? super U> op) {
3651     return new DRLCPap(ex, origin, fence, array, selector,
3652     compoundIndexedOp(this.op, op));
3653     }
3654    
3655     public <V> ParallelDoubleArrayWithMapping<V> withIndexedMapping
3656     (IntAndObjectToObject<? super U, ? extends V> mapper) {
3657     return new DROCPap<V>(ex, origin, fence, array, selector,
3658     compoundIndexedOp(this.op, mapper));
3659     }
3660    
3661     public ParallelDoubleArrayWithDoubleMapping withIndexedMapping
3662     (IntAndObjectToDouble<? super U> mapper) {
3663     return new DRDCPap(ex, origin, fence, array, selector,
3664     compoundIndexedOp(this.op, mapper));
3665     }
3666    
3667     public ParallelDoubleArrayWithLongMapping withIndexedMapping
3668     (IntAndObjectToLong<? super U> mapper) {
3669     return new DRLCPap(ex, origin, fence, array, selector,
3670     compoundIndexedOp(this.op, mapper));
3671     }
3672    
3673     void leafApply(int lo, int hi, Procedure procedure) {
3674     final IntAndDoublePredicate s = selector;
3675     final double[] a = this.array;
3676     final IntAndDoubleToObject f = op;
3677     for (int i = lo; i < hi; ++i) {
3678     double x = a[i];
3679     if (s.op(i, x))
3680     procedure.op(f.op(i, x));
3681     }
3682     }
3683     Object leafReduce(int lo, int hi, Reducer reducer, Object base) {
3684     final IntAndDoublePredicate s = selector;
3685     final double[] a = this.array;
3686     final IntAndDoubleToObject f = op;
3687     boolean gotFirst = false;
3688     Object r = base;
3689     for (int i = lo; i < hi; ++i) {
3690     double x = a[i];
3691     if (s.op(i, x)) {
3692     Object y = f.op(i, x);
3693     if (!gotFirst) {
3694     gotFirst = true;
3695     r = y;
3696     }
3697     else
3698     r = reducer.op(r, y);
3699     }
3700     }
3701     return r;
3702     }
3703     }
3704    
3705     static final class LROCPap<U> extends LOCPap<U> {
3706     final IntAndLongPredicate selector;
3707     LROCPap(ForkJoinPool ex, int origin, int fence,
3708     long[] array, IntAndLongPredicate selector,
3709     IntAndLongToObject<? extends U> op) {
3710     super(ex, origin, fence, array, op);
3711     this.selector = selector;
3712     }
3713    
3714     boolean hasFilter() { return true; }
3715     boolean isSelected(int i) { return selector.op(i, this.array[i]); }
3716    
3717     public <V> ParallelLongArrayWithMapping< V> withMapping
3718     (Op<? super U, ? extends V> op) {
3719     return new LROCPap<V>(ex, origin, fence, array, selector,
3720     compoundIndexedOp(this.op, op));
3721     }
3722    
3723     public ParallelLongArrayWithDoubleMapping withMapping
3724     (ObjectToDouble<? super U> op) {
3725     return new LRDCPap(ex, origin, fence, array, selector,
3726     compoundIndexedOp(this.op, op));
3727     }
3728    
3729     public ParallelLongArrayWithLongMapping withMapping
3730     (ObjectToLong<? super U> op) {
3731     return new LRLCPap(ex, origin, fence, array, selector,
3732     compoundIndexedOp(this.op, op));
3733     }
3734    
3735     public <V> ParallelLongArrayWithMapping<V> withIndexedMapping
3736     (IntAndObjectToObject<? super U, ? extends V> mapper) {
3737     return new LROCPap<V>(ex, origin, fence, array, selector,
3738     compoundIndexedOp(this.op, mapper));
3739     }
3740    
3741     public ParallelLongArrayWithDoubleMapping withIndexedMapping
3742     (IntAndObjectToDouble<? super U> mapper) {
3743     return new LRDCPap(ex, origin, fence, array, selector,
3744     compoundIndexedOp(this.op, mapper));
3745     }
3746    
3747     public ParallelLongArrayWithLongMapping withIndexedMapping
3748     (IntAndObjectToLong<? super U> mapper) {
3749     return new LRLCPap(ex, origin, fence, array, selector,
3750     compoundIndexedOp(this.op, mapper));
3751     }
3752    
3753     void leafApply(int lo, int hi, Procedure procedure) {
3754     final IntAndLongPredicate s = selector;
3755     final long[] a = this.array;
3756     final IntAndLongToObject f = op;
3757     for (int i = lo; i < hi; ++i) {
3758     long x = a[i];
3759     if (s.op(i, x))
3760     procedure.op(f.op(i, x));
3761     }
3762     }
3763     Object leafReduce(int lo, int hi, Reducer reducer, Object base) {
3764     final IntAndLongPredicate s = selector;
3765     final long[] a = this.array;
3766     final IntAndLongToObject f = op;
3767     boolean gotFirst = false;
3768     Object r = base;
3769     for (int i = lo; i < hi; ++i) {
3770     long x = a[i];
3771     if (s.op(i, x)) {
3772     Object y = f.op(i, x);
3773     if (!gotFirst) {
3774     gotFirst = true;
3775     r = y;
3776     }
3777     else
3778     r = reducer.op(r, y);
3779     }
3780     }
3781     return r;
3782     }
3783     }
3784    
3785     // Double-mapped
3786    
3787     static abstract class ODMPap<T> extends ParallelArrayWithDoubleMapping<T> {
3788     final ObjectToDouble<? super T> op;
3789     ODMPap(ForkJoinPool ex, int origin, int fence,
3790     T[] array, ObjectToDouble<? super T> op) {
3791     super(ex, origin, fence, array);
3792     this.op = op;
3793     }
3794    
3795     final boolean hasMap() { return true; }
3796     final double dget(int i) { return op.op(this.array[i]); }
3797     final Object oget(int i) { return Double.valueOf(dget(i)); }
3798     final long lget(int i) { return (long)(dget(i)); }
3799    
3800     final void leafTransfer(int lo, int hi, double[] dest, int offset) {
3801     final ObjectToDouble f = op;
3802     final Object[] a = this.array;
3803     for (int i = lo; i < hi; ++i)
3804     dest[offset++] = f.op(a[i]);
3805     }
3806    
3807     final void leafTransferByIndex(int[] indices, int loIdx, int hiIdx,
3808     double[] dest, int offset) {
3809     final Object[] a = this.array;
3810     final ObjectToDouble f = op;
3811     for (int i = loIdx; i < hiIdx; ++i)
3812     dest[offset++] = f.op(a[indices[i]]);
3813     }
3814    
3815     }
3816    
3817     static abstract class DDMPap extends ParallelDoubleArrayWithDoubleMapping {
3818     final DoubleOp op;
3819     DDMPap
3820     (ForkJoinPool ex, int origin, int fence,
3821     double[] array, DoubleOp op) {
3822     super(ex, origin, fence, array);
3823     this.op = op;
3824     }
3825    
3826     final boolean hasMap() { return true; }
3827     final double dget(int i) { return op.op(this.array[i]); }
3828     final Object oget(int i) { return Double.valueOf(dget(i)); }
3829     final long lget(int i) { return (long)(dget(i)); }
3830    
3831     final void leafTransfer(int lo, int hi, double[] dest, int offset) {
3832     final double[] a = this.array;
3833     final DoubleOp f = op;
3834     for (int i = lo; i < hi; ++i)
3835     dest[offset++] = f.op(a[i]);
3836     }
3837    
3838     final void leafTransferByIndex(int[] indices, int loIdx, int hiIdx,
3839     double[] dest, int offset) {
3840     final double[] a = this.array;
3841     final DoubleOp f = op;
3842     for (int i = loIdx; i < hiIdx; ++i)
3843     dest[offset++] = f.op(a[indices[i]]);
3844     }
3845     }
3846    
3847     static abstract class LDMPap extends ParallelLongArrayWithDoubleMapping {
3848     final LongToDouble op;
3849     LDMPap(ForkJoinPool ex, int origin, int fence,
3850     long[] array, LongToDouble op) {
3851     super(ex, origin, fence, array);
3852     this.op = op;
3853     }
3854    
3855     final boolean hasMap() { return true; }
3856     final double dget(int i) { return op.op(this.array[i]); }
3857     final Object oget(int i) { return Double.valueOf(dget(i)); }
3858     final long lget(int i) { return (long)(dget(i)); }
3859    
3860     final void leafTransfer(int lo, int hi, double[] dest, int offset) {
3861     final long[] a = this.array;
3862     final LongToDouble f = op;
3863     for (int i = lo; i < hi; ++i)
3864     dest[offset++] = f.op(a[i]);
3865     }
3866    
3867     final void leafTransferByIndex(int[] indices, int loIdx, int hiIdx,
3868     double[] dest, int offset) {
3869     final long[] a = this.array;
3870     final LongToDouble f = op;
3871     for (int i = loIdx; i < hiIdx; ++i)
3872     dest[offset++] = f.op(a[indices[i]]);
3873     }
3874    
3875     }
3876    
3877     // double-mapped, unfiltered
3878    
3879     static final class OUDMPap<T> extends ODMPap<T> {
3880     OUDMPap(ForkJoinPool ex, int origin, int fence,
3881     T[] array, ObjectToDouble<? super T> op) {
3882     super(ex, origin, fence, array, op);
3883     }
3884    
3885     public ParallelArrayWithDoubleMapping<T> withMapping(DoubleOp op) {
3886     return new OUDMPap<T>(ex, origin, fence, array,
3887     CommonOps.compoundOp(this.op, op));
3888     }
3889    
3890     public ParallelArrayWithLongMapping<T> withMapping(DoubleToLong op) {
3891     return new OULMPap<T>(ex, origin, fence, array,
3892     CommonOps.compoundOp(this.op, op));
3893     }
3894    
3895     public <U> ParallelArrayWithMapping<T, U> withMapping
3896     (DoubleToObject<? extends U> op) {
3897     return new OUOMPap<T,U>(ex, origin, fence, array,
3898     CommonOps.compoundOp(this.op, op));
3899     }
3900    
3901     public <V> ParallelArrayWithMapping<T,V> withIndexedMapping
3902     (IntAndDoubleToObject<? extends V> mapper) {
3903     return new OUOCPap<T,V>(ex, origin, fence, array,
3904     compoundIndexedOp(this.op, mapper));
3905     }
3906    
3907     public ParallelArrayWithDoubleMapping<T> withIndexedMapping
3908     (IntAndDoubleToDouble mapper) {
3909     return new OUDCPap<T>(ex, origin, fence, array,
3910     compoundIndexedOp(this.op, mapper));
3911     }
3912    
3913     public ParallelArrayWithLongMapping<T> withIndexedMapping
3914     (IntAndDoubleToLong mapper) {
3915     return new OULCPap<T>(ex, origin, fence, array,
3916     compoundIndexedOp(this.op, mapper));
3917     }
3918    
3919     void leafApply(int lo, int hi, DoubleProcedure procedure) {
3920     final ObjectToDouble f = op;
3921     final Object[] a = this.array;
3922     for (int i = lo; i < hi; ++i)
3923     procedure.op(f.op(a[i]));
3924     }
3925    
3926     double leafReduce(int lo, int hi, DoubleReducer reducer, double base) {
3927     if (lo >= hi)
3928     return base;
3929     final Object[] a = this.array;
3930     final ObjectToDouble f = op;
3931     double r = f.op(a[lo]);
3932     for (int i = lo+1; i < hi; ++i)
3933     r = reducer.op(r, f.op(a[i]));
3934     return r;
3935     }
3936    
3937     }
3938    
3939     static final class DUDMPap extends DDMPap {
3940     DUDMPap(ForkJoinPool ex, int origin, int fence,
3941     double[] array, DoubleOp op) {
3942     super(ex, origin, fence, array, op);
3943     }
3944    
3945     public ParallelDoubleArrayWithDoubleMapping withMapping(DoubleOp op) {
3946     return new DUDMPap(ex, origin, fence, array,
3947     CommonOps.compoundOp(this.op, op));
3948     }
3949    
3950     public ParallelDoubleArrayWithLongMapping withMapping(DoubleToLong op) {
3951     return new DULMPap(ex, origin, fence, array,
3952     CommonOps.compoundOp(this.op, op));
3953     }
3954    
3955     public <U> ParallelDoubleArrayWithMapping<U> withMapping
3956     (DoubleToObject<? extends U> op) {
3957     return new DUOMPap<U>(ex, origin, fence, array,
3958     CommonOps.compoundOp(this.op, op));
3959     }
3960    
3961     public <V> ParallelDoubleArrayWithMapping<V> withIndexedMapping
3962     (IntAndDoubleToObject<? extends V> mapper) {
3963     return new DUOCPap<V>(ex, origin, fence, array,
3964     compoundIndexedOp(this.op, mapper));
3965     }
3966    
3967     public ParallelDoubleArrayWithDoubleMapping withIndexedMapping
3968     (IntAndDoubleToDouble mapper) {
3969     return new DUDCPap(ex, origin, fence, array,
3970     compoundIndexedOp(this.op, mapper));
3971     }
3972    
3973     public ParallelDoubleArrayWithLongMapping withIndexedMapping
3974     (IntAndDoubleToLong mapper) {
3975     return new DULCPap(ex, origin, fence, array,
3976     compoundIndexedOp(this.op, mapper));
3977     }
3978    
3979     void leafApply(int lo, int hi, DoubleProcedure procedure) {
3980     final double[] a = this.array;
3981     final DoubleOp f = op;
3982     for (int i = lo; i < hi; ++i)
3983     procedure.op(f.op(a[i]));
3984     }
3985    
3986     double leafReduce(int lo, int hi, DoubleReducer reducer, double base) {
3987     if (lo >= hi)
3988     return base;
3989     final double[] a = this.array;
3990     final DoubleOp f = op;
3991     double r = f.op(a[lo]);
3992     for (int i = lo+1; i < hi; ++i)
3993     r = reducer.op(r, f.op(a[i]));
3994     return r;
3995     }
3996    
3997     }
3998    
3999     static final class LUDMPap extends LDMPap {
4000     LUDMPap(ForkJoinPool ex, int origin, int fence,
4001     long[] array, LongToDouble op) {
4002     super(ex, origin, fence, array, op);
4003     }
4004    
4005     public ParallelLongArrayWithLongMapping withMapping(DoubleToLong op) {
4006     return new LULMPap(ex, origin, fence, array,
4007     CommonOps.compoundOp(this.op, op));
4008     }
4009    
4010     public ParallelLongArrayWithDoubleMapping withMapping(DoubleOp op) {
4011     return new LUDMPap(ex, origin, fence, array,
4012     CommonOps.compoundOp(this.op, op));
4013     }
4014    
4015     public <U> ParallelLongArrayWithMapping<U> withMapping
4016     (DoubleToObject<? extends U> op) {
4017     return new LUOMPap<U>(ex, origin, fence, array,
4018     CommonOps.compoundOp(this.op, op));
4019     }
4020    
4021     public <V> ParallelLongArrayWithMapping<V> withIndexedMapping
4022     (IntAndDoubleToObject<? extends V> mapper) {
4023     return new LUOCPap<V>(ex, origin, fence, array,
4024     compoundIndexedOp(this.op, mapper));
4025     }
4026    
4027     public ParallelLongArrayWithDoubleMapping withIndexedMapping
4028     (IntAndDoubleToDouble mapper) {
4029     return new LUDCPap(ex, origin, fence, array,
4030     compoundIndexedOp(this.op, mapper));
4031     }
4032    
4033     public ParallelLongArrayWithLongMapping withIndexedMapping
4034     (IntAndDoubleToLong mapper) {
4035     return new LULCPap(ex, origin, fence, array,
4036     compoundIndexedOp(this.op, mapper));
4037     }
4038    
4039     void leafApply(int lo, int hi, DoubleProcedure procedure) {
4040     final LongToDouble f = op;
4041     final long[] a = this.array;
4042     for (int i = lo; i < hi; ++i)
4043     procedure.op(f.op(a[i]));
4044     }
4045    
4046     double leafReduce(int lo, int hi, DoubleReducer reducer, double base) {
4047     if (lo >= hi)
4048     return base;
4049     final long[] a = this.array;
4050     final LongToDouble f = op;
4051     double r = f.op(a[lo]);
4052     for (int i = lo+1; i < hi; ++i)
4053     r = reducer.op(r, f.op(a[i]));
4054     return r;
4055     }
4056    
4057     }
4058    
4059     // double-mapped, filtered
4060    
4061     static final class OFDMPap<T> extends ODMPap<T> {
4062     final Predicate<? super T> selector;
4063     OFDMPap(ForkJoinPool ex, int origin, int fence,
4064     T[] array, Predicate<? super T> selector,
4065     ObjectToDouble<? super T> op) {
4066     super(ex, origin, fence, array, op);
4067     this.selector = selector;
4068     }
4069    
4070     boolean hasFilter() { return true; }
4071     boolean isSelected(int i) { return selector.op(this.array[i]); }
4072    
4073     public ParallelArrayWithDoubleMapping<T> withMapping(DoubleOp op) {
4074     return new OFDMPap<T>(ex, origin, fence, array, selector,
4075     CommonOps.compoundOp(this.op, op));
4076     }
4077    
4078     public ParallelArrayWithLongMapping<T> withMapping(DoubleToLong op) {
4079     return new OFLMPap<T>(ex, origin, fence, array, selector,
4080     CommonOps.compoundOp(this.op, op));
4081     }
4082    
4083     public <U> ParallelArrayWithMapping<T, U> withMapping
4084     (DoubleToObject<? extends U> op) {
4085     return new OFOMPap<T,U>(ex, origin, fence, array, selector,
4086     CommonOps.compoundOp(this.op, op));
4087     }
4088    
4089     public <V> ParallelArrayWithMapping<T,V> withIndexedMapping
4090     (IntAndDoubleToObject<? extends V> mapper) {
4091     return new OFOCPap<T,V>(ex, origin, fence, array, selector,
4092     compoundIndexedOp(this.op, mapper));
4093     }
4094    
4095     public ParallelArrayWithDoubleMapping<T> withIndexedMapping
4096     (IntAndDoubleToDouble mapper) {
4097     return new OFDCPap<T>(ex, origin, fence, array, selector,
4098     compoundIndexedOp(this.op, mapper));
4099     }
4100    
4101     public ParallelArrayWithLongMapping<T> withIndexedMapping
4102     (IntAndDoubleToLong mapper) {
4103     return new OFLCPap<T>(ex, origin, fence, array, selector,
4104     compoundIndexedOp(this.op, mapper));
4105     }
4106    
4107     void leafApply(int lo, int hi, DoubleProcedure procedure) {
4108     final Predicate s = selector;
4109     final Object[] a = this.array;
4110     final ObjectToDouble f = op;
4111     for (int i = lo; i < hi; ++i) {
4112     Object x = a[i];
4113     if (s.op(x))
4114     procedure.op(f.op(x));
4115     }
4116     }
4117    
4118     double leafReduce(int lo, int hi, DoubleReducer reducer, double base) {
4119     final Predicate s = selector;
4120     final ObjectToDouble f = op;
4121     boolean gotFirst = false;
4122     double r = base;
4123     final Object[] a = this.array;
4124     for (int i = lo; i < hi; ++i) {
4125     Object t = a[i];
4126     if (s.op(t)) {
4127     double y = f.op(t);
4128     if (!gotFirst) {
4129     gotFirst = true;
4130     r = y;
4131     }
4132     else
4133     r = reducer.op(r, y);
4134     }
4135     }
4136     return r;
4137     }
4138     }
4139    
4140     static final class DFDMPap extends DDMPap {
4141     final DoublePredicate selector;
4142     DFDMPap(ForkJoinPool ex, int origin, int fence,
4143     double[] array, DoublePredicate selector, DoubleOp op) {
4144     super(ex, origin, fence, array, op);
4145     this.selector = selector;
4146     }
4147    
4148     boolean hasFilter() { return true; }
4149     boolean isSelected(int i) { return selector.op(this.array[i]); }
4150    
4151     public ParallelDoubleArrayWithDoubleMapping withMapping(DoubleOp op) {
4152     return new DFDMPap(ex, origin, fence, array, selector,
4153     CommonOps.compoundOp(this.op, op));
4154     }
4155    
4156     public ParallelDoubleArrayWithLongMapping withMapping(DoubleToLong op) {
4157     return new DFLMPap(ex, origin, fence, array, selector,
4158     CommonOps.compoundOp(this.op, op));
4159     }
4160    
4161     public <U> ParallelDoubleArrayWithMapping<U> withMapping
4162     (DoubleToObject<? extends U> op) {
4163     return new DFOMPap<U>(ex, origin, fence, array, selector,
4164     CommonOps.compoundOp(this.op, op));
4165     }
4166    
4167     public <V> ParallelDoubleArrayWithMapping<V> withIndexedMapping
4168     (IntAndDoubleToObject<? extends V> mapper) {
4169     return new DFOCPap<V>(ex, origin, fence, array, selector,
4170     compoundIndexedOp(this.op, mapper));
4171     }
4172    
4173     public ParallelDoubleArrayWithDoubleMapping withIndexedMapping
4174     (IntAndDoubleToDouble mapper) {
4175     return new DFDCPap(ex, origin, fence, array, selector,
4176     compoundIndexedOp(this.op, mapper));
4177     }
4178    
4179     public ParallelDoubleArrayWithLongMapping withIndexedMapping
4180     (IntAndDoubleToLong mapper) {
4181     return new DFLCPap(ex, origin, fence, array, selector,
4182     compoundIndexedOp(this.op, mapper));
4183     }
4184    
4185     void leafApply(int lo, int hi, DoubleProcedure procedure) {
4186     final DoublePredicate s = selector;
4187     final DoubleOp f = op;
4188     final double[] a = this.array;
4189     for (int i = lo; i < hi; ++i) {
4190     double x = a[i];
4191     if (s.op(x))
4192     procedure.op(f.op(x));
4193     }
4194     }
4195    
4196     double leafReduce(int lo, int hi, DoubleReducer reducer, double base) {
4197     final DoublePredicate s = selector;
4198     boolean gotFirst = false;
4199     double r = base;
4200     final double[] a = this.array;
4201     final DoubleOp f = op;
4202     for (int i = lo; i < hi; ++i) {
4203     double t = a[i];
4204     if (s.op(t)) {
4205     double y = f.op(t);
4206     if (!gotFirst) {
4207     gotFirst = true;
4208     r = y;
4209     }
4210     else
4211     r = reducer.op(r, y);
4212     }
4213     }
4214     return r;
4215     }
4216     }
4217    
4218     static final class LFDMPap extends LDMPap {
4219     final LongPredicate selector;
4220     LFDMPap(ForkJoinPool ex, int origin, int fence,
4221     long[] array, LongPredicate selector, LongToDouble op) {
4222     super(ex, origin, fence, array, op);
4223     this.selector = selector;
4224     }
4225    
4226     boolean hasFilter() { return true; }
4227     boolean isSelected(int i) { return selector.op(this.array[i]); }
4228    
4229     public ParallelLongArrayWithLongMapping withMapping(DoubleToLong op) {
4230     return new LFLMPap(ex, origin, fence, array, selector,
4231     CommonOps.compoundOp(this.op, op));
4232     }
4233    
4234     public ParallelLongArrayWithDoubleMapping withMapping(DoubleOp op) {
4235     return new LFDMPap(ex, origin, fence, array, selector,
4236     CommonOps.compoundOp(this.op, op));
4237     }
4238    
4239     public <U> ParallelLongArrayWithMapping<U> withMapping
4240     (DoubleToObject<? extends U> op) {
4241     return new LFOMPap<U>(ex, origin, fence, array, selector,
4242     CommonOps.compoundOp(this.op, op));
4243     }
4244    
4245     public <V> ParallelLongArrayWithMapping<V> withIndexedMapping
4246     (IntAndDoubleToObject<? extends V> mapper) {
4247     return new LFOCPap<V>(ex, origin, fence, array, selector,
4248     compoundIndexedOp(this.op, mapper));
4249     }
4250    
4251     public ParallelLongArrayWithDoubleMapping withIndexedMapping
4252     (IntAndDoubleToDouble mapper) {
4253     return new LFDCPap(ex, origin, fence, array, selector,
4254     compoundIndexedOp(this.op, mapper));
4255     }
4256    
4257     public ParallelLongArrayWithLongMapping withIndexedMapping
4258     (IntAndDoubleToLong mapper) {
4259     return new LFLCPap(ex, origin, fence, array, selector,
4260     compoundIndexedOp(this.op, mapper));
4261     }
4262    
4263     void leafApply(int lo, int hi, DoubleProcedure procedure) {
4264     final LongPredicate s = selector;
4265     final long[] a = this.array;
4266     final LongToDouble f = op;
4267     for (int i = lo; i < hi; ++i) {
4268     long x = a[i];
4269     if (s.op(x))
4270     procedure.op(f.op(x));
4271     }
4272     }
4273    
4274     double leafReduce(int lo, int hi, DoubleReducer reducer, double base) {
4275     final LongPredicate s = selector;
4276     final LongToDouble f = op;
4277     boolean gotFirst = false;
4278     double r = base;
4279     final long[] a = this.array;
4280     for (int i = lo; i < hi; ++i) {
4281     long t = a[i];
4282     if (s.op(t)) {
4283     double y = f.op(t);
4284     if (!gotFirst) {
4285     gotFirst = true;
4286     r = y;
4287     }
4288     else
4289     r = reducer.op(r, y);
4290     }
4291     }
4292     return r;
4293     }
4294     }
4295    
4296     // double-mapped, relational
4297     static final class ORDMPap<T> extends ODMPap<T> {
4298     final IntAndObjectPredicate<? super T> selector;
4299     ORDMPap(ForkJoinPool ex, int origin, int fence,
4300     T[] array, IntAndObjectPredicate<? super T> selector,
4301     ObjectToDouble<? super T> op) {
4302     super(ex, origin, fence, array, op);
4303     this.selector = selector;
4304     }
4305    
4306     boolean hasFilter() { return true; }
4307     boolean isSelected(int i) { return selector.op(i, this.array[i]); }
4308    
4309     public ParallelArrayWithDoubleMapping<T> withMapping(DoubleOp op) {
4310     return new ORDMPap<T>(ex, origin, fence, array, selector,
4311     CommonOps.compoundOp(this.op, op));
4312     }
4313    
4314     public ParallelArrayWithLongMapping<T> withMapping(DoubleToLong op) {
4315     return new ORLMPap<T>(ex, origin, fence, array, selector,
4316     CommonOps.compoundOp(this.op, op));
4317     }
4318    
4319     public <U> ParallelArrayWithMapping<T, U> withMapping
4320     (DoubleToObject<? extends U> op) {
4321     return new OROMPap<T,U>(ex, origin, fence, array, selector,
4322     CommonOps.compoundOp(this.op, op));
4323     }
4324    
4325     public <V> ParallelArrayWithMapping<T,V> withIndexedMapping
4326     (IntAndDoubleToObject<? extends V> mapper) {
4327     return new OROCPap<T,V>(ex, origin, fence, array, selector,
4328     compoundIndexedOp(this.op, mapper));
4329     }
4330    
4331     public ParallelArrayWithDoubleMapping<T> withIndexedMapping
4332     (IntAndDoubleToDouble mapper) {
4333     return new ORDCPap<T>(ex, origin, fence, array, selector,
4334     compoundIndexedOp(this.op, mapper));
4335     }
4336    
4337     public ParallelArrayWithLongMapping<T> withIndexedMapping
4338     (IntAndDoubleToLong mapper) {
4339     return new ORLCPap<T>(ex, origin, fence, array, selector,
4340     compoundIndexedOp(this.op, mapper));
4341     }
4342    
4343     void leafApply(int lo, int hi, DoubleProcedure procedure) {
4344     final IntAndObjectPredicate s = selector;
4345     final Object[] a = this.array;
4346     final ObjectToDouble f = op;
4347     for (int i = lo; i < hi; ++i) {
4348     Object x = a[i];
4349     if (s.op(i, x))
4350     procedure.op(f.op(x));
4351     }
4352     }
4353    
4354     double leafReduce(int lo, int hi, DoubleReducer reducer, double base) {
4355     final IntAndObjectPredicate s = selector;
4356     final ObjectToDouble f = op;
4357     boolean gotFirst = false;
4358     double r = base;
4359     final Object[] a = this.array;
4360     for (int i = lo; i < hi; ++i) {
4361     Object t = a[i];
4362     if (s.op(i, t)) {
4363     double y = f.op(t);
4364     if (!gotFirst) {
4365     gotFirst = true;
4366     r = y;
4367     }
4368     else
4369     r = reducer.op(r, y);
4370     }
4371     }
4372     return r;
4373     }
4374     }
4375    
4376     static final class DRDMPap extends DDMPap {
4377     final IntAndDoublePredicate selector;
4378     DRDMPap(ForkJoinPool ex, int origin, int fence,
4379     double[] array, IntAndDoublePredicate selector, DoubleOp op) {
4380     super(ex, origin, fence, array, op);
4381     this.selector = selector;
4382     }
4383    
4384     boolean hasFilter() { return true; }
4385     boolean isSelected(int i) { return selector.op(i, this.array[i]); }
4386    
4387     public ParallelDoubleArrayWithDoubleMapping withMapping(DoubleOp op) {
4388     return new DRDMPap(ex, origin, fence, array, selector,
4389     CommonOps.compoundOp(this.op, op));
4390     }
4391    
4392     public ParallelDoubleArrayWithLongMapping withMapping(DoubleToLong op) {
4393     return new DRLMPap(ex, origin, fence, array, selector,
4394     CommonOps.compoundOp(this.op, op));
4395     }
4396    
4397     public <U> ParallelDoubleArrayWithMapping<U> withMapping
4398     (DoubleToObject<? extends U> op) {
4399     return new DROMPap<U>(ex, origin, fence, array, selector,
4400     CommonOps.compoundOp(this.op, op));
4401     }
4402    
4403     public <V> ParallelDoubleArrayWithMapping<V> withIndexedMapping
4404     (IntAndDoubleToObject<? extends V> mapper) {
4405     return new DROCPap<V>(ex, origin, fence, array, selector,
4406     compoundIndexedOp(this.op, mapper));
4407     }
4408    
4409     public ParallelDoubleArrayWithDoubleMapping withIndexedMapping
4410     (IntAndDoubleToDouble mapper) {
4411     return new DRDCPap(ex, origin, fence, array, selector,
4412     compoundIndexedOp(this.op, mapper));
4413     }
4414    
4415     public ParallelDoubleArrayWithLongMapping withIndexedMapping
4416     (IntAndDoubleToLong mapper) {
4417     return new DRLCPap(ex, origin, fence, array, selector,
4418     compoundIndexedOp(this.op, mapper));
4419     }
4420    
4421     void leafApply(int lo, int hi, DoubleProcedure procedure) {
4422     final IntAndDoublePredicate s = selector;
4423     final DoubleOp f = op;
4424     final double[] a = this.array;
4425     for (int i = lo; i < hi; ++i) {
4426     double x = a[i];
4427     if (s.op(i, x))
4428     procedure.op(f.op(x));
4429     }
4430     }
4431    
4432     double leafReduce(int lo, int hi, DoubleReducer reducer, double base) {
4433     final IntAndDoublePredicate s = selector;
4434     boolean gotFirst = false;
4435     double r = base;
4436     final double[] a = this.array;
4437     final DoubleOp f = op;
4438     for (int i = lo; i < hi; ++i) {
4439     double t = a[i];
4440     if (s.op(i, t)) {
4441     double y = f.op(t);
4442     if (!gotFirst) {
4443     gotFirst = true;
4444     r = y;
4445     }
4446     else
4447     r = reducer.op(r, y);
4448     }
4449     }
4450     return r;
4451     }
4452     }
4453    
4454     static final class LRDMPap extends LDMPap {
4455     final IntAndLongPredicate selector;
4456     LRDMPap(ForkJoinPool ex, int origin, int fence,
4457     long[] array, IntAndLongPredicate selector, LongToDouble op) {
4458     super(ex, origin, fence, array, op);
4459     this.selector = selector;
4460     }
4461    
4462     boolean hasFilter() { return true; }
4463     boolean isSelected(int i) { return selector.op(i, this.array[i]); }
4464    
4465     public ParallelLongArrayWithLongMapping withMapping(DoubleToLong op) {
4466     return new LRLMPap(ex, origin, fence, array, selector,
4467     CommonOps.compoundOp(this.op, op));
4468     }
4469    
4470     public ParallelLongArrayWithDoubleMapping withMapping(DoubleOp op) {
4471     return new LRDMPap(ex, origin, fence, array, selector,
4472     CommonOps.compoundOp(this.op, op));
4473     }
4474    
4475     public <U> ParallelLongArrayWithMapping<U> withMapping
4476     (DoubleToObject<? extends U> op) {
4477     return new LROMPap<U>(ex, origin, fence, array, selector,
4478     CommonOps.compoundOp(this.op, op));
4479     }
4480    
4481     public <V> ParallelLongArrayWithMapping<V> withIndexedMapping
4482     (IntAndDoubleToObject<? extends V> mapper) {
4483     return new LROCPap<V>(ex, origin, fence, array, selector,
4484     compoundIndexedOp(this.op, mapper));
4485     }
4486    
4487     public ParallelLongArrayWithDoubleMapping withIndexedMapping
4488     (IntAndDoubleToDouble mapper) {
4489     return new LRDCPap(ex, origin, fence, array, selector,
4490     compoundIndexedOp(this.op, mapper));
4491     }
4492    
4493     public ParallelLongArrayWithLongMapping withIndexedMapping
4494     (IntAndDoubleToLong mapper) {
4495     return new LRLCPap(ex, origin, fence, array, selector,
4496     compoundIndexedOp(this.op, mapper));
4497     }
4498    
4499     void leafApply(int lo, int hi, DoubleProcedure procedure) {
4500     final IntAndLongPredicate s = selector;
4501     final long[] a = this.array;
4502     final LongToDouble f = op;
4503     for (int i = lo; i < hi; ++i) {
4504     long x = a[i];
4505     if (s.op(i, x))
4506     procedure.op(f.op(x));
4507     }
4508     }
4509    
4510     double leafReduce(int lo, int hi, DoubleReducer reducer, double base) {
4511     final IntAndLongPredicate s = selector;
4512     final LongToDouble f = op;
4513     boolean gotFirst = false;
4514     double r = base;
4515     final long[] a = this.array;
4516     for (int i = lo; i < hi; ++i) {
4517     long t = a[i];
4518     if (s.op(i, t)) {
4519     double y = f.op(t);
4520     if (!gotFirst) {
4521     gotFirst = true;
4522     r = y;
4523     }
4524     else
4525     r = reducer.op(r, y);
4526     }
4527     }
4528     return r;
4529     }
4530     }
4531    
4532     // double-combined
4533     static abstract class ODCPap<T> extends ParallelArrayWithDoubleMapping<T> {
4534     final IntAndObjectToDouble<? super T> op;
4535     ODCPap(ForkJoinPool ex, int origin, int fence,
4536     T[] array, IntAndObjectToDouble<? super T> op) {
4537     super(ex, origin, fence, array);
4538     this.op = op;
4539     }
4540    
4541     final boolean hasMap() { return true; }
4542     final double dget(int i) { return op.op(i, this.array[i]); }
4543     final Object oget(int i) { return Double.valueOf(dget(i)); }
4544     final long lget(int i) { return (long)(dget(i)); }
4545    
4546     final void leafTransfer(int lo, int hi, double[] dest, int offset) {
4547     final IntAndObjectToDouble f = op;
4548     final Object[] a = this.array;
4549     for (int i = lo; i < hi; ++i)
4550     dest[offset++] = f.op(i, a[i]);
4551     }
4552    
4553     final void leafTransferByIndex(int[] indices, int loIdx, int hiIdx,
4554     double[] dest, int offset) {
4555     final Object[] a = this.array;
4556     final IntAndObjectToDouble f = op;
4557     for (int i = loIdx; i < hiIdx; ++i) {
4558     int idx = indices[i];
4559     dest[offset++] = f.op(idx, a[idx]);
4560     }
4561     }
4562    
4563     }
4564    
4565     static abstract class DDCPap extends ParallelDoubleArrayWithDoubleMapping {
4566     final IntAndDoubleToDouble op;
4567     DDCPap(ForkJoinPool ex, int origin, int fence,
4568     double[] array, IntAndDoubleToDouble op) {
4569     super(ex, origin, fence, array);
4570     this.op = op;
4571     }
4572    
4573     final boolean hasMap() { return true; }
4574     final double dget(int i) { return op.op(i, this.array[i]); }
4575     final Object oget(int i) { return Double.valueOf(dget(i)); }
4576     final long lget(int i) { return (long)(dget(i)); }
4577    
4578     final void leafTransfer(int lo, int hi, double[] dest, int offset) {
4579     final IntAndDoubleToDouble f = op;
4580     final double[] a = this.array;
4581     for (int i = lo; i < hi; ++i)
4582     dest[offset++] = f.op(i, a[i]);
4583     }
4584    
4585     final void leafTransferByIndex(int[] indices, int loIdx, int hiIdx,
4586     double[] dest, int offset) {
4587     final double[] a = this.array;
4588     final IntAndDoubleToDouble f = op;
4589     for (int i = loIdx; i < hiIdx; ++i) {
4590     int idx = indices[i];
4591     dest[offset++] = f.op(idx, a[idx]);
4592     }
4593     }
4594     }
4595    
4596     static abstract class LDCPap extends ParallelLongArrayWithDoubleMapping {
4597     final IntAndLongToDouble op;
4598     LDCPap(ForkJoinPool ex, int origin, int fence,
4599     long[] array, IntAndLongToDouble op) {
4600     super(ex, origin, fence, array);
4601     this.op = op;
4602     }
4603    
4604     final boolean hasMap() { return true; }
4605     final double dget(int i) { return op.op(i, this.array[i]); }
4606     final Object oget(int i) { return Double.valueOf(dget(i)); }
4607     final long lget(int i) { return (long)(dget(i)); }
4608    
4609     final void leafTransfer(int lo, int hi, double[] dest, int offset) {
4610     final IntAndLongToDouble f = op;
4611     final long[] a = this.array;
4612     for (int i = lo; i < hi; ++i)
4613     dest[offset++] = f.op(i, a[i]);
4614     }
4615    
4616     final void leafTransferByIndex(int[] indices, int loIdx, int hiIdx,
4617     double[] dest, int offset) {
4618     final long[] a = this.array;
4619     final IntAndLongToDouble f = op;
4620     for (int i = loIdx; i < hiIdx; ++i) {
4621     int idx = indices[i];
4622     dest[offset++] = f.op(idx, a[idx]);
4623     }
4624     }
4625     }
4626    
4627     // double-combined, unfiltered
4628     static final class OUDCPap<T> extends ODCPap<T> {
4629     OUDCPap(ForkJoinPool ex, int origin, int fence,
4630     T[] array, IntAndObjectToDouble<? super T> op) {
4631     super(ex, origin, fence, array, op);
4632     }
4633    
4634     public ParallelArrayWithDoubleMapping<T> withMapping(DoubleOp op) {
4635     return new OUDCPap<T>(ex, origin, fence, array,
4636     compoundIndexedOp(this.op, op));
4637     }
4638    
4639     public ParallelArrayWithLongMapping<T> withMapping(DoubleToLong op) {
4640     return new OULCPap<T>(ex, origin, fence, array,
4641     compoundIndexedOp(this.op, op));
4642     }
4643    
4644     public <U> ParallelArrayWithMapping<T, U> withMapping
4645     (DoubleToObject<? extends U> op) {
4646     return new OUOCPap<T,U>(ex, origin, fence, array,
4647     compoundIndexedOp(this.op, op));
4648     }
4649    
4650     public <V> ParallelArrayWithMapping<T,V> withIndexedMapping
4651     (IntAndDoubleToObject<? extends V> mapper) {
4652     return new OUOCPap<T,V>(ex, origin, fence, array,
4653     compoundIndexedOp(this.op, mapper));
4654     }
4655    
4656     public ParallelArrayWithDoubleMapping<T> withIndexedMapping
4657     (IntAndDoubleToDouble mapper) {
4658     return new OUDCPap<T>(ex, origin, fence, array,
4659     compoundIndexedOp(this.op, mapper));
4660     }
4661    
4662     public ParallelArrayWithLongMapping<T> withIndexedMapping
4663     (IntAndDoubleToLong mapper) {
4664     return new OULCPap<T>(ex, origin, fence, array,
4665     compoundIndexedOp(this.op, mapper));
4666     }
4667    
4668     void leafApply(int lo, int hi, DoubleProcedure procedure) {
4669     final IntAndObjectToDouble f = op;
4670     final Object[] a = this.array;
4671     for (int i = lo; i < hi; ++i)
4672     procedure.op(f.op(i, a[i]));
4673     }
4674    
4675     double leafReduce(int lo, int hi, DoubleReducer reducer, double base) {
4676     if (lo >= hi)
4677     return base;
4678     final Object[] a = this.array;
4679     final IntAndObjectToDouble f = op;
4680     double r = f.op(lo, a[lo]);
4681     for (int i = lo+1; i < hi; ++i)
4682     r = reducer.op(r, f.op(i, a[i]));
4683     return r;
4684     }
4685    
4686     }
4687    
4688     static final class DUDCPap extends DDCPap {
4689     DUDCPap(ForkJoinPool ex, int origin, int fence,
4690     double[] array, IntAndDoubleToDouble op) {
4691     super(ex, origin, fence, array, op);
4692     }
4693    
4694     public ParallelDoubleArrayWithDoubleMapping withMapping(DoubleOp op) {
4695     return new DUDCPap(ex, origin, fence, array,
4696     compoundIndexedOp(this.op, op));
4697     }
4698    
4699     public ParallelDoubleArrayWithLongMapping withMapping(DoubleToLong op) {
4700     return new DULCPap(ex, origin, fence, array,
4701     compoundIndexedOp(this.op, op));
4702     }
4703    
4704     public <U> ParallelDoubleArrayWithMapping< U> withMapping
4705     (DoubleToObject<? extends U> op) {
4706     return new DUOCPap<U>(ex, origin, fence, array,
4707     compoundIndexedOp(this.op, op));
4708     }
4709    
4710     public <V> ParallelDoubleArrayWithMapping<V> withIndexedMapping
4711     (IntAndDoubleToObject<? extends V> mapper) {
4712     return new DUOCPap<V>(ex, origin, fence, array,
4713     compoundIndexedOp(this.op, mapper));
4714     }
4715    
4716     public ParallelDoubleArrayWithDoubleMapping withIndexedMapping
4717     (IntAndDoubleToDouble mapper) {
4718     return new DUDCPap(ex, origin, fence, array,
4719     compoundIndexedOp(this.op, mapper));
4720     }
4721    
4722     public ParallelDoubleArrayWithLongMapping withIndexedMapping
4723     (IntAndDoubleToLong mapper) {
4724     return new DULCPap(ex, origin, fence, array,
4725     compoundIndexedOp(this.op, mapper));
4726     }
4727    
4728     void leafApply(int lo, int hi, DoubleProcedure procedure) {
4729     final IntAndDoubleToDouble f = op;
4730     final double[] a = this.array;
4731     for (int i = lo; i < hi; ++i)
4732     procedure.op(f.op(i, a[i]));
4733     }
4734    
4735     double leafReduce(int lo, int hi, DoubleReducer reducer, double base) {
4736     if (lo >= hi)
4737     return base;
4738     final double[] a = this.array;
4739     final IntAndDoubleToDouble f = op;
4740     double r = f.op(lo, a[lo]);
4741     for (int i = lo+1; i < hi; ++i)
4742     r = reducer.op(r, f.op(i, a[i]));
4743     return r;
4744     }
4745     }
4746    
4747     static final class LUDCPap extends LDCPap {
4748     LUDCPap(ForkJoinPool ex, int origin, int fence,
4749     long[] array, IntAndLongToDouble op) {
4750     super(ex, origin, fence, array, op);
4751     }
4752    
4753     public ParallelLongArrayWithDoubleMapping withMapping(DoubleOp op) {
4754     return new LUDCPap(ex, origin, fence, array,
4755     compoundIndexedOp(this.op, op));
4756     }
4757    
4758     public ParallelLongArrayWithLongMapping withMapping(DoubleToLong op) {
4759     return new LULCPap(ex, origin, fence, array,
4760     compoundIndexedOp(this.op, op));
4761     }
4762    
4763     public <U> ParallelLongArrayWithMapping< U> withMapping
4764     (DoubleToObject<? extends U> op) {
4765     return new LUOCPap<U>(ex, origin, fence, array,
4766     compoundIndexedOp(this.op, op));
4767     }
4768    
4769     public <V> ParallelLongArrayWithMapping<V> withIndexedMapping
4770     (IntAndDoubleToObject<? extends V> mapper) {
4771     return new LUOCPap<V>(ex, origin, fence, array,
4772     compoundIndexedOp(this.op, mapper));
4773     }
4774    
4775     public ParallelLongArrayWithDoubleMapping withIndexedMapping
4776     (IntAndDoubleToDouble mapper) {
4777     return new LUDCPap(ex, origin, fence, array,
4778     compoundIndexedOp(this.op, mapper));
4779     }
4780    
4781     public ParallelLongArrayWithLongMapping withIndexedMapping
4782     (IntAndDoubleToLong mapper) {
4783     return new LULCPap(ex, origin, fence, array,
4784     compoundIndexedOp(this.op, mapper));
4785     }
4786    
4787     void leafApply(int lo, int hi, DoubleProcedure procedure) {
4788     final IntAndLongToDouble f = op;
4789     final long[] a = this.array;
4790     for (int i = lo; i < hi; ++i)
4791     procedure.op(f.op(i, a[i]));
4792     }
4793    
4794     double leafReduce(int lo, int hi, DoubleReducer reducer, double base) {
4795     if (lo >= hi)
4796     return base;
4797     final long[] a = this.array;
4798     final IntAndLongToDouble f = op;
4799     double r = f.op(lo, a[lo]);
4800     for (int i = lo+1; i < hi; ++i)
4801     r = reducer.op(r, f.op(i, a[i]));
4802     return r;
4803     }
4804    
4805     }
4806    
4807     // double-combined, filtered
4808     static final class OFDCPap<T> extends ODCPap<T> {
4809     final Predicate<? super T> selector;
4810     OFDCPap(ForkJoinPool ex, int origin, int fence,
4811     T[] array, Predicate<? super T> selector,
4812     IntAndObjectToDouble<? super T> op) {
4813     super(ex, origin, fence, array, op);
4814     this.selector = selector;
4815     }
4816    
4817     boolean hasFilter() { return true; }
4818     boolean isSelected(int i) { return selector.op(this.array[i]); }
4819    
4820     public ParallelArrayWithDoubleMapping<T> withMapping(DoubleOp op) {
4821     return new OFDCPap<T>
4822     (ex, origin, fence, array, selector,
4823     compoundIndexedOp(this.op, op));
4824     }
4825    
4826     public ParallelArrayWithLongMapping<T> withMapping(DoubleToLong op) {
4827     return new OFLCPap<T>(ex, origin, fence, array, selector,
4828     compoundIndexedOp(this.op, op));
4829     }
4830    
4831     public <U> ParallelArrayWithMapping<T, U> withMapping
4832     (DoubleToObject<? extends U> op) {
4833     return new OFOCPap<T,U>(ex, origin, fence, array, selector,
4834     compoundIndexedOp(this.op, op));
4835     }
4836    
4837     public <V> ParallelArrayWithMapping<T,V> withIndexedMapping
4838     (IntAndDoubleToObject<? extends V> mapper) {
4839     return new OFOCPap<T,V>(ex, origin, fence, array, selector,
4840     compoundIndexedOp(this.op, mapper));
4841     }
4842    
4843     public ParallelArrayWithDoubleMapping<T> withIndexedMapping
4844     (IntAndDoubleToDouble mapper) {
4845     return new OFDCPap<T>(ex, origin, fence, array, selector,
4846     compoundIndexedOp(this.op, mapper));
4847     }
4848    
4849     public ParallelArrayWithLongMapping<T> withIndexedMapping
4850     (IntAndDoubleToLong mapper) {
4851     return new OFLCPap<T>(ex, origin, fence, array, selector,
4852     compoundIndexedOp(this.op, mapper));
4853     }
4854    
4855     void leafApply(int lo, int hi, DoubleProcedure procedure) {
4856     final Predicate s = selector;
4857     final Object[] a = this.array;
4858     final IntAndObjectToDouble f = op;
4859     for (int i = lo; i < hi; ++i) {
4860     Object x = a[i];
4861     if (s.op(x))
4862     procedure.op(f.op(i, x));
4863     }
4864     }
4865    
4866     double leafReduce(int lo, int hi, DoubleReducer reducer, double base) {
4867     final Predicate s = selector;
4868     final IntAndObjectToDouble f = op;
4869     boolean gotFirst = false;
4870     double r = base;
4871     final Object[] a = this.array;
4872     for (int i = lo; i < hi; ++i) {
4873     Object t = a[i];
4874     if (s.op(t)) {
4875     double y = f.op(i, t);
4876     if (!gotFirst) {
4877     gotFirst = true;
4878     r = y;
4879     }
4880     else
4881     r = reducer.op(r, y);
4882     }
4883     }
4884     return r;
4885     }
4886     }
4887    
4888     static final class DFDCPap extends DDCPap {
4889     final DoublePredicate selector;
4890     DFDCPap(ForkJoinPool ex, int origin, int fence,
4891     double[] array, DoublePredicate selector,
4892     IntAndDoubleToDouble op) {
4893     super(ex, origin, fence, array, op);
4894     this.selector = selector;
4895     }
4896    
4897     boolean hasFilter() { return true; }
4898     boolean isSelected(int i) { return selector.op(this.array[i]); }
4899    
4900     public ParallelDoubleArrayWithDoubleMapping withMapping(DoubleOp op) {
4901     return new DFDCPap(ex, origin, fence, array, selector,
4902     compoundIndexedOp(this.op, op));
4903     }
4904    
4905     public ParallelDoubleArrayWithLongMapping withMapping(DoubleToLong op) {
4906 jsr166 1.4 return new DFLCPap(ex, origin, fence, array, selector,
4907     compoundIndexedOp(this.op, op));
4908 dl 1.1 }
4909    
4910     public <U> ParallelDoubleArrayWithMapping< U> withMapping
4911     (DoubleToObject<? extends U> op) {
4912     return new DFOCPap<U>(ex, origin, fence, array, selector,
4913     compoundIndexedOp(this.op, op));
4914     }
4915    
4916     public <V> ParallelDoubleArrayWithMapping<V> withIndexedMapping
4917     (IntAndDoubleToObject<? extends V> mapper) {
4918     return new DFOCPap<V>(ex, origin, fence, array, selector,
4919     compoundIndexedOp(this.op, mapper));
4920     }
4921    
4922     public ParallelDoubleArrayWithDoubleMapping withIndexedMapping
4923     (IntAndDoubleToDouble mapper) {
4924     return new DFDCPap(ex, origin, fence, array, selector,
4925     compoundIndexedOp(this.op, mapper));
4926     }
4927    
4928     public ParallelDoubleArrayWithLongMapping withIndexedMapping
4929     (IntAndDoubleToLong mapper) {
4930     return new DFLCPap(ex, origin, fence, array, selector,
4931     compoundIndexedOp(this.op, mapper));
4932     }
4933    
4934     void leafApply(int lo, int hi, DoubleProcedure procedure) {
4935     final DoublePredicate s = selector;
4936     final double[] a = this.array;
4937     final IntAndDoubleToDouble f = op;
4938     for (int i = lo; i < hi; ++i) {
4939     double x = a[i];
4940     if (s.op(x))
4941     procedure.op(f.op(i, x));
4942     }
4943     }
4944    
4945     double leafReduce(int lo, int hi, DoubleReducer reducer, double base) {
4946     final DoublePredicate s = selector;
4947     final IntAndDoubleToDouble f = op;
4948     boolean gotFirst = false;
4949     double r = base;
4950     final double[] a = this.array;
4951     for (int i = lo; i < hi; ++i) {
4952     double t = a[i];
4953     if (s.op(t)) {
4954     double y = f.op(i, t);
4955     if (!gotFirst) {
4956     gotFirst = true;
4957     r = y;
4958     }
4959     else
4960     r = reducer.op(r, y);
4961     }
4962     }
4963     return r;
4964     }
4965     }
4966    
4967     static final class LFDCPap extends LDCPap {
4968     final LongPredicate selector;
4969     LFDCPap(ForkJoinPool ex, int origin, int fence,
4970     long[] array, LongPredicate selector, IntAndLongToDouble op) {
4971     super(ex, origin, fence, array, op);
4972     this.selector = selector;
4973     }
4974    
4975     boolean hasFilter() { return true; }
4976     boolean isSelected(int i) { return selector.op(this.array[i]); }
4977    
4978     public ParallelLongArrayWithDoubleMapping withMapping(DoubleOp op) {
4979     return new LFDCPap(ex, origin, fence, array, selector,
4980     compoundIndexedOp(this.op, op));
4981     }
4982    
4983     public ParallelLongArrayWithLongMapping withMapping(DoubleToLong op) {
4984     return new LFLCPap(ex, origin, fence, array, selector,
4985     compoundIndexedOp(this.op, op));
4986     }
4987    
4988     public <U> ParallelLongArrayWithMapping< U> withMapping
4989     (DoubleToObject<? extends U> op) {
4990     return new LFOCPap<U>(ex, origin, fence, array, selector,
4991     compoundIndexedOp(this.op, op));
4992     }
4993    
4994     public <V> ParallelLongArrayWithMapping<V> withIndexedMapping
4995     (IntAndDoubleToObject<? extends V> mapper) {
4996     return new LFOCPap<V>(ex, origin, fence, array, selector,
4997     compoundIndexedOp(this.op, mapper));
4998     }
4999    
5000     public ParallelLongArrayWithDoubleMapping withIndexedMapping
5001     (IntAndDoubleToDouble mapper) {
5002     return new LFDCPap(ex, origin, fence, array, selector,
5003     compoundIndexedOp(this.op, mapper));
5004     }
5005    
5006     public ParallelLongArrayWithLongMapping withIndexedMapping
5007     (IntAndDoubleToLong mapper) {
5008     return new LFLCPap(ex, origin, fence, array, selector,
5009     compoundIndexedOp(this.op, mapper));
5010     }
5011    
5012     void leafApply(int lo, int hi, DoubleProcedure procedure) {
5013     final LongPredicate s = selector;
5014     final long[] a = this.array;
5015     final IntAndLongToDouble f = op;
5016     for (int i = lo; i < hi; ++i) {
5017     long x = a[i];
5018     if (s.op(x))
5019     procedure.op(f.op(i, x));
5020     }
5021     }
5022    
5023     double leafReduce(int lo, int hi, DoubleReducer reducer, double base) {
5024     final LongPredicate s = selector;
5025     final IntAndLongToDouble f = op;
5026     boolean gotFirst = false;
5027     double r = base;
5028     final long[] a = this.array;
5029     for (int i = lo; i < hi; ++i) {
5030     long t = a[i];
5031     if (s.op(t)) {
5032     double y = f.op(i, t);
5033     if (!gotFirst) {
5034     gotFirst = true;
5035     r = y;
5036     }
5037     else
5038     r = reducer.op(r, y);
5039     }
5040     }
5041     return r;
5042     }
5043     }
5044    
5045     // double-combined, relational
5046     static final class ORDCPap<T> extends ODCPap<T> {
5047     final IntAndObjectPredicate<? super T> selector;
5048     ORDCPap(ForkJoinPool ex, int origin, int fence,
5049     T[] array, IntAndObjectPredicate<? super T> selector,
5050     IntAndObjectToDouble<? super T> op) {
5051     super(ex, origin, fence, array, op);
5052     this.selector = selector;
5053     }
5054    
5055     boolean hasFilter() { return true; }
5056     boolean isSelected(int i) { return selector.op(i, this.array[i]); }
5057    
5058     public ParallelArrayWithDoubleMapping<T> withMapping(DoubleOp op) {
5059     return new ORDCPap<T>
5060     (ex, origin, fence, array, selector,
5061     compoundIndexedOp(this.op, op));
5062     }
5063    
5064     public ParallelArrayWithLongMapping<T> withMapping(DoubleToLong op) {
5065     return new ORLCPap<T>(ex, origin, fence, array, selector,
5066     compoundIndexedOp(this.op, op));
5067     }
5068    
5069     public <U> ParallelArrayWithMapping<T, U> withMapping
5070     (DoubleToObject<? extends U> op) {
5071     return new OROCPap<T,U>(ex, origin, fence, array, selector,
5072     compoundIndexedOp(this.op, op));
5073     }
5074    
5075     public <V> ParallelArrayWithMapping<T,V> withIndexedMapping
5076     (IntAndDoubleToObject<? extends V> mapper) {
5077     return new OROCPap<T,V>(ex, origin, fence, array, selector,
5078     compoundIndexedOp(this.op, mapper));
5079     }
5080    
5081     public ParallelArrayWithDoubleMapping<T> withIndexedMapping
5082     (IntAndDoubleToDouble mapper) {
5083     return new ORDCPap<T>(ex, origin, fence, array, selector,
5084     compoundIndexedOp(this.op, mapper));
5085     }
5086    
5087     public ParallelArrayWithLongMapping<T> withIndexedMapping
5088     (IntAndDoubleToLong mapper) {
5089     return new ORLCPap<T>(ex, origin, fence, array, selector,
5090     compoundIndexedOp(this.op, mapper));
5091     }
5092    
5093     void leafApply(int lo, int hi, DoubleProcedure procedure) {
5094     final IntAndObjectPredicate s = selector;
5095     final Object[] a = this.array;
5096     final IntAndObjectToDouble f = op;
5097     for (int i = lo; i < hi; ++i) {
5098     Object x = a[i];
5099     if (s.op(i, x))
5100     procedure.op(f.op(i, x));
5101     }
5102     }
5103    
5104     double leafReduce(int lo, int hi, DoubleReducer reducer, double base) {
5105     final IntAndObjectPredicate s = selector;
5106     final IntAndObjectToDouble f = op;
5107     boolean gotFirst = false;
5108     double r = base;
5109     final Object[] a = this.array;
5110     for (int i = lo; i < hi; ++i) {
5111     Object t = a[i];
5112     if (s.op(i, t)) {
5113     double y = f.op(i, t);
5114     if (!gotFirst) {
5115     gotFirst = true;
5116     r = y;
5117     }
5118     else
5119     r = reducer.op(r, y);
5120     }
5121     }
5122     return r;
5123     }
5124     }
5125    
5126     static final class DRDCPap extends DDCPap {
5127     final IntAndDoublePredicate selector;
5128     DRDCPap(ForkJoinPool ex, int origin, int fence,
5129     double[] array, IntAndDoublePredicate selector,
5130     IntAndDoubleToDouble op) {
5131     super(ex, origin, fence, array, op);
5132     this.selector = selector;
5133     }
5134    
5135     boolean hasFilter() { return true; }
5136     boolean isSelected(int i) { return selector.op(i, this.array[i]); }
5137    
5138     public ParallelDoubleArrayWithDoubleMapping withMapping(DoubleOp op) {
5139     return new DRDCPap(ex, origin, fence, array, selector,
5140     compoundIndexedOp(this.op, op));
5141     }
5142    
5143     public ParallelDoubleArrayWithLongMapping withMapping(DoubleToLong op) {
5144 jsr166 1.4 return new DRLCPap(ex, origin, fence, array, selector,
5145     compoundIndexedOp(this.op, op));
5146 dl 1.1 }
5147    
5148     public <U> ParallelDoubleArrayWithMapping< U> withMapping
5149     (DoubleToObject<? extends U> op) {
5150     return new DROCPap<U>(ex, origin, fence, array, selector,
5151     compoundIndexedOp(this.op, op));
5152     }
5153    
5154     public <V> ParallelDoubleArrayWithMapping<V> withIndexedMapping
5155     (IntAndDoubleToObject<? extends V> mapper) {
5156     return new DROCPap<V>(ex, origin, fence, array, selector,
5157     compoundIndexedOp(this.op, mapper));
5158     }
5159    
5160     public ParallelDoubleArrayWithDoubleMapping withIndexedMapping
5161     (IntAndDoubleToDouble mapper) {
5162     return new DRDCPap(ex, origin, fence, array, selector,
5163     compoundIndexedOp(this.op, mapper));
5164     }
5165    
5166     public ParallelDoubleArrayWithLongMapping withIndexedMapping
5167     (IntAndDoubleToLong mapper) {
5168     return new DRLCPap(ex, origin, fence, array, selector,
5169     compoundIndexedOp(this.op, mapper));
5170     }
5171    
5172     void leafApply(int lo, int hi, DoubleProcedure procedure) {
5173     final IntAndDoublePredicate s = selector;
5174     final double[] a = this.array;
5175     final IntAndDoubleToDouble f = op;
5176     for (int i = lo; i < hi; ++i) {
5177     double x = a[i];
5178     if (s.op(i, x))
5179     procedure.op(f.op(i, x));
5180     }
5181     }
5182    
5183     double leafReduce(int lo, int hi, DoubleReducer reducer, double base) {
5184     final IntAndDoublePredicate s = selector;
5185     final IntAndDoubleToDouble f = op;
5186     boolean gotFirst = false;
5187     double r = base;
5188     final double[] a = this.array;
5189     for (int i = lo; i < hi; ++i) {
5190     double t = a[i];
5191     if (s.op(i, t)) {
5192     double y = f.op(i, t);
5193     if (!gotFirst) {
5194     gotFirst = true;
5195     r = y;
5196     }
5197     else
5198     r = reducer.op(r, y);
5199     }
5200     }
5201     return r;
5202     }
5203     }
5204    
5205     static final class LRDCPap extends LDCPap {
5206     final IntAndLongPredicate selector;
5207     LRDCPap(ForkJoinPool ex, int origin, int fence,
5208     long[] array, IntAndLongPredicate selector, IntAndLongToDouble op) {
5209     super(ex, origin, fence, array, op);
5210     this.selector = selector;
5211     }
5212    
5213     boolean hasFilter() { return true; }
5214     boolean isSelected(int i) { return selector.op(i, this.array[i]); }
5215    
5216     public ParallelLongArrayWithDoubleMapping withMapping(DoubleOp op) {
5217     return new LRDCPap(ex, origin, fence, array, selector,
5218     compoundIndexedOp(this.op, op));
5219     }
5220    
5221     public ParallelLongArrayWithLongMapping withMapping(DoubleToLong op) {
5222     return new LRLCPap(ex, origin, fence, array, selector,
5223     compoundIndexedOp(this.op, op));
5224     }
5225    
5226     public <U> ParallelLongArrayWithMapping< U> withMapping
5227     (DoubleToObject<? extends U> op) {
5228     return new LROCPap<U>(ex, origin, fence, array, selector,
5229     compoundIndexedOp(this.op, op));
5230     }
5231    
5232     public <V> ParallelLongArrayWithMapping<V> withIndexedMapping
5233     (IntAndDoubleToObject<? extends V> mapper) {
5234     return new LROCPap<V>(ex, origin, fence, array, selector,
5235     compoundIndexedOp(this.op, mapper));
5236     }
5237    
5238     public ParallelLongArrayWithDoubleMapping withIndexedMapping
5239     (IntAndDoubleToDouble mapper) {
5240     return new LRDCPap(ex, origin, fence, array, selector,
5241     compoundIndexedOp(this.op, mapper));
5242     }
5243    
5244     public ParallelLongArrayWithLongMapping withIndexedMapping
5245     (IntAndDoubleToLong mapper) {
5246     return new LRLCPap(ex, origin, fence, array, selector,
5247     compoundIndexedOp(this.op, mapper));
5248     }
5249    
5250     void leafApply(int lo, int hi, DoubleProcedure procedure) {
5251     final IntAndLongPredicate s = selector;
5252     final long[] a = this.array;
5253     final IntAndLongToDouble f = op;
5254     for (int i = lo; i < hi; ++i) {
5255     long x = a[i];
5256     if (s.op(i, x))
5257     procedure.op(f.op(i, x));
5258     }
5259     }
5260    
5261     double leafReduce(int lo, int hi, DoubleReducer reducer, double base) {
5262     final IntAndLongPredicate s = selector;
5263     final IntAndLongToDouble f = op;
5264     boolean gotFirst = false;
5265     double r = base;
5266     final long[] a = this.array;
5267     for (int i = lo; i < hi; ++i) {
5268     long t = a[i];
5269     if (s.op(i, t)) {
5270     double y = f.op(i, t);
5271     if (!gotFirst) {
5272     gotFirst = true;
5273     r = y;
5274     }
5275     else
5276     r = reducer.op(r, y);
5277     }
5278     }
5279     return r;
5280     }
5281     }
5282    
5283     // long-combined
5284     static abstract class OLMPap<T> extends ParallelArrayWithLongMapping<T> {
5285     final ObjectToLong<? super T> op;
5286     OLMPap(ForkJoinPool ex, int origin, int fence,
5287     T[] array, final ObjectToLong<? super T> op) {
5288     super(ex, origin, fence, array);
5289     this.op = op;
5290     }
5291    
5292     final boolean hasMap() { return true; }
5293     final long lget(int i) { return op.op(this.array[i]); }
5294     final Object oget(int i) { return Long.valueOf(lget(i)); }
5295     final double dget(int i) { return (double)(lget(i)); }
5296    
5297     final void leafTransfer(int lo, int hi, long[] dest, int offset) {
5298     final ObjectToLong f = op;
5299     final Object[] a = this.array;
5300     for (int i = lo; i < hi; ++i)
5301     dest[offset++] = f.op(a[i]);
5302     }
5303    
5304     final void leafTransferByIndex(int[] indices, int loIdx, int hiIdx,
5305     long[] dest, int offset) {
5306     final Object[] a = this.array;
5307     final ObjectToLong f = op;
5308     for (int i = loIdx; i < hiIdx; ++i)
5309     dest[offset++] = f.op(a[indices[i]]);
5310     }
5311     }
5312    
5313     static abstract class DLMPap extends ParallelDoubleArrayWithLongMapping {
5314     final DoubleToLong op;
5315     DLMPap(ForkJoinPool ex, int origin, int fence,
5316     double[] array, DoubleToLong op) {
5317     super(ex, origin, fence, array);
5318     this.op = op;
5319     }
5320    
5321     final boolean hasMap() { return true; }
5322     final long lget(int i) { return op.op(this.array[i]); }
5323     final Object oget(int i) { return Long.valueOf(lget(i)); }
5324     final double dget(int i) { return (double)(lget(i)); }
5325    
5326     final void leafTransfer(int lo, int hi, long[] dest, int offset) {
5327     final double[] a = this.array;
5328     final DoubleToLong f = op;
5329     for (int i = lo; i < hi; ++i)
5330     dest[offset++] = f.op(a[i]);
5331     }
5332    
5333     final void leafTransferByIndex(int[] indices, int loIdx, int hiIdx,
5334     long[] dest, int offset) {
5335     final double[] a = this.array;
5336     final DoubleToLong f = op;
5337     for (int i = loIdx; i < hiIdx; ++i)
5338     dest[offset++] = f.op(a[indices[i]]);
5339     }
5340    
5341     }
5342    
5343     static abstract class LLMPap extends ParallelLongArrayWithLongMapping {
5344     final LongOp op;
5345     LLMPap(ForkJoinPool ex, int origin, int fence,
5346     long[] array, LongOp op) {
5347     super(ex, origin, fence, array);
5348     this.op = op;
5349     }
5350    
5351     final boolean hasMap() { return true; }
5352     final long lget(int i) { return op.op(this.array[i]); }
5353     final Object oget(int i) { return Long.valueOf(lget(i)); }
5354     final double dget(int i) { return (double)(lget(i)); }
5355    
5356     final void leafTransfer(int lo, int hi, long[] dest, int offset) {
5357     final long[] a = this.array;
5358     final LongOp f = op;
5359     for (int i = lo; i < hi; ++i)
5360     dest[offset++] = f.op(a[i]);
5361     }
5362    
5363     final void leafTransferByIndex(int[] indices, int loIdx, int hiIdx,
5364     long[] dest, int offset) {
5365     final long[] a = this.array;
5366     final LongOp f = op;
5367     for (int i = loIdx; i < hiIdx; ++i)
5368     dest[offset++] = f.op(a[indices[i]]);
5369     }
5370    
5371     }
5372    
5373     // long-combined, unfiltered
5374     static final class OULMPap<T> extends OLMPap<T> {
5375     OULMPap(ForkJoinPool ex, int origin, int fence,
5376     T[] array, ObjectToLong<? super T> op) {
5377     super(ex, origin, fence, array, op);
5378     }
5379    
5380     public ParallelArrayWithDoubleMapping<T> withMapping(LongToDouble op) {
5381     return new OUDMPap<T>(ex, origin, fence, array,
5382     CommonOps.compoundOp(this.op, op));
5383     }
5384    
5385     public ParallelArrayWithLongMapping<T> withMapping(LongOp op) {
5386     return new OULMPap<T>(ex, origin, fence, array,
5387     CommonOps.compoundOp(this.op, op));
5388     }
5389    
5390     public <U> ParallelArrayWithMapping<T, U> withMapping
5391     (LongToObject<? extends U> op) {
5392     return new OUOMPap<T,U>(ex, origin, fence, array,
5393     CommonOps.compoundOp(this.op, op));
5394     }
5395    
5396     public <V> ParallelArrayWithMapping<T,V> withIndexedMapping
5397     (IntAndLongToObject<? extends V> mapper) {
5398     return new OUOCPap<T,V>(ex, origin, fence, array,
5399     compoundIndexedOp(this.op, mapper));
5400     }
5401    
5402     public ParallelArrayWithDoubleMapping<T> withIndexedMapping
5403     (IntAndLongToDouble mapper) {
5404     return new OUDCPap<T>(ex, origin, fence, array,
5405     compoundIndexedOp(this.op, mapper));
5406     }
5407    
5408     public ParallelArrayWithLongMapping<T> withIndexedMapping
5409     (IntAndLongToLong mapper) {
5410     return new OULCPap<T>(ex, origin, fence, array,
5411     compoundIndexedOp(this.op, mapper));
5412     }
5413    
5414     void leafApply(int lo, int hi, LongProcedure procedure) {
5415     final Object[] a = this.array;
5416     final ObjectToLong f = op;
5417     for (int i = lo; i < hi; ++i)
5418     procedure.op(f.op(a[i]));
5419     }
5420    
5421     long leafReduce(int lo, int hi, LongReducer reducer, long base) {
5422     if (lo >= hi)
5423     return base;
5424     final Object[] a = this.array;
5425     final ObjectToLong f = op;
5426     long r = f.op(a[lo]);
5427     for (int i = lo+1; i < hi; ++i)
5428     r = reducer.op(r, f.op(a[i]));
5429     return r;
5430     }
5431     }
5432    
5433     static final class DULMPap extends DLMPap {
5434     DULMPap(ForkJoinPool ex, int origin, int fence,
5435     double[] array, DoubleToLong op) {
5436     super(ex, origin, fence, array, op);
5437     }
5438    
5439     public ParallelDoubleArrayWithDoubleMapping withMapping
5440     (LongToDouble op) {
5441     return new DUDMPap(ex, origin, fence, array,
5442     CommonOps.compoundOp(this.op, op));
5443     }
5444    
5445     public ParallelDoubleArrayWithLongMapping withMapping
5446     (LongOp op) {
5447     return new DULMPap(ex, origin, fence, array,
5448     CommonOps.compoundOp(this.op, op));
5449     }
5450    
5451     public <U> ParallelDoubleArrayWithMapping<U> withMapping
5452     (LongToObject<? extends U> op) {
5453     return new DUOMPap<U>(ex, origin, fence, array,
5454     CommonOps.compoundOp(this.op, op));
5455     }
5456    
5457     public <V> ParallelDoubleArrayWithMapping<V> withIndexedMapping
5458     (IntAndLongToObject<? extends V> mapper) {
5459     return new DUOCPap<V>(ex, origin, fence, array,
5460     compoundIndexedOp(this.op, mapper));
5461     }
5462    
5463     public ParallelDoubleArrayWithDoubleMapping withIndexedMapping
5464     (IntAndLongToDouble mapper) {
5465     return new DUDCPap(ex, origin, fence, array,
5466     compoundIndexedOp(this.op, mapper));
5467     }
5468    
5469     public ParallelDoubleArrayWithLongMapping withIndexedMapping
5470     (IntAndLongToLong mapper) {
5471     return new DULCPap(ex, origin, fence, array,
5472     compoundIndexedOp(this.op, mapper));
5473     }
5474    
5475     void leafApply(int lo, int hi, LongProcedure procedure) {
5476     final double[] a = this.array;
5477     final DoubleToLong f = op;
5478     for (int i = lo; i < hi; ++i)
5479     procedure.op(f.op(a[i]));
5480     }
5481    
5482     long leafReduce(int lo, int hi, LongReducer reducer, long base) {
5483     if (lo >= hi)
5484     return base;
5485     final double[] a = this.array;
5486     final DoubleToLong f = op;
5487     long r = f.op(a[lo]);
5488     for (int i = lo+1; i < hi; ++i)
5489     r = reducer.op(r, f.op(a[i]));
5490     return r;
5491     }
5492    
5493     }
5494    
5495     static final class LULMPap extends LLMPap {
5496     LULMPap(ForkJoinPool ex, int origin, int fence,
5497     long[] array, LongOp op) {
5498     super(ex, origin, fence, array, op);
5499     }
5500    
5501     public ParallelLongArrayWithLongMapping withMapping(LongOp op) {
5502     return new LULMPap(ex, origin, fence, array,
5503     CommonOps.compoundOp(this.op, op));
5504     }
5505    
5506     public ParallelLongArrayWithDoubleMapping withMapping(LongToDouble op) {
5507     return new LUDMPap(ex, origin, fence, array,
5508     CommonOps.compoundOp(this.op, op));
5509     }
5510    
5511     public <U> ParallelLongArrayWithMapping<U> withMapping
5512     (LongToObject<? extends U> op) {
5513     return new LUOMPap<U>(ex, origin, fence, array,
5514     CommonOps.compoundOp(this.op, op));
5515     }
5516    
5517     public <V> ParallelLongArrayWithMapping<V> withIndexedMapping
5518     (IntAndLongToObject<? extends V> mapper) {
5519     return new LUOCPap<V>(ex, origin, fence, array,
5520     compoundIndexedOp(this.op, mapper));
5521     }
5522    
5523     public ParallelLongArrayWithDoubleMapping withIndexedMapping
5524     (IntAndLongToDouble mapper) {
5525     return new LUDCPap(ex, origin, fence, array,
5526     compoundIndexedOp(this.op, mapper));
5527     }
5528    
5529     public ParallelLongArrayWithLongMapping withIndexedMapping
5530     (IntAndLongToLong mapper) {
5531     return new LULCPap(ex, origin, fence, array,
5532     compoundIndexedOp(this.op, mapper));
5533     }
5534    
5535     void leafApply(int lo, int hi, LongProcedure procedure) {
5536     final LongOp f = op;
5537     final long[] a = this.array;
5538     for (int i = lo; i < hi; ++i)
5539     procedure.op(f.op(a[i]));
5540     }
5541    
5542     long leafReduce(int lo, int hi, LongReducer reducer, long base) {
5543     if (lo >= hi)
5544     return base;
5545     final long[] a = this.array;
5546     final LongOp f = op;
5547     long r = f.op(a[lo]);
5548     for (int i = lo+1; i < hi; ++i)
5549     r = reducer.op(r, f.op(a[i]));
5550     return r;
5551     }
5552     }
5553    
5554     // long-combined, filtered
5555     static final class OFLMPap<T> extends OLMPap<T> {
5556     final Predicate<? super T> selector;
5557     OFLMPap(ForkJoinPool ex, int origin, int fence,
5558     T[] array, Predicate<? super T> selector,
5559     ObjectToLong<? super T> op) {
5560     super(ex, origin, fence, array, op);
5561     this.selector = selector;
5562     }
5563    
5564     boolean hasFilter() { return true; }
5565     boolean isSelected(int i) { return selector.op(this.array[i]); }
5566    
5567     public ParallelArrayWithDoubleMapping<T> withMapping
5568     (LongToDouble op) {
5569     return new OFDMPap<T>(ex, origin, fence, array, selector,
5570     CommonOps.compoundOp(this.op, op));
5571     }
5572    
5573     public ParallelArrayWithLongMapping<T> withMapping
5574     (LongOp op) {
5575     return new OFLMPap<T>(ex, origin, fence, array, selector,
5576     CommonOps.compoundOp(this.op, op));
5577     }
5578    
5579     public <U> ParallelArrayWithMapping<T, U> withMapping
5580     (LongToObject<? extends U> op) {
5581     return new OFOMPap<T,U>(ex, origin, fence, array, selector,
5582     CommonOps.compoundOp(this.op, op));
5583     }
5584    
5585     public <V> ParallelArrayWithMapping<T,V> withIndexedMapping
5586     (IntAndLongToObject<? extends V> mapper) {
5587     return new OFOCPap<T,V>(ex, origin, fence, array, selector,
5588     compoundIndexedOp(this.op, mapper));
5589     }
5590    
5591     public ParallelArrayWithDoubleMapping<T> withIndexedMapping
5592     (IntAndLongToDouble mapper) {
5593     return new OFDCPap<T>(ex, origin, fence, array, selector,
5594     compoundIndexedOp(this.op, mapper));
5595     }
5596    
5597     public ParallelArrayWithLongMapping<T> withIndexedMapping
5598     (IntAndLongToLong mapper) {
5599     return new OFLCPap<T>(ex, origin, fence, array, selector,
5600     compoundIndexedOp(this.op, mapper));
5601     }
5602    
5603     void leafApply(int lo, int hi, LongProcedure procedure) {
5604     final Predicate s = selector;
5605     final Object[] a = this.array;
5606     final ObjectToLong f = op;
5607     for (int i = lo; i < hi; ++i) {
5608     Object x = a[i];
5609     if (s.op(x))
5610     procedure.op(f.op(x));
5611     }
5612     }
5613    
5614     long leafReduce(int lo, int hi, LongReducer reducer, long base) {
5615     final Predicate s = selector;
5616     final ObjectToLong f = op;
5617     boolean gotFirst = false;
5618     long r = base;
5619     final Object[] a = this.array;
5620     for (int i = lo; i < hi; ++i) {
5621     Object t = a[i];
5622     if (s.op(t)) {
5623     long y = f.op(t);
5624     if (!gotFirst) {
5625     gotFirst = true;
5626     r = y;
5627     }
5628     else
5629     r = reducer.op(r, y);
5630     }
5631     }
5632     return r;
5633     }
5634     }
5635    
5636     static final class DFLMPap extends DLMPap {
5637     final DoublePredicate selector;
5638     DFLMPap(ForkJoinPool ex, int origin, int fence,
5639     double[] array, DoublePredicate selector, DoubleToLong op) {
5640     super(ex, origin, fence, array, op);
5641     this.selector = selector;
5642     }
5643    
5644     boolean hasFilter() { return true; }
5645     boolean isSelected(int i) { return selector.op(this.array[i]); }
5646    
5647     public ParallelDoubleArrayWithDoubleMapping withMapping
5648     (LongToDouble op) {
5649     return new DFDMPap(ex, origin, fence, array, selector,
5650     CommonOps.compoundOp(this.op, op));
5651     }
5652    
5653     public ParallelDoubleArrayWithLongMapping withMapping
5654     (LongOp op) {
5655     return new DFLMPap(ex, origin, fence, array, selector,
5656     CommonOps.compoundOp(this.op, op));
5657     }
5658    
5659     public <U> ParallelDoubleArrayWithMapping<U> withMapping
5660     (LongToObject<? extends U> op) {
5661     return new DFOMPap<U>(ex, origin, fence, array, selector,
5662     CommonOps.compoundOp(this.op, op));
5663     }
5664    
5665     public <V> ParallelDoubleArrayWithMapping<V> withIndexedMapping
5666     (IntAndLongToObject<? extends V> mapper) {
5667     return new DFOCPap<V>(ex, origin, fence, array, selector,
5668     compoundIndexedOp(this.op, mapper));
5669     }
5670    
5671     public ParallelDoubleArrayWithDoubleMapping withIndexedMapping
5672     (IntAndLongToDouble mapper) {
5673     return new DFDCPap(ex, origin, fence, array, selector,
5674     compoundIndexedOp(this.op, mapper));
5675     }
5676    
5677     public ParallelDoubleArrayWithLongMapping withIndexedMapping
5678     (IntAndLongToLong mapper) {
5679     return new DFLCPap(ex, origin, fence, array, selector,
5680     compoundIndexedOp(this.op, mapper));
5681     }
5682    
5683     void leafApply(int lo, int hi, LongProcedure procedure) {
5684     final DoublePredicate s = selector;
5685     final DoubleToLong f = op;
5686     final double[] a = this.array;
5687     for (int i = lo; i < hi; ++i) {
5688     double x = a[i];
5689     if (s.op(x))
5690     procedure.op(f.op(x));
5691     }
5692     }
5693    
5694     long leafReduce(int lo, int hi, LongReducer reducer, long base) {
5695     boolean gotFirst = false;
5696     long r = base;
5697     final double[] a = this.array;
5698     final DoublePredicate s = selector;
5699     final DoubleToLong f = op;
5700     for (int i = lo; i < hi; ++i) {
5701     double t = a[i];
5702     if (s.op(t)) {
5703     long y = f.op(t);
5704     if (!gotFirst) {
5705     gotFirst = true;
5706     r = y;
5707     }
5708     else
5709     r = reducer.op(r, y);
5710     }
5711     }
5712     return r;
5713     }
5714     }
5715    
5716     static final class LFLMPap extends LLMPap {
5717     final LongPredicate selector;
5718     LFLMPap(ForkJoinPool ex, int origin, int fence,
5719     long[] array, LongPredicate selector, LongOp op) {
5720     super(ex, origin, fence, array, op);
5721     this.selector = selector;
5722     }
5723    
5724     boolean hasFilter() { return true; }
5725     boolean isSelected(int i) { return selector.op(this.array[i]); }
5726    
5727     public ParallelLongArrayWithLongMapping withMapping(LongOp op) {
5728     return new LFLMPap(ex, origin, fence, array, selector,
5729     CommonOps.compoundOp(this.op, op));
5730     }
5731    
5732     public ParallelLongArrayWithDoubleMapping withMapping(LongToDouble op) {
5733     return new LFDMPap(ex, origin, fence, array, selector,
5734     CommonOps.compoundOp(this.op, op));
5735     }
5736    
5737     public <U> ParallelLongArrayWithMapping<U> withMapping
5738     (LongToObject<? extends U> op) {
5739     return new LFOMPap<U>(ex, origin, fence, array, selector,
5740     CommonOps.compoundOp(this.op, op));
5741     }
5742    
5743     public <V> ParallelLongArrayWithMapping<V> withIndexedMapping
5744     (IntAndLongToObject<? extends V> mapper) {
5745     return new LFOCPap<V>(ex, origin, fence, array, selector,
5746     compoundIndexedOp(this.op, mapper));
5747     }
5748    
5749     public ParallelLongArrayWithDoubleMapping withIndexedMapping
5750     (IntAndLongToDouble mapper) {
5751     return new LFDCPap(ex, origin, fence, array, selector,
5752     compoundIndexedOp(this.op, mapper));
5753     }
5754    
5755     public ParallelLongArrayWithLongMapping withIndexedMapping
5756     (IntAndLongToLong mapper) {
5757     return new LFLCPap(ex, origin, fence, array, selector,
5758     compoundIndexedOp(this.op, mapper));
5759     }
5760    
5761     void leafApply(int lo, int hi, LongProcedure procedure) {
5762     final LongPredicate s = selector;
5763     final LongOp f = op;
5764     final long[] a = this.array;
5765     for (int i = lo; i < hi; ++i) {
5766     long x = a[i];
5767     if (s.op(x))
5768     procedure.op(f.op(x));
5769     }
5770     }
5771    
5772     long leafReduce(int lo, int hi, LongReducer reducer, long base) {
5773     final LongPredicate s = selector;
5774     final LongOp f = op;
5775     boolean gotFirst = false;
5776     long r = base;
5777     final long[] a = this.array;
5778     for (int i = lo; i < hi; ++i) {
5779     long t = a[i];
5780     if (s.op(t)) {
5781     long y = f.op(t);
5782     if (!gotFirst) {
5783     gotFirst = true;
5784     r = y;
5785     }
5786     else
5787     r = reducer.op(r, y);
5788     }
5789     }
5790     return r;
5791     }
5792     }
5793    
5794     // Long-mapped, relational
5795     static final class ORLMPap<T> extends OLMPap<T> {
5796     final IntAndObjectPredicate<? super T> selector;
5797     ORLMPap(ForkJoinPool ex, int origin, int fence,
5798     T[] array, IntAndObjectPredicate<? super T> selector,
5799     ObjectToLong<? super T> op) {
5800     super(ex, origin, fence, array, op);
5801     this.selector = selector;
5802     }
5803    
5804     boolean hasFilter() { return true; }
5805     boolean isSelected(int i) { return selector.op(i, this.array[i]); }
5806    
5807     public ParallelArrayWithDoubleMapping<T> withMapping
5808     (LongToDouble op) {
5809     return new ORDMPap<T>(ex, origin, fence, array, selector,
5810     CommonOps.compoundOp(this.op, op));
5811     }
5812    
5813     public ParallelArrayWithLongMapping<T> withMapping
5814     (LongOp op) {
5815     return new ORLMPap<T>(ex, origin, fence, array, selector,
5816     CommonOps.compoundOp(this.op, op));
5817     }
5818    
5819     public <U> ParallelArrayWithMapping<T, U> withMapping
5820     (LongToObject<? extends U> op) {
5821     return new OROMPap<T,U>(ex, origin, fence, array, selector,
5822     CommonOps.compoundOp(this.op, op));
5823     }
5824    
5825     public <V> ParallelArrayWithMapping<T,V> withIndexedMapping
5826     (IntAndLongToObject<? extends V> mapper) {
5827     return new OROCPap<T,V>(ex, origin, fence, array, selector,
5828     compoundIndexedOp(this.op, mapper));
5829     }
5830    
5831     public ParallelArrayWithDoubleMapping<T> withIndexedMapping
5832     (IntAndLongToDouble mapper) {
5833     return new ORDCPap<T>(ex, origin, fence, array, selector,
5834     compoundIndexedOp(this.op, mapper));
5835     }
5836    
5837     public ParallelArrayWithLongMapping<T> withIndexedMapping
5838     (IntAndLongToLong mapper) {
5839     return new ORLCPap<T>(ex, origin, fence, array, selector,
5840     compoundIndexedOp(this.op, mapper));
5841     }
5842    
5843     void leafApply(int lo, int hi, LongProcedure procedure) {
5844     final IntAndObjectPredicate s = selector;
5845     final Object[] a = this.array;
5846     final ObjectToLong f = op;
5847     for (int i = lo; i < hi; ++i) {
5848     Object x = a[i];
5849     if (s.op(i, x))
5850     procedure.op(f.op(x));
5851     }
5852     }
5853    
5854     long leafReduce(int lo, int hi, LongReducer reducer, long base) {
5855     final IntAndObjectPredicate s = selector;
5856     final ObjectToLong f = op;
5857     boolean gotFirst = false;
5858     long r = base;
5859     final Object[] a = this.array;
5860     for (int i = lo; i < hi; ++i) {
5861     Object t = a[i];
5862     if (s.op(i, t)) {
5863     long y = f.op(t);
5864     if (!gotFirst) {
5865     gotFirst = true;
5866     r = y;
5867     }
5868     else
5869     r = reducer.op(r, y);
5870     }
5871     }
5872     return r;
5873     }
5874     }
5875    
5876     static final class DRLMPap extends DLMPap {
5877     final IntAndDoublePredicate selector;
5878     DRLMPap(ForkJoinPool ex, int origin, int fence, double[] array,
5879     IntAndDoublePredicate selector, DoubleToLong op) {
5880     super(ex, origin, fence, array, op);
5881     this.selector = selector;
5882     }
5883    
5884     boolean hasFilter() { return true; }
5885     boolean isSelected(int i) { return selector.op(i, this.array[i]); }
5886    
5887     public ParallelDoubleArrayWithDoubleMapping withMapping
5888     (LongToDouble op) {
5889     return new DRDMPap(ex, origin, fence, array, selector,
5890     CommonOps.compoundOp(this.op, op));
5891     }
5892    
5893     public ParallelDoubleArrayWithLongMapping withMapping
5894     (LongOp op) {
5895     return new DRLMPap(ex, origin, fence, array, selector,
5896     CommonOps.compoundOp(this.op, op));
5897     }
5898    
5899     public <U> ParallelDoubleArrayWithMapping<U> withMapping
5900     (LongToObject<? extends U> op) {
5901     return new DROMPap<U>(ex, origin, fence, array, selector,
5902     CommonOps.compoundOp(this.op, op));
5903     }
5904    
5905     public <V> ParallelDoubleArrayWithMapping<V> withIndexedMapping
5906     (IntAndLongToObject<? extends V> mapper) {
5907     return new DROCPap<V>(ex, origin, fence, array, selector,
5908     compoundIndexedOp(this.op, mapper));
5909     }
5910    
5911     public ParallelDoubleArrayWithDoubleMapping withIndexedMapping
5912     (IntAndLongToDouble mapper) {
5913     return new DRDCPap(ex, origin, fence, array, selector,
5914     compoundIndexedOp(this.op, mapper));
5915     }
5916    
5917     public ParallelDoubleArrayWithLongMapping withIndexedMapping
5918     (IntAndLongToLong mapper) {
5919     return new DRLCPap(ex, origin, fence, array, selector,
5920     compoundIndexedOp(this.op, mapper));
5921     }
5922    
5923     void leafApply(int lo, int hi, LongProcedure procedure) {
5924     final IntAndDoublePredicate s = selector;
5925     final DoubleToLong f = op;
5926     final double[] a = this.array;
5927     for (int i = lo; i < hi; ++i) {
5928     double x = a[i];
5929     if (s.op(i, x))
5930     procedure.op(f.op(x));
5931     }
5932     }
5933    
5934     long leafReduce(int lo, int hi, LongReducer reducer, long base) {
5935     boolean gotFirst = false;
5936     long r = base;
5937     final double[] a = this.array;
5938     final IntAndDoublePredicate s = selector;
5939     final DoubleToLong f = op;
5940     for (int i = lo; i < hi; ++i) {
5941     double t = a[i];
5942     if (s.op(i, t)) {
5943     long y = f.op(t);
5944     if (!gotFirst) {
5945     gotFirst = true;
5946     r = y;
5947     }
5948     else
5949     r = reducer.op(r, y);
5950     }
5951     }
5952     return r;
5953     }
5954     }
5955    
5956     static final class LRLMPap extends LLMPap {
5957     final IntAndLongPredicate selector;
5958     LRLMPap(ForkJoinPool ex, int origin, int fence,
5959     long[] array, IntAndLongPredicate selector, LongOp op) {
5960     super(ex, origin, fence, array, op);
5961     this.selector = selector;
5962     }
5963    
5964     boolean hasFilter() { return true; }
5965     boolean isSelected(int i) { return selector.op(i, this.array[i]); }
5966    
5967     public ParallelLongArrayWithLongMapping withMapping(LongOp op) {
5968     return new LRLMPap(ex, origin, fence, array, selector,
5969     CommonOps.compoundOp(this.op, op));
5970     }
5971    
5972     public ParallelLongArrayWithDoubleMapping withMapping(LongToDouble op) {
5973     return new LRDMPap(ex, origin, fence, array, selector,
5974     CommonOps.compoundOp(this.op, op));
5975     }
5976    
5977     public <U> ParallelLongArrayWithMapping<U> withMapping
5978     (LongToObject<? extends U> op) {
5979     return new LROMPap<U>(ex, origin, fence, array, selector,
5980     CommonOps.compoundOp(this.op, op));
5981     }
5982    
5983     public <V> ParallelLongArrayWithMapping<V> withIndexedMapping
5984     (IntAndLongToObject<? extends V> mapper) {
5985     return new LROCPap<V>(ex, origin, fence, array, selector,
5986     compoundIndexedOp(this.op, mapper));
5987     }
5988    
5989     public ParallelLongArrayWithDoubleMapping withIndexedMapping
5990     (IntAndLongToDouble mapper) {
5991     return new LRDCPap(ex, origin, fence, array, selector,
5992     compoundIndexedOp(this.op, mapper));
5993     }
5994    
5995     public ParallelLongArrayWithLongMapping withIndexedMapping
5996     (IntAndLongToLong mapper) {
5997     return new LRLCPap(ex, origin, fence, array, selector,
5998     compoundIndexedOp(this.op, mapper));
5999     }
6000    
6001     void leafApply(int lo, int hi, LongProcedure procedure) {
6002     final IntAndLongPredicate s = selector;
6003     final LongOp f = op;
6004     final long[] a = this.array;
6005     for (int i = lo; i < hi; ++i) {
6006     long x = a[i];
6007     if (s.op(i, x))
6008     procedure.op(f.op(x));
6009     }
6010     }
6011    
6012     long leafReduce(int lo, int hi, LongReducer reducer, long base) {
6013     final IntAndLongPredicate s = selector;
6014     final LongOp f = op;
6015     boolean gotFirst = false;
6016     long r = base;
6017     final long[] a = this.array;
6018     for (int i = lo; i < hi; ++i) {
6019     long t = a[i];
6020     if (s.op(i, t)) {
6021     long y = f.op(t);
6022     if (!gotFirst) {
6023     gotFirst = true;
6024     r = y;
6025     }
6026     else
6027     r = reducer.op(r, y);
6028     }
6029     }
6030     return r;
6031     }
6032     }
6033    
6034     // long-combined
6035     static abstract class OLCPap<T> extends ParallelArrayWithLongMapping<T> {
6036     final IntAndObjectToLong<? super T> op;
6037     OLCPap(ForkJoinPool ex, int origin, int fence,
6038     T[] array, IntAndObjectToLong<? super T> op) {
6039     super(ex, origin, fence, array);
6040     this.op = op;
6041     }
6042    
6043     final boolean hasMap() { return true; }
6044     final long lget(int i) { return op.op(i, this.array[i]); }
6045     final Object oget(int i) { return Long.valueOf(lget(i)); }
6046     final double dget(int i) { return (double)(lget(i)); }
6047    
6048     final void leafTransfer(int lo, int hi, long[] dest, int offset) {
6049     final IntAndObjectToLong f = op;
6050     final Object[] a = this.array;
6051     for (int i = lo; i < hi; ++i)
6052     dest[offset++] = f.op(i, a[i]);
6053     }
6054    
6055     final void leafTransferByIndex(int[] indices, int loIdx, int hiIdx,
6056     long[] dest, int offset) {
6057     final Object[] a = this.array;
6058     final IntAndObjectToLong f = op;
6059     for (int i = loIdx; i < hiIdx; ++i) {
6060     int idx = indices[i];
6061     dest[offset++] = f.op(idx, a[idx]);
6062     }
6063     }
6064     }
6065    
6066     static abstract class DLCPap extends ParallelDoubleArrayWithLongMapping {
6067     final IntAndDoubleToLong op;
6068     DLCPap(ForkJoinPool ex, int origin, int fence,
6069     double[] array, IntAndDoubleToLong op) {
6070     super(ex, origin, fence, array);
6071     this.op = op;
6072     }
6073    
6074     final boolean hasMap() { return true; }
6075     final long lget(int i) { return op.op(i, this.array[i]); }
6076     final Object oget(int i) { return Long.valueOf(lget(i)); }
6077     final double dget(int i) { return (double)(lget(i)); }
6078    
6079     final void leafTransfer(int lo, int hi, long[] dest, int offset) {
6080     final IntAndDoubleToLong f = op;
6081     final double[] a = this.array;
6082     for (int i = lo; i < hi; ++i)
6083     dest[offset++] = f.op(i, a[i]);
6084     }
6085    
6086     final void leafTransferByIndex(int[] indices, int loIdx, int hiIdx,
6087     long[] dest, int offset) {
6088     final double[] a = this.array;
6089     final IntAndDoubleToLong f = op;
6090     for (int i = loIdx; i < hiIdx; ++i) {
6091     int idx = indices[i];
6092     dest[offset++] = f.op(idx, a[idx]);
6093     }
6094     }
6095     }
6096    
6097     static abstract class LLCPap extends ParallelLongArrayWithLongMapping {
6098     final IntAndLongToLong op;
6099     LLCPap(ForkJoinPool ex, int origin, int fence,
6100     long[] array, IntAndLongToLong op) {
6101     super(ex, origin, fence, array);
6102     this.op = op;
6103     }
6104    
6105     final boolean hasMap() { return true; }
6106     final long lget(int i) { return op.op(i, this.array[i]); }
6107     final Object oget(int i) { return Long.valueOf(lget(i)); }
6108     final double dget(int i) { return (double)(lget(i)); }
6109    
6110     final void leafTransfer(int lo, int hi, long[] dest, int offset) {
6111     final IntAndLongToLong f = op;
6112     final long[] a = this.array;
6113     for (int i = lo; i < hi; ++i)
6114     dest[offset++] = f.op(i, a[i]);
6115     }
6116    
6117     final void leafTransferByIndex(int[] indices, int loIdx, int hiIdx,
6118     long[] dest, int offset) {
6119     final long[] a = this.array;
6120     final IntAndLongToLong f = op;
6121     for (int i = loIdx; i < hiIdx; ++i) {
6122     int idx = indices[i];
6123     dest[offset++] = f.op(idx, a[idx]);
6124     }
6125     }
6126     }
6127    
6128     // long-combined, unfiltered
6129     static final class OULCPap<T> extends OLCPap<T> {
6130     OULCPap(ForkJoinPool ex, int origin, int fence,
6131     T[] array, IntAndObjectToLong<? super T> op) {
6132     super(ex, origin, fence, array, op);
6133     }
6134    
6135     public ParallelArrayWithDoubleMapping<T> withMapping(LongToDouble op) {
6136     return new OUDCPap<T>(ex, origin, fence, array,
6137     compoundIndexedOp(this.op, op));
6138     }
6139    
6140     public ParallelArrayWithLongMapping<T> withMapping(LongOp op) {
6141     return new OULCPap<T>(ex, origin, fence, array,
6142     compoundIndexedOp(this.op, op));
6143     }
6144    
6145     public <U> ParallelArrayWithMapping<T, U> withMapping
6146     (LongToObject<? extends U> op) {
6147     return new OUOCPap<T,U>(ex, origin, fence, array,
6148     compoundIndexedOp(this.op, op));
6149     }
6150    
6151     public <V> ParallelArrayWithMapping<T,V> withIndexedMapping
6152     (IntAndLongToObject<? extends V> mapper) {
6153     return new OUOCPap<T,V>(ex, origin, fence, array,
6154     compoundIndexedOp(this.op, mapper));
6155     }
6156    
6157     public ParallelArrayWithDoubleMapping<T> withIndexedMapping
6158     (IntAndLongToDouble mapper) {
6159     return new OUDCPap<T>(ex, origin, fence, array,
6160     compoundIndexedOp(this.op, mapper));
6161     }
6162    
6163     public ParallelArrayWithLongMapping<T> withIndexedMapping
6164     (IntAndLongToLong mapper) {
6165     return new OULCPap<T>(ex, origin, fence, array,
6166     compoundIndexedOp(this.op, mapper));
6167     }
6168    
6169     void leafApply(int lo, int hi, LongProcedure procedure) {
6170     final IntAndObjectToLong f = op;
6171     final Object[] a = this.array;
6172     for (int i = lo; i < hi; ++i)
6173     procedure.op(f.op(i, a[i]));
6174     }
6175    
6176     long leafReduce(int lo, int hi, LongReducer reducer, long base) {
6177     if (lo >= hi)
6178     return base;
6179     final Object[] a = this.array;
6180     final IntAndObjectToLong f = op;
6181     long r = f.op(lo, a[lo]);
6182     for (int i = lo+1; i < hi; ++i)
6183     r = reducer.op(r, f.op(i, a[i]));
6184     return r;
6185     }
6186    
6187     }
6188     static final class DULCPap extends DLCPap {
6189     DULCPap(ForkJoinPool ex, int origin, int fence,
6190     double[] array, IntAndDoubleToLong op) {
6191     super(ex, origin, fence, array, op);
6192     }
6193    
6194     public ParallelDoubleArrayWithDoubleMapping withMapping
6195     (LongToDouble op) {
6196     return new DUDCPap(ex, origin, fence, array,
6197     compoundIndexedOp(this.op, op));
6198     }
6199    
6200     public ParallelDoubleArrayWithLongMapping withMapping(LongOp op) {
6201     return new DULCPap(ex, origin, fence, array,
6202     compoundIndexedOp(this.op, op));
6203     }
6204    
6205     public <U> ParallelDoubleArrayWithMapping< U> withMapping
6206     (LongToObject<? extends U> op) {
6207     return new DUOCPap<U>(ex, origin, fence, array,
6208     compoundIndexedOp(this.op, op));
6209     }
6210    
6211     public <V> ParallelDoubleArrayWithMapping<V> withIndexedMapping
6212     (IntAndLongToObject<? extends V> mapper) {
6213     return new DUOCPap<V>(ex, origin, fence, array,
6214     compoundIndexedOp(this.op, mapper));
6215     }
6216    
6217     public ParallelDoubleArrayWithDoubleMapping withIndexedMapping
6218     (IntAndLongToDouble mapper) {
6219     return new DUDCPap(ex, origin, fence, array,
6220     compoundIndexedOp(this.op, mapper));
6221     }
6222    
6223     public ParallelDoubleArrayWithLongMapping withIndexedMapping
6224     (IntAndLongToLong mapper) {
6225     return new DULCPap(ex, origin, fence, array,
6226     compoundIndexedOp(this.op, mapper));
6227     }
6228    
6229     void leafApply(int lo, int hi, LongProcedure procedure) {
6230     final IntAndDoubleToLong f = op;
6231     final double[] a = this.array;
6232     for (int i = lo; i < hi; ++i)
6233     procedure.op(f.op(i, a[i]));
6234     }
6235    
6236     long leafReduce(int lo, int hi, LongReducer reducer, long base) {
6237     if (lo >= hi)
6238     return base;
6239     final double[] a = this.array;
6240     final IntAndDoubleToLong f = op;
6241     long r = f.op(lo, a[lo]);
6242     for (int i = lo+1; i < hi; ++i)
6243     r = reducer.op(r, f.op(i, a[i]));
6244     return r;
6245     }
6246     }
6247    
6248     static final class LULCPap extends LLCPap {
6249     LULCPap(ForkJoinPool ex, int origin, int fence,
6250     long[] array, IntAndLongToLong op) {
6251     super(ex, origin, fence, array, op);
6252     }
6253    
6254     public ParallelLongArrayWithDoubleMapping withMapping(LongToDouble op) {
6255     return new LUDCPap(ex, origin, fence, array,
6256     compoundIndexedOp(this.op, op));
6257     }
6258    
6259     public ParallelLongArrayWithLongMapping withMapping(LongOp op) {
6260     return new LULCPap(ex, origin, fence, array,
6261     compoundIndexedOp(this.op, op));
6262     }
6263    
6264     public <U> ParallelLongArrayWithMapping< U> withMapping
6265     (LongToObject<? extends U> op) {
6266     return new LUOCPap<U>(ex, origin, fence, array,
6267     compoundIndexedOp(this.op, op));
6268     }
6269    
6270     public <V> ParallelLongArrayWithMapping<V> withIndexedMapping
6271     (IntAndLongToObject<? extends V> mapper) {
6272     return new LUOCPap<V>(ex, origin, fence, array,
6273     compoundIndexedOp(this.op, mapper));
6274     }
6275    
6276     public ParallelLongArrayWithDoubleMapping withIndexedMapping
6277     (IntAndLongToDouble mapper) {
6278     return new LUDCPap(ex, origin, fence, array,
6279     compoundIndexedOp(this.op, mapper));
6280     }
6281    
6282     public ParallelLongArrayWithLongMapping withIndexedMapping
6283     (IntAndLongToLong mapper) {
6284     return new LULCPap(ex, origin, fence, array,
6285     compoundIndexedOp(this.op, mapper));
6286     }
6287    
6288     void leafApply(int lo, int hi, LongProcedure procedure) {
6289     final IntAndLongToLong f = op;
6290     final long[] a = this.array;
6291     for (int i = lo; i < hi; ++i)
6292     procedure.op(f.op(i, a[i]));
6293     }
6294    
6295     long leafReduce(int lo, int hi, LongReducer reducer, long base) {
6296     if (lo >= hi)
6297     return base;
6298     final long[] a = this.array;
6299     final IntAndLongToLong f = op;
6300     long r = f.op(lo, a[lo]);
6301     for (int i = lo+1; i < hi; ++i)
6302     r = reducer.op(r, f.op(i, a[i]));
6303     return r;
6304     }
6305     }
6306    
6307     // long-combined, filtered
6308     static final class OFLCPap<T> extends OLCPap<T> {
6309     final Predicate<? super T> selector;
6310     OFLCPap(ForkJoinPool ex, int origin, int fence,
6311     T[] array, Predicate<? super T> selector,
6312     IntAndObjectToLong<? super T> op) {
6313     super(ex, origin, fence, array, op);
6314     this.selector = selector;
6315     }
6316    
6317     boolean hasFilter() { return true; }
6318     boolean isSelected(int i) { return selector.op(this.array[i]); }
6319    
6320     public ParallelArrayWithDoubleMapping<T> withMapping(LongToDouble op) {
6321     return new OFDCPap<T>(ex, origin, fence, array, selector,
6322     compoundIndexedOp(this.op, op));
6323     }
6324    
6325     public ParallelArrayWithLongMapping<T> withMapping(LongOp op) {
6326     return new OFLCPap<T>(ex, origin, fence, array, selector,
6327     compoundIndexedOp(this.op, op));
6328     }
6329    
6330     public <U> ParallelArrayWithMapping<T, U> withMapping
6331     (LongToObject<? extends U> op) {
6332     return new OFOCPap<T,U>(ex, origin, fence, array,
6333     selector,
6334     compoundIndexedOp(this.op, op));
6335     }
6336    
6337     public <V> ParallelArrayWithMapping<T,V> withIndexedMapping
6338     (IntAndLongToObject<? extends V> mapper) {
6339     return new OFOCPap<T,V>(ex, origin, fence, array,
6340     selector,
6341     compoundIndexedOp(this.op, mapper));
6342     }
6343    
6344     public ParallelArrayWithDoubleMapping<T> withIndexedMapping
6345     (IntAndLongToDouble mapper) {
6346     return new OFDCPap<T>(ex, origin, fence, array, selector,
6347     compoundIndexedOp(this.op, mapper));
6348     }
6349    
6350     public ParallelArrayWithLongMapping<T> withIndexedMapping
6351     (IntAndLongToLong mapper) {
6352     return new OFLCPap<T>(ex, origin, fence, array, selector,
6353     compoundIndexedOp(this.op, mapper));
6354     }
6355    
6356     void leafApply(int lo, int hi, LongProcedure procedure) {
6357     final Predicate s = selector;
6358     final Object[] a = this.array;
6359     final IntAndObjectToLong f = op;
6360     for (int i = lo; i < hi; ++i) {
6361     Object x = a[i];
6362     if (s.op(x))
6363     procedure.op(f.op(i, x));
6364     }
6365     }
6366    
6367     long leafReduce(int lo, int hi, LongReducer reducer, long base) {
6368     final Predicate s = selector;
6369     final IntAndObjectToLong f = op;
6370     boolean gotFirst = false;
6371     long r = base;
6372     final Object[] a = this.array;
6373     for (int i = lo; i < hi; ++i) {
6374     Object t = a[i];
6375     if (s.op(t)) {
6376     long y = f.op(i, t);
6377     if (!gotFirst) {
6378     gotFirst = true;
6379     r = y;
6380     }
6381     else
6382     r = reducer.op(r, y);
6383     }
6384     }
6385     return r;
6386     }
6387    
6388     }
6389    
6390     static final class DFLCPap extends DLCPap {
6391     final DoublePredicate selector;
6392     DFLCPap(ForkJoinPool ex, int origin, int fence,
6393     double[] array, DoublePredicate selector,
6394     IntAndDoubleToLong op) {
6395     super(ex, origin, fence, array, op);
6396     this.selector = selector;
6397     }
6398    
6399     boolean hasFilter() { return true; }
6400     boolean isSelected(int i) { return selector.op(this.array[i]); }
6401    
6402     public ParallelDoubleArrayWithDoubleMapping withMapping
6403     (LongToDouble op) {
6404     return new DFDCPap(ex, origin, fence, array, selector,
6405     compoundIndexedOp(this.op, op));
6406     }
6407    
6408     public ParallelDoubleArrayWithLongMapping withMapping(LongOp op) {
6409     return new DFLCPap(ex, origin, fence, array, selector,
6410     compoundIndexedOp(this.op, op));
6411     }
6412    
6413     public <U> ParallelDoubleArrayWithMapping< U> withMapping
6414     (LongToObject<? extends U> op) {
6415     return new DFOCPap<U>(ex, origin, fence, array, selector,
6416     compoundIndexedOp(this.op, op));
6417     }
6418    
6419     public <V> ParallelDoubleArrayWithMapping<V> withIndexedMapping
6420     (IntAndLongToObject<? extends V> mapper) {
6421     return new DFOCPap<V>(ex, origin, fence, array, selector,
6422     compoundIndexedOp(this.op, mapper));
6423     }
6424    
6425     public ParallelDoubleArrayWithDoubleMapping withIndexedMapping
6426     (IntAndLongToDouble mapper) {
6427     return new DFDCPap(ex, origin, fence, array, selector,
6428     compoundIndexedOp(this.op, mapper));
6429     }
6430    
6431     public ParallelDoubleArrayWithLongMapping withIndexedMapping
6432     (IntAndLongToLong mapper) {
6433     return new DFLCPap(ex, origin, fence, array, selector,
6434     compoundIndexedOp(this.op, mapper));
6435     }
6436    
6437     void leafApply(int lo, int hi, LongProcedure procedure) {
6438     final DoublePredicate s = selector;
6439     final double[] a = this.array;
6440     final IntAndDoubleToLong f = op;
6441     for (int i = lo; i < hi; ++i) {
6442     double x = a[i];
6443     if (s.op(x))
6444     procedure.op(f.op(i, x));
6445     }
6446     }
6447    
6448     long leafReduce(int lo, int hi, LongReducer reducer, long base) {
6449     final DoublePredicate s = selector;
6450     final IntAndDoubleToLong f = op;
6451     boolean gotFirst = false;
6452     long r = base;
6453     final double[] a = this.array;
6454     for (int i = lo; i < hi; ++i) {
6455     double t = a[i];
6456     if (s.op(t)) {
6457     long y = f.op(i, t);
6458     if (!gotFirst) {
6459     gotFirst = true;
6460     r = y;
6461     }
6462     else
6463     r = reducer.op(r, y);
6464     }
6465     }
6466     return r;
6467     }
6468     }
6469    
6470     static final class LFLCPap extends LLCPap {
6471     final LongPredicate selector;
6472     LFLCPap(ForkJoinPool ex, int origin, int fence,
6473     long[] array, LongPredicate selector,
6474     IntAndLongToLong op) {
6475     super(ex, origin, fence, array, op);
6476     this.selector = selector;
6477     }
6478    
6479     boolean hasFilter() { return true; }
6480     boolean isSelected(int i) { return selector.op(this.array[i]); }
6481    
6482     public ParallelLongArrayWithDoubleMapping withMapping(LongToDouble op) {
6483     return new LFDCPap(ex, origin, fence, array, selector,
6484     compoundIndexedOp(this.op, op));
6485     }
6486    
6487     public ParallelLongArrayWithLongMapping withMapping(LongOp op) {
6488     return new LFLCPap(ex, origin, fence, array, selector,
6489     compoundIndexedOp(this.op, op));
6490     }
6491    
6492     public <U> ParallelLongArrayWithMapping< U> withMapping
6493     (LongToObject<? extends U> op) {
6494     return new LFOCPap<U>(ex, origin, fence, array, selector,
6495     compoundIndexedOp(this.op, op));
6496     }
6497    
6498     public <V> ParallelLongArrayWithMapping<V> withIndexedMapping
6499     (IntAndLongToObject<? extends V> mapper) {
6500     return new LFOCPap<V>(ex, origin, fence, array, selector,
6501     compoundIndexedOp(this.op, mapper));
6502     }
6503    
6504     public ParallelLongArrayWithDoubleMapping withIndexedMapping
6505     (IntAndLongToDouble mapper) {
6506     return new LFDCPap(ex, origin, fence, array, selector,
6507     compoundIndexedOp(this.op, mapper));
6508     }
6509    
6510     public ParallelLongArrayWithLongMapping withIndexedMapping
6511     (IntAndLongToLong mapper) {
6512     return new LFLCPap(ex, origin, fence, array, selector,
6513     compoundIndexedOp(this.op, mapper));
6514     }
6515    
6516     void leafApply(int lo, int hi, LongProcedure procedure) {
6517     final LongPredicate s = selector;
6518     final long[] a = this.array;
6519     final IntAndLongToLong f = op;
6520     for (int i = lo; i < hi; ++i) {
6521     long x = a[i];
6522     if (s.op(x))
6523     procedure.op(f.op(i, x));
6524     }
6525     }
6526    
6527     long leafReduce(int lo, int hi, LongReducer reducer, long base) {
6528     final LongPredicate s = selector;
6529     final IntAndLongToLong f = op;
6530     boolean gotFirst = false;
6531     long r = base;
6532     final long[] a = this.array;
6533     for (int i = lo; i < hi; ++i) {
6534     long t = a[i];
6535     if (s.op(t)) {
6536     long y = f.op(i, t);
6537     if (!gotFirst) {
6538     gotFirst = true;
6539     r = y;
6540     }
6541     else
6542     r = reducer.op(r, y);
6543     }
6544     }
6545     return r;
6546     }
6547     }
6548    
6549     // long-combined, relational
6550     static final class ORLCPap<T> extends OLCPap<T> {
6551     final IntAndObjectPredicate<? super T> selector;
6552     ORLCPap(ForkJoinPool ex, int origin, int fence,
6553     T[] array, IntAndObjectPredicate<? super T> selector,
6554     IntAndObjectToLong<? super T> op) {
6555     super(ex, origin, fence, array, op);
6556     this.selector = selector;
6557     }
6558    
6559     boolean hasFilter() { return true; }
6560     boolean isSelected(int i) { return selector.op(i, this.array[i]); }
6561    
6562     public ParallelArrayWithDoubleMapping<T> withMapping(LongToDouble op) {
6563     return new ORDCPap<T>(ex, origin, fence, array, selector,
6564     compoundIndexedOp(this.op, op));
6565     }
6566    
6567     public ParallelArrayWithLongMapping<T> withMapping(LongOp op) {
6568     return new ORLCPap<T>(ex, origin, fence, array, selector,
6569     compoundIndexedOp(this.op, op));
6570     }
6571    
6572     public <U> ParallelArrayWithMapping<T, U> withMapping
6573     (LongToObject<? extends U> op) {
6574     return new OROCPap<T,U>(ex, origin, fence, array,
6575     selector,
6576     compoundIndexedOp(this.op, op));
6577     }
6578    
6579     public <V> ParallelArrayWithMapping<T,V> withIndexedMapping
6580     (IntAndLongToObject<? extends V> mapper) {
6581     return new OROCPap<T,V>(ex, origin, fence, array,
6582     selector,
6583     compoundIndexedOp(this.op, mapper));
6584     }
6585    
6586     public ParallelArrayWithDoubleMapping<T> withIndexedMapping
6587     (IntAndLongToDouble mapper) {
6588     return new ORDCPap<T>(ex, origin, fence, array, selector,
6589     compoundIndexedOp(this.op, mapper));
6590     }
6591    
6592     public ParallelArrayWithLongMapping<T> withIndexedMapping
6593     (IntAndLongToLong mapper) {
6594     return new ORLCPap<T>(ex, origin, fence, array, selector,
6595     compoundIndexedOp(this.op, mapper));
6596     }
6597    
6598     void leafApply(int lo, int hi, LongProcedure procedure) {
6599     final IntAndObjectPredicate s = selector;
6600     final Object[] a = this.array;
6601     final IntAndObjectToLong f = op;
6602     for (int i = lo; i < hi; ++i) {
6603     Object x = a[i];
6604     if (s.op(i, x))
6605     procedure.op(f.op(i, x));
6606     }
6607     }
6608    
6609     long leafReduce(int lo, int hi, LongReducer reducer, long base) {
6610     final IntAndObjectPredicate s = selector;
6611     final IntAndObjectToLong f = op;
6612     boolean gotFirst = false;
6613     long r = base;
6614     final Object[] a = this.array;
6615     for (int i = lo; i < hi; ++i) {
6616     Object t = a[i];
6617     if (s.op(i, t)) {
6618     long y = f.op(i, t);
6619     if (!gotFirst) {
6620     gotFirst = true;
6621     r = y;
6622     }
6623     else
6624     r = reducer.op(r, y);
6625     }
6626     }
6627     return r;
6628     }
6629    
6630     }
6631    
6632     static final class DRLCPap extends DLCPap {
6633     final IntAndDoublePredicate selector;
6634     DRLCPap(ForkJoinPool ex, int origin, int fence,
6635     double[] array, IntAndDoublePredicate selector,
6636     IntAndDoubleToLong op) {
6637     super(ex, origin, fence, array, op);
6638     this.selector = selector;
6639     }
6640    
6641     boolean hasFilter() { return true; }
6642     boolean isSelected(int i) { return selector.op(i, this.array[i]); }
6643    
6644     public ParallelDoubleArrayWithDoubleMapping withMapping
6645     (LongToDouble op) {
6646     return new DRDCPap(ex, origin, fence, array, selector,
6647     compoundIndexedOp(this.op, op));
6648     }
6649    
6650     public ParallelDoubleArrayWithLongMapping withMapping(LongOp op) {
6651     return new DRLCPap(ex, origin, fence, array, selector,
6652     compoundIndexedOp(this.op, op));
6653     }
6654    
6655     public <U> ParallelDoubleArrayWithMapping< U> withMapping
6656     (LongToObject<? extends U> op) {
6657     return new DROCPap<U>(ex, origin, fence, array, selector,
6658     compoundIndexedOp(this.op, op));
6659     }
6660    
6661     public <V> ParallelDoubleArrayWithMapping<V> withIndexedMapping
6662     (IntAndLongToObject<? extends V> mapper) {
6663     return new DROCPap<V>(ex, origin, fence, array, selector,
6664     compoundIndexedOp(this.op, mapper));
6665     }
6666    
6667     public ParallelDoubleArrayWithDoubleMapping withIndexedMapping
6668     (IntAndLongToDouble mapper) {
6669     return new DRDCPap(ex, origin, fence, array, selector,
6670     compoundIndexedOp(this.op, mapper));
6671     }
6672    
6673     public ParallelDoubleArrayWithLongMapping withIndexedMapping
6674     (IntAndLongToLong mapper) {
6675     return new DRLCPap(ex, origin, fence, array, selector,
6676     compoundIndexedOp(this.op, mapper));
6677     }
6678    
6679     void leafApply(int lo, int hi, LongProcedure procedure) {
6680     final IntAndDoublePredicate s = selector;
6681     final double[] a = this.array;
6682     final IntAndDoubleToLong f = op;
6683     for (int i = lo; i < hi; ++i) {
6684     double x = a[i];
6685     if (s.op(i, x))
6686     procedure.op(f.op(i, x));
6687     }
6688     }
6689    
6690     long leafReduce(int lo, int hi, LongReducer reducer, long base) {
6691     final IntAndDoublePredicate s = selector;
6692     final IntAndDoubleToLong f = op;
6693     boolean gotFirst = false;
6694     long r = base;
6695     final double[] a = this.array;
6696     for (int i = lo; i < hi; ++i) {
6697     double t = a[i];
6698     if (s.op(i, t)) {
6699     long y = f.op(i, t);
6700     if (!gotFirst) {
6701     gotFirst = true;
6702     r = y;
6703     }
6704     else
6705     r = reducer.op(r, y);
6706     }
6707     }
6708     return r;
6709     }
6710     }
6711    
6712     static final class LRLCPap extends LLCPap {
6713     final IntAndLongPredicate selector;
6714     LRLCPap(ForkJoinPool ex, int origin, int fence,
6715     long[] array, IntAndLongPredicate selector,
6716     IntAndLongToLong op) {
6717     super(ex, origin, fence, array, op);
6718     this.selector = selector;
6719     }
6720    
6721     boolean hasFilter() { return true; }
6722     boolean isSelected(int i) { return selector.op(i, this.array[i]); }
6723    
6724     public ParallelLongArrayWithDoubleMapping withMapping(LongToDouble op) {
6725     return new LRDCPap(ex, origin, fence, array, selector,
6726     compoundIndexedOp(this.op, op));
6727     }
6728    
6729     public ParallelLongArrayWithLongMapping withMapping(LongOp op) {
6730     return new LRLCPap(ex, origin, fence, array, selector,
6731     compoundIndexedOp(this.op, op));
6732     }
6733    
6734     public <U> ParallelLongArrayWithMapping< U> withMapping
6735     (LongToObject<? extends U> op) {
6736     return new LROCPap<U>(ex, origin, fence, array, selector,
6737     compoundIndexedOp(this.op, op));
6738     }
6739    
6740     public <V> ParallelLongArrayWithMapping<V> withIndexedMapping
6741     (IntAndLongToObject<? extends V> mapper) {
6742     return new LROCPap<V>(ex, origin, fence, array, selector,
6743     compoundIndexedOp(this.op, mapper));
6744     }
6745    
6746     public ParallelLongArrayWithDoubleMapping withIndexedMapping
6747     (IntAndLongToDouble mapper) {
6748     return new LRDCPap(ex, origin, fence, array, selector,
6749     compoundIndexedOp(this.op, mapper));
6750     }
6751    
6752     public ParallelLongArrayWithLongMapping withIndexedMapping
6753     (IntAndLongToLong mapper) {
6754     return new LRLCPap(ex, origin, fence, array, selector,
6755     compoundIndexedOp(this.op, mapper));
6756     }
6757    
6758     void leafApply(int lo, int hi, LongProcedure procedure) {
6759     final IntAndLongPredicate s = selector;
6760     final long[] a = this.array;
6761     final IntAndLongToLong f = op;
6762     for (int i = lo; i < hi; ++i) {
6763     long x = a[i];
6764     if (s.op(i, x))
6765     procedure.op(f.op(i, x));
6766     }
6767     }
6768    
6769     long leafReduce(int lo, int hi, LongReducer reducer, long base) {
6770     final IntAndLongPredicate s = selector;
6771     final IntAndLongToLong f = op;
6772     boolean gotFirst = false;
6773     long r = base;
6774     final long[] a = this.array;
6775     for (int i = lo; i < hi; ++i) {
6776     long t = a[i];
6777     if (s.op(i, t)) {
6778     long y = f.op(i, t);
6779     if (!gotFirst) {
6780     gotFirst = true;
6781     r = y;
6782     }
6783     else
6784     r = reducer.op(r, y);
6785     }
6786     }
6787     return r;
6788     }
6789     }
6790    
6791     /*
6792     * Iterator support
6793     */
6794    
6795     class SequentiallyAsDouble implements Iterable<Double> {
6796     public Iterator<Double> iterator() {
6797     if (hasFilter())
6798     return new FilteredAsDoubleIterator();
6799     else
6800     return new UnfilteredAsDoubleIterator();
6801     }
6802     }
6803    
6804     class UnfilteredAsDoubleIterator implements Iterator<Double> {
6805     int cursor = origin;
6806     public boolean hasNext() { return cursor < fence; }
6807     public Double next() {
6808     if (cursor >= fence)
6809     throw new NoSuchElementException();
6810     return Double.valueOf(dget(cursor++));
6811     }
6812     public void remove() {
6813     throw new UnsupportedOperationException();
6814     }
6815     }
6816    
6817     class FilteredAsDoubleIterator implements Iterator<Double> {
6818     double next;
6819     int cursor;
6820     FilteredAsDoubleIterator() {
6821     cursor = origin;
6822     advance() ;
6823     }
6824     private void advance() {
6825     while (cursor < fence) {
6826     if (isSelected(cursor)) {
6827     next = dget(cursor);
6828     break;
6829     }
6830     cursor++;
6831     }
6832     }
6833    
6834     public boolean hasNext() { return cursor < fence; }
6835     public Double next() {
6836     if (cursor >= fence)
6837     throw new NoSuchElementException();
6838     Double x = Double.valueOf(next);
6839     cursor++;
6840     advance();
6841     return x;
6842     }
6843     public void remove() {
6844     throw new UnsupportedOperationException();
6845     }
6846     }
6847    
6848     class SequentiallyAsLong implements Iterable<Long> {
6849     public Iterator<Long> iterator() {
6850     if (hasFilter())
6851     return new FilteredAsLongIterator();
6852     else
6853     return new UnfilteredAsLongIterator();
6854     }
6855     }
6856    
6857     class UnfilteredAsLongIterator implements Iterator<Long> {
6858     int cursor = origin;
6859     public boolean hasNext() { return cursor < fence; }
6860     public Long next() {
6861     if (cursor >= fence)
6862     throw new NoSuchElementException();
6863     return Long.valueOf(lget(cursor++));
6864     }
6865     public void remove() {
6866     throw new UnsupportedOperationException();
6867     }
6868     }
6869    
6870     class FilteredAsLongIterator implements Iterator<Long> {
6871     long next;
6872     int cursor;
6873     FilteredAsLongIterator() {
6874     cursor = origin;
6875     advance() ;
6876     }
6877     private void advance() {
6878     while (cursor < fence) {
6879     if (isSelected(cursor)) {
6880     next = lget(cursor);
6881     break;
6882     }
6883     cursor++;
6884     }
6885     }
6886    
6887     public boolean hasNext() { return cursor < fence; }
6888     public Long next() {
6889     if (cursor >= fence)
6890     throw new NoSuchElementException();
6891     Long x = Long.valueOf(next);
6892     cursor++;
6893     advance();
6894     return x;
6895     }
6896     public void remove() {
6897     throw new UnsupportedOperationException();
6898     }
6899     }
6900    
6901     class Sequentially<U> implements Iterable<U> {
6902     public Iterator<U> iterator() {
6903     if (hasFilter())
6904     return new FilteredIterator<U>();
6905     else
6906     return new UnfilteredIterator<U>();
6907     }
6908     }
6909    
6910     class UnfilteredIterator<U> implements Iterator<U> {
6911     int cursor = origin;
6912     public boolean hasNext() { return cursor < fence; }
6913     public U next() {
6914     if (cursor >= fence)
6915     throw new NoSuchElementException();
6916     return (U)oget(cursor++);
6917     }
6918     public void remove() {
6919     throw new UnsupportedOperationException();
6920     }
6921     }
6922    
6923     class FilteredIterator<U> implements Iterator<U> {
6924     Object next;
6925     int cursor;
6926     FilteredIterator() {
6927     cursor = origin;
6928     advance() ;
6929     }
6930     private void advance() {
6931     while (cursor < fence) {
6932     if (isSelected(cursor)) {
6933     next = oget(cursor);
6934     break;
6935     }
6936     cursor++;
6937     }
6938     }
6939    
6940     public boolean hasNext() { return cursor < fence; }
6941     public U next() {
6942     if (cursor >= fence)
6943     throw new NoSuchElementException();
6944     U x = (U)next;
6945     cursor++;
6946     advance();
6947     return x;
6948     }
6949     public void remove() {
6950     throw new UnsupportedOperationException();
6951     }
6952     }
6953    
6954     // Zillions of little classes to support binary ops
6955     // ToDo: specialize to flatten dispatch
6956    
6957     static <T,U,V,W> IntAndObjectToObject<T,V> indexedMapper
6958     (final BinaryOp<? super T, ? super U, ? extends V> combiner,
6959     final ParallelArrayWithMapping<W,U> u, final int origin) {
6960     return new IntAndObjectToObject<T,V>() {
6961     final int offset = u.origin - origin;
6962     public V op(int i, T a) { return combiner.op(a, (U)(u.oget(i+offset))); }
6963     };
6964     }
6965    
6966     static <T,U,W> IntAndObjectToDouble<T> indexedMapper
6967     (final ObjectAndObjectToDouble<? super T, ? super U> combiner,
6968     final ParallelArrayWithMapping<W,U> u, final int origin) {
6969     return new IntAndObjectToDouble<T>() {
6970     final int offset = u.origin - origin;
6971     public double op(int i, T a) { return combiner.op(a, (U)(u.oget(i+offset))); }
6972     };
6973     }
6974    
6975     static <T,U,W> IntAndObjectToLong<T> indexedMapper
6976     (final ObjectAndObjectToLong<? super T, ? super U> combiner,
6977     final ParallelArrayWithMapping<W,U> u, final int origin) {
6978     return new IntAndObjectToLong<T>() {
6979     final int offset = u.origin - origin;
6980     public long op(int i, T a) { return combiner.op(a, (U)(u.oget(i+offset))); }
6981     };
6982     }
6983    
6984     static <T,V> IntAndObjectToObject<T,V> indexedMapper
6985     (final ObjectAndDoubleToObject<? super T, ? extends V> combiner,
6986     final ParallelDoubleArrayWithDoubleMapping u, final int origin) {
6987     return new IntAndObjectToObject<T,V>() {
6988     final int offset = u.origin - origin;
6989     public V op(int i, T a) { return combiner.op(a, u.dget(i+offset)); }
6990     };
6991     }
6992    
6993     static <T> IntAndObjectToDouble<T> indexedMapper
6994     (final ObjectAndDoubleToDouble<? super T> combiner,
6995     final ParallelDoubleArrayWithDoubleMapping u, final int origin) {
6996     return new IntAndObjectToDouble<T>() {
6997     final int offset = u.origin - origin;
6998     public double op(int i, T a) { return combiner.op(a, u.dget(i+offset)); }
6999     };
7000     }
7001    
7002     static <T,U> IntAndObjectToLong<T> indexedMapper
7003     (final ObjectAndDoubleToLong<? super T> combiner,
7004     final ParallelDoubleArrayWithDoubleMapping u, final int origin) {
7005     return new IntAndObjectToLong<T>() {
7006     final int offset = u.origin - origin;
7007     public long op(int i, T a) { return combiner.op(a, u.dget(i+offset)); }
7008     };
7009     }
7010    
7011     static <T,V> IntAndObjectToObject<T,V> indexedMapper
7012     (final ObjectAndLongToObject<? super T, ? extends V> combiner,
7013     final ParallelLongArrayWithLongMapping u, final int origin) {
7014     return new IntAndObjectToObject<T,V>() {
7015     final int offset = u.origin - origin;
7016     public V op(int i, T a) { return combiner.op(a, u.lget(i+offset)); }
7017     };
7018     }
7019    
7020     static <T> IntAndObjectToDouble<T> indexedMapper
7021     (final ObjectAndLongToDouble<? super T> combiner,
7022     final ParallelLongArrayWithLongMapping u, final int origin) {
7023     return new IntAndObjectToDouble<T>() {
7024     final int offset = u.origin - origin;
7025     public double op(int i, T a) { return combiner.op(a, u.lget(i+offset)); }
7026     };
7027     }
7028    
7029     static <T> IntAndObjectToLong<T> indexedMapper
7030     (final ObjectAndLongToLong<? super T> combiner,
7031     final ParallelLongArrayWithLongMapping u, final int origin) {
7032     return new IntAndObjectToLong<T>() {
7033     final int offset = u.origin - origin;
7034     public long op(int i, T a) { return combiner.op(a, u.lget(i+offset)); }
7035     };
7036     }
7037    
7038     static <U,V,W> IntAndDoubleToObject<V> indexedMapper
7039     (final DoubleAndObjectToObject<? super U, ? extends V> combiner,
7040     final ParallelArrayWithMapping<W,U> u, final int origin) {
7041     return new IntAndDoubleToObject<V>() {
7042     final int offset = u.origin - origin;
7043     public V op(int i, double a) { return combiner.op(a, (U)(u.oget(i+offset))); }
7044     };
7045     }
7046    
7047     static <U,W> IntAndDoubleToDouble indexedMapper
7048     (final DoubleAndObjectToDouble<? super U> combiner,
7049     final ParallelArrayWithMapping<W,U> u, final int origin) {
7050     return new IntAndDoubleToDouble() {
7051     final int offset = u.origin - origin;
7052     public double op(int i, double a) { return combiner.op(a, (U)(u.oget(i+offset))); }
7053     };
7054     }
7055    
7056     static <U,W> IntAndDoubleToLong indexedMapper
7057     (final DoubleAndObjectToLong<? super U> combiner,
7058     final ParallelArrayWithMapping<W,U> u, final int origin) {
7059     return new IntAndDoubleToLong() {
7060     final int offset = u.origin - origin;
7061     public long op(int i, double a) { return combiner.op(a, (U)(u.oget(i+offset))); }
7062     };
7063     }
7064    
7065     static <V> IntAndDoubleToObject<V> indexedMapper
7066     (final DoubleAndDoubleToObject<? extends V> combiner,
7067     final ParallelDoubleArrayWithDoubleMapping u, final int origin) {
7068     return new IntAndDoubleToObject<V>() {
7069     final int offset = u.origin - origin;
7070     public V op(int i, double a) { return combiner.op(a, u.dget(i+offset)); }
7071     };
7072     }
7073    
7074     static IntAndDoubleToDouble indexedMapper
7075     (final BinaryDoubleOp combiner,
7076     final ParallelDoubleArrayWithDoubleMapping u, final int origin) {
7077     return new IntAndDoubleToDouble() {
7078     final int offset = u.origin - origin;
7079     public double op(int i, double a) { return combiner.op(a, u.dget(i+offset)); }
7080     };
7081     }
7082    
7083     static IntAndDoubleToLong indexedMapper
7084     (final DoubleAndDoubleToLong combiner,
7085     final ParallelDoubleArrayWithDoubleMapping u, final int origin) {
7086     return new IntAndDoubleToLong() {
7087     final int offset = u.origin - origin;
7088     public long op(int i, double a) { return combiner.op(a, u.dget(i+offset)); }
7089     };
7090     }
7091    
7092     static <V> IntAndDoubleToObject<V> indexedMapper
7093     (final DoubleAndLongToObject<? extends V> combiner,
7094     final ParallelLongArrayWithLongMapping u, final int origin) {
7095     return new IntAndDoubleToObject<V>() {
7096     final int offset = u.origin - origin;
7097     public V op(int i, double a) { return combiner.op(a, u.lget(i+offset)); }
7098     };
7099     }
7100    
7101     static IntAndDoubleToDouble indexedMapper
7102     (final DoubleAndLongToDouble combiner,
7103     final ParallelLongArrayWithLongMapping u, final int origin) {
7104     return new IntAndDoubleToDouble() {
7105     final int offset = u.origin - origin;
7106     public double op(int i, double a) { return combiner.op(a, u.lget(i+offset)); }
7107     };
7108     }
7109    
7110     static IntAndDoubleToLong indexedMapper
7111     (final DoubleAndLongToLong combiner,
7112     final ParallelLongArrayWithLongMapping u, final int origin) {
7113     return new IntAndDoubleToLong() {
7114     final int offset = u.origin - origin;
7115     public long op(int i, double a) { return combiner.op(a, u.lget(i+offset)); }
7116     };
7117     }
7118    
7119     static <U,V,W> IntAndLongToObject<V> indexedMapper
7120     (final LongAndObjectToObject<? super U, ? extends V> combiner,
7121     final ParallelArrayWithMapping<W,U> u, final int origin) {
7122     return new IntAndLongToObject<V>() {
7123     final int offset = u.origin - origin;
7124     public V op(int i, long a) { return combiner.op(a, (U)(u.oget(i+offset))); }
7125     };
7126     }
7127    
7128     static <U,W> IntAndLongToDouble indexedMapper
7129     (final LongAndObjectToDouble<? super U> combiner,
7130     final ParallelArrayWithMapping<W,U> u, final int origin) {
7131     return new IntAndLongToDouble() {
7132     final int offset = u.origin - origin;
7133     public double op(int i, long a) { return combiner.op(a, (U)(u.oget(i+offset))); }
7134     };
7135     }
7136    
7137     static <U,W> IntAndLongToLong indexedMapper
7138     (final LongAndObjectToLong<? super U> combiner,
7139     final ParallelArrayWithMapping<W,U> u, final int origin) {
7140     return new IntAndLongToLong() {
7141     final int offset = u.origin - origin;
7142     public long op(int i, long a) { return combiner.op(a, (U)(u.oget(i+offset))); }
7143     };
7144     }
7145    
7146     static <V> IntAndLongToObject<V> indexedMapper
7147     (final LongAndDoubleToObject<? extends V> combiner,
7148     final ParallelDoubleArrayWithDoubleMapping u, final int origin) {
7149     return new IntAndLongToObject<V>() {
7150     final int offset = u.origin - origin;
7151     public V op(int i, long a) { return combiner.op(a, u.dget(i+offset)); }
7152     };
7153     }
7154    
7155     static IntAndLongToDouble indexedMapper
7156     (final LongAndDoubleToDouble combiner,
7157     final ParallelDoubleArrayWithDoubleMapping u, final int origin) {
7158     return new IntAndLongToDouble() {
7159     final int offset = u.origin - origin;
7160     public double op(int i, long a) { return combiner.op(a, u.dget(i+offset)); }
7161     };
7162     }
7163    
7164     static IntAndLongToLong indexedMapper
7165     (final LongAndDoubleToLong combiner,
7166     final ParallelDoubleArrayWithDoubleMapping u, final int origin) {
7167     return new IntAndLongToLong() {
7168     final int offset = u.origin - origin;
7169     public long op(int i, long a) { return combiner.op(a, u.dget(i+offset)); }
7170     };
7171     }
7172    
7173     static <V> IntAndLongToObject<V> indexedMapper
7174     (final LongAndLongToObject<? extends V> combiner,
7175     final ParallelLongArrayWithLongMapping u, final int origin) {
7176     return new IntAndLongToObject<V>() {
7177     final int offset = u.origin - origin;
7178     public V op(int i, long a) { return combiner.op(a, u.lget(i+offset)); }
7179     };
7180     }
7181    
7182     static IntAndLongToDouble indexedMapper
7183     (final LongAndLongToDouble combiner,
7184     final ParallelLongArrayWithLongMapping u, final int origin) {
7185     return new IntAndLongToDouble() {
7186     final int offset = u.origin - origin;
7187     public double op(int i, long a) { return combiner.op(a, u.lget(i+offset)); }
7188     };
7189     }
7190    
7191     static IntAndLongToLong indexedMapper
7192     (final BinaryLongOp combiner,
7193     final ParallelLongArrayWithLongMapping u, final int origin) {
7194     return new IntAndLongToLong() {
7195     final int offset = u.origin - origin;
7196     public long op(int i, long a) { return combiner.op(a, u.lget(i+offset)); }
7197     };
7198     }
7199    
7200     static <T,U,V> IntAndObjectToObject<T,V> compoundIndexedOp
7201     (final IntAndObjectToObject<? super T, ? extends U> fst,
7202     final IntAndObjectToObject<? super U, ? extends V> snd) {
7203     return new IntAndObjectToObject<T,V>() {
7204     public V op(int i, T a) { return snd.op(i, fst.op(i, a)); }
7205     };
7206     }
7207    
7208     static <T,U> IntAndObjectToDouble<T> compoundIndexedOp
7209     (final IntAndObjectToObject<? super T, ? extends U> fst,
7210     final IntAndObjectToDouble<? super U> snd) {
7211     return new IntAndObjectToDouble<T>() {
7212     public double op(int i, T a) { return snd.op(i, fst.op(i, a)); }
7213     };
7214     }
7215    
7216     static <T,U> IntAndObjectToLong<T> compoundIndexedOp
7217     (final IntAndObjectToObject<? super T, ? extends U> fst,
7218     final IntAndObjectToLong<? super U> snd) {
7219     return new IntAndObjectToLong<T>() {
7220     public long op(int i, T a) { return snd.op(i, fst.op(i, a)); }
7221     };
7222     }
7223    
7224     static <U,V> IntAndDoubleToObject<V> compoundIndexedOp
7225     (final IntAndDoubleToObject<? extends U> fst,
7226     final IntAndObjectToObject<? super U, ? extends V> snd) {
7227     return new IntAndDoubleToObject<V>() {
7228     public V op(int i, double a) { return snd.op(i, fst.op(i, a)); }
7229     };
7230     }
7231    
7232     static <U> IntAndDoubleToDouble compoundIndexedOp
7233     (final IntAndDoubleToObject<? extends U> fst,
7234     final IntAndObjectToDouble<? super U> snd) {
7235     return new IntAndDoubleToDouble() {
7236     public double op(int i, double a) { return snd.op(i, fst.op(i, a)); }
7237     };
7238     }
7239    
7240     static <U> IntAndDoubleToLong compoundIndexedOp
7241     (final IntAndDoubleToObject<? extends U> fst,
7242     final IntAndObjectToLong<? super U> snd) {
7243     return new IntAndDoubleToLong() {
7244     public long op(int i, double a) { return snd.op(i, fst.op(i, a)); }
7245     };
7246     }
7247    
7248     static <U,V> IntAndLongToObject<V> compoundIndexedOp
7249     (final IntAndLongToObject<? extends U> fst,
7250     final IntAndObjectToObject<? super U, ? extends V> snd) {
7251     return new IntAndLongToObject<V>() {
7252     public V op(int i, long a) { return snd.op(i, fst.op(i, a)); }
7253     };
7254     }
7255    
7256     static <U> IntAndLongToDouble compoundIndexedOp
7257     (final IntAndLongToObject<? extends U> fst,
7258     final IntAndObjectToDouble<? super U> snd) {
7259     return new IntAndLongToDouble() {
7260     public double op(int i, long a) { return snd.op(i, fst.op(i, a)); }
7261     };
7262     }
7263    
7264     static <U> IntAndLongToLong compoundIndexedOp
7265     (final IntAndLongToObject<? extends U> fst,
7266     final IntAndObjectToLong<? super U> snd) {
7267     return new IntAndLongToLong() {
7268     public long op(int i, long a) { return snd.op(i, fst.op(i, a)); }
7269     };
7270     }
7271    
7272     static <T,V> IntAndObjectToObject<T,V> compoundIndexedOp
7273     (final IntAndObjectToDouble<? super T> fst,
7274     final IntAndDoubleToObject<? extends V> snd) {
7275     return new IntAndObjectToObject<T,V>() {
7276     public V op(int i, T a) { return snd.op(i, fst.op(i, a)); }
7277     };
7278     }
7279    
7280     static <T> IntAndObjectToDouble<T> compoundIndexedOp
7281     (final IntAndObjectToDouble<? super T> fst,
7282     final IntAndDoubleToDouble snd) {
7283     return new IntAndObjectToDouble<T>() {
7284     public double op(int i, T a) { return snd.op(i, fst.op(i, a)); }
7285     };
7286     }
7287    
7288     static <T> IntAndObjectToLong<T> compoundIndexedOp
7289     (final IntAndObjectToLong<? super T> fst,
7290     final IntAndLongToLong snd) {
7291     return new IntAndObjectToLong<T>() {
7292     public long op(int i, T a) { return snd.op(i, fst.op(i, a)); }
7293     };
7294     }
7295    
7296     static <V> IntAndDoubleToObject<V> compoundIndexedOp
7297     (final IntAndDoubleToLong fst,
7298     final IntAndLongToObject<? extends V> snd) {
7299     return new IntAndDoubleToObject<V>() {
7300     public V op(int i, double a) { return snd.op(i, fst.op(i, a)); }
7301     };
7302     }
7303    
7304     static IntAndDoubleToDouble compoundIndexedOp
7305     (final IntAndDoubleToDouble fst,
7306     final IntAndDoubleToDouble snd) {
7307     return new IntAndDoubleToDouble() {
7308     public double op(int i, double a) { return snd.op(i, fst.op(i, a)); }
7309     };
7310     }
7311    
7312     static IntAndDoubleToLong compoundIndexedOp
7313     (final IntAndDoubleToDouble fst,
7314     final IntAndDoubleToLong snd) {
7315     return new IntAndDoubleToLong() {
7316     public long op(int i, double a) { return snd.op(i, fst.op(i, a)); }
7317     };
7318     }
7319    
7320     static <V> IntAndLongToObject<V> compoundIndexedOp
7321     (final IntAndLongToDouble fst,
7322     final IntAndDoubleToObject<? extends V> snd) {
7323     return new IntAndLongToObject<V>() {
7324     public V op(int i, long a) { return snd.op(i, fst.op(i, a)); }
7325     };
7326     }
7327    
7328     static IntAndLongToDouble compoundIndexedOp
7329     (final IntAndLongToDouble fst,
7330     final IntAndDoubleToDouble snd) {
7331     return new IntAndLongToDouble() {
7332     public double op(int i, long a) { return snd.op(i, fst.op(i, a)); }
7333     };
7334     }
7335    
7336     static IntAndLongToLong compoundIndexedOp
7337     (final IntAndLongToDouble fst,
7338     final IntAndDoubleToLong snd) {
7339     return new IntAndLongToLong() {
7340     public long op(int i, long a) { return snd.op(i, fst.op(i, a)); }
7341     };
7342     }
7343    
7344     static <T,V> IntAndObjectToObject<T,V> compoundIndexedOp
7345     (final IntAndObjectToLong<? super T> fst,
7346     final IntAndLongToObject<? extends V> snd) {
7347     return new IntAndObjectToObject<T,V>() {
7348     public V op(int i, T a) { return snd.op(i, fst.op(i, a)); }
7349     };
7350     }
7351    
7352     static <T> IntAndObjectToDouble<T> compoundIndexedOp
7353     (final IntAndObjectToLong<? super T> fst,
7354     final IntAndLongToDouble snd) {
7355     return new IntAndObjectToDouble<T>() {
7356     public double op(int i, T a) { return snd.op(i, fst.op(i, a)); }
7357     };
7358     }
7359    
7360     static <T> IntAndObjectToLong<T> compoundIndexedOp
7361     (final IntAndObjectToDouble<? super T> fst,
7362     final IntAndDoubleToLong snd) {
7363     return new IntAndObjectToLong<T>() {
7364     public long op(int i, T a) { return snd.op(i, fst.op(i, a)); }
7365     };
7366     }
7367    
7368     static <V> IntAndDoubleToObject<V> compoundIndexedOp
7369     (final IntAndDoubleToDouble fst,
7370     final IntAndDoubleToObject<? extends V> snd) {
7371     return new IntAndDoubleToObject<V>() {
7372     public V op(int i, double a) { return snd.op(i, fst.op(i, a)); }
7373     };
7374     }
7375    
7376     static IntAndDoubleToDouble compoundIndexedOp
7377     (final IntAndDoubleToLong fst,
7378     final IntAndLongToDouble snd) {
7379     return new IntAndDoubleToDouble() {
7380     public double op(int i, double a) { return snd.op(i, fst.op(i, a)); }
7381     };
7382     }
7383    
7384     static IntAndDoubleToLong compoundIndexedOp
7385     (final IntAndDoubleToLong fst,
7386     final IntAndLongToLong snd) {
7387     return new IntAndDoubleToLong() {
7388     public long op(int i, double a) { return snd.op(i, fst.op(i, a)); }
7389     };
7390     }
7391    
7392     static <V> IntAndLongToObject<V> compoundIndexedOp
7393     (final IntAndLongToLong fst,
7394     final IntAndLongToObject<? extends V> snd) {
7395     return new IntAndLongToObject<V>() {
7396     public V op(int i, long a) { return snd.op(i, fst.op(i, a)); }
7397     };
7398     }
7399    
7400     static IntAndLongToDouble compoundIndexedOp
7401     (final IntAndLongToLong fst,
7402     final IntAndLongToDouble snd) {
7403     return new IntAndLongToDouble() {
7404     public double op(int i, long a) { return snd.op(i, fst.op(i, a)); }
7405     };
7406     }
7407    
7408     static IntAndLongToLong compoundIndexedOp
7409     (final IntAndLongToLong fst,
7410     final IntAndLongToLong snd) {
7411     return new IntAndLongToLong() {
7412     public long op(int i, long a) { return snd.op(i, fst.op(i, a)); }
7413     };
7414     }
7415    
7416     static <T,U,V> IntAndObjectToObject<T,V> compoundIndexedOp
7417     (final IntAndObjectToObject<? super T, ? extends U> fst,
7418     final Op<? super U, ? extends V> snd) {
7419     return new IntAndObjectToObject<T,V>() {
7420     public V op(int i, T a) { return snd.op(fst.op(i, a)); }
7421     };
7422     }
7423    
7424     static <T,U> IntAndObjectToDouble<T> compoundIndexedOp
7425     (final IntAndObjectToObject<? super T, ? extends U> fst,
7426     final ObjectToDouble<? super U> snd) {
7427     return new IntAndObjectToDouble<T>() {
7428     public double op(int i, T a) { return snd.op(fst.op(i, a)); }
7429     };
7430     }
7431    
7432     static <T,U> IntAndObjectToLong<T> compoundIndexedOp
7433     (final IntAndObjectToObject<? super T, ? extends U> fst,
7434     final ObjectToLong<? super U> snd) {
7435     return new IntAndObjectToLong<T>() {
7436     public long op(int i, T a) { return snd.op(fst.op(i, a)); }
7437     };
7438     }
7439    
7440     static <U,V> IntAndDoubleToObject<V> compoundIndexedOp
7441     (final IntAndDoubleToObject<? extends U> fst,
7442     final Op<? super U, ? extends V> snd) {
7443     return new IntAndDoubleToObject<V>() {
7444     public V op(int i, double a) { return snd.op(fst.op(i, a)); }
7445     };
7446     }
7447    
7448     static <U> IntAndDoubleToDouble compoundIndexedOp
7449     (final IntAndDoubleToObject<? extends U> fst,
7450     final ObjectToDouble<? super U> snd) {
7451     return new IntAndDoubleToDouble() {
7452     public double op(int i, double a) { return snd.op(fst.op(i, a)); }
7453     };
7454     }
7455    
7456     static <U> IntAndDoubleToLong compoundIndexedOp
7457     (final IntAndDoubleToObject<? extends U> fst,
7458     final ObjectToLong<? super U> snd) {
7459     return new IntAndDoubleToLong() {
7460     public long op(int i, double a) { return snd.op(fst.op(i, a)); }
7461     };
7462     }
7463    
7464     static <U,V> IntAndLongToObject<V> compoundIndexedOp
7465     (final IntAndLongToObject<? extends U> fst,
7466     final Op<? super U, ? extends V> snd) {
7467     return new IntAndLongToObject<V>() {
7468     public V op(int i, long a) { return snd.op(fst.op(i, a)); }
7469     };
7470     }
7471    
7472     static <U> IntAndLongToDouble compoundIndexedOp
7473     (final IntAndLongToObject<? extends U> fst,
7474     final ObjectToDouble<? super U> snd) {
7475     return new IntAndLongToDouble() {
7476     public double op(int i, long a) { return snd.op(fst.op(i, a)); }
7477     };
7478     }
7479    
7480     static <U> IntAndLongToLong compoundIndexedOp
7481     (final IntAndLongToObject<? extends U> fst,
7482     final ObjectToLong<? super U> snd) {
7483     return new IntAndLongToLong() {
7484     public long op(int i, long a) { return snd.op(fst.op(i, a)); }
7485     };
7486     }
7487    
7488     static <T,V> IntAndObjectToObject<T,V> compoundIndexedOp
7489     (final IntAndObjectToDouble<? super T> fst,
7490     final DoubleToObject<? extends V> snd) {
7491     return new IntAndObjectToObject<T,V>() {
7492     public V op(int i, T a) { return snd.op(fst.op(i, a)); }
7493     };
7494     }
7495    
7496     static <T> IntAndObjectToDouble<T> compoundIndexedOp
7497     (final IntAndObjectToDouble<? super T> fst, final DoubleOp snd) {
7498     return new IntAndObjectToDouble<T>() {
7499     public double op(int i, T a) { return snd.op(fst.op(i, a)); }
7500     };
7501     }
7502    
7503     static <T> IntAndObjectToLong<T> compoundIndexedOp
7504     (final IntAndObjectToDouble<? super T> fst, final DoubleToLong snd) {
7505     return new IntAndObjectToLong<T>() {
7506     public long op(int i, T a) { return snd.op(fst.op(i, a)); }
7507     };
7508     }
7509    
7510     static <V> IntAndDoubleToObject<V> compoundIndexedOp
7511     (final IntAndDoubleToDouble fst,
7512     final DoubleToObject<? extends V> snd) {
7513     return new IntAndDoubleToObject<V>() {
7514     public V op(int i, double a) { return snd.op(fst.op(i, a)); }
7515     };
7516     }
7517    
7518     static IntAndDoubleToDouble compoundIndexedOp
7519     (final IntAndDoubleToDouble fst, final DoubleOp snd) {
7520     return new IntAndDoubleToDouble() {
7521     public double op(int i, double a) { return snd.op(fst.op(i, a)); }
7522     };
7523     }
7524    
7525     static IntAndDoubleToLong compoundIndexedOp
7526     (final IntAndDoubleToDouble fst, final DoubleToLong snd) {
7527     return new IntAndDoubleToLong() {
7528     public long op(int i, double a) { return snd.op(fst.op(i, a)); }
7529     };
7530     }
7531    
7532     static <V> IntAndLongToObject<V> compoundIndexedOp
7533     (final IntAndLongToDouble fst, final DoubleToObject<? extends V> snd) {
7534     return new IntAndLongToObject<V>() {
7535     public V op(int i, long a) { return snd.op(fst.op(i, a)); }
7536     };
7537     }
7538    
7539     static IntAndLongToDouble compoundIndexedOp
7540     (final IntAndLongToDouble fst, final DoubleOp snd) {
7541     return new IntAndLongToDouble() {
7542     public double op(int i,long a) { return snd.op(fst.op(i, a)); }
7543     };
7544     }
7545    
7546     static IntAndLongToLong compoundIndexedOp
7547     (final IntAndLongToDouble fst, final DoubleToLong snd) {
7548     return new IntAndLongToLong() {
7549     public long op(int i, long a) { return snd.op(fst.op(i, a)); }
7550     };
7551     }
7552    
7553     static <T,V> IntAndObjectToObject<T,V> compoundIndexedOp
7554     (final IntAndObjectToLong<? super T> fst,
7555     final LongToObject<? extends V> snd) {
7556     return new IntAndObjectToObject<T,V>() {
7557     public V op(int i, T a) { return snd.op(fst.op(i, a)); }
7558     };
7559     }
7560    
7561     static <T> IntAndObjectToDouble<T> compoundIndexedOp
7562     (final IntAndObjectToLong<? super T> fst, final LongToDouble snd) {
7563     return new IntAndObjectToDouble<T>() {
7564     public double op(int i, T a) { return snd.op(fst.op(i, a)); }
7565     };
7566     }
7567    
7568     static <T> IntAndObjectToLong<T> compoundIndexedOp
7569     (final IntAndObjectToLong<? super T> fst, final LongOp snd) {
7570     return new IntAndObjectToLong<T>() {
7571     public long op(int i, T a) { return snd.op(fst.op(i, a)); }
7572     };
7573     }
7574    
7575     static <V> IntAndDoubleToObject<V> compoundIndexedOp
7576     (final IntAndDoubleToLong fst, final LongToObject<? extends V> snd) {
7577     return new IntAndDoubleToObject<V>() {
7578     public V op(int i, double a) { return snd.op(fst.op(i, a)); }
7579     };
7580     }
7581    
7582     static IntAndDoubleToDouble compoundIndexedOp
7583     (final IntAndDoubleToLong fst, final LongToDouble snd) {
7584     return new IntAndDoubleToDouble() {
7585     public double op(int i, double a) { return snd.op(fst.op(i, a)); }
7586     };
7587     }
7588    
7589     static IntAndDoubleToLong compoundIndexedOp
7590     (final IntAndDoubleToLong fst, final LongOp snd) {
7591     return new IntAndDoubleToLong() {
7592     public long op(int i, double a) { return snd.op(fst.op(i, a)); }
7593     };
7594     }
7595    
7596     static <V> IntAndLongToObject<V> compoundIndexedOp
7597     (final IntAndLongToLong fst, final LongToObject<? extends V> snd) {
7598     return new IntAndLongToObject<V>() {
7599     public V op(int i, long a) { return snd.op(fst.op(i, a)); }
7600     };
7601     }
7602    
7603     static IntAndLongToDouble compoundIndexedOp
7604     (final IntAndLongToLong fst, final LongToDouble snd) {
7605     return new IntAndLongToDouble() {
7606     public double op(int i,long a) { return snd.op(fst.op(i, a)); }
7607     };
7608     }
7609    
7610     static IntAndLongToLong compoundIndexedOp
7611     (final IntAndLongToLong fst,
7612     final LongOp snd) {
7613     return new IntAndLongToLong() {
7614     public long op(int i, long a) { return snd.op(fst.op(i, a)); }
7615     };
7616     }
7617    
7618     static <T,U,V> IntAndObjectToObject<T,V> compoundIndexedOp
7619     (final Op<? super T, ? extends U> fst,
7620     final IntAndObjectToObject<? super U, ? extends V> snd) {
7621     return new IntAndObjectToObject<T,V>() {
7622     public V op(int i, T a) { return snd.op(i, fst.op(a)); }
7623     };
7624     }
7625    
7626     static <T,U> IntAndObjectToDouble<T> compoundIndexedOp
7627     (final Op<? super T, ? extends U> fst,
7628     final IntAndObjectToDouble<? super U> snd) {
7629     return new IntAndObjectToDouble<T>() {
7630     public double op(int i, T a) { return snd.op(i, fst.op(a)); }
7631     };
7632     }
7633    
7634     static <T,U> IntAndObjectToLong<T> compoundIndexedOp
7635     (final Op<? super T, ? extends U> fst,
7636     final IntAndObjectToLong<? super U> snd) {
7637     return new IntAndObjectToLong<T>() {
7638     public long op(int i, T a) { return snd.op(i, fst.op(a)); }
7639     };
7640     }
7641    
7642     static <U,V> IntAndDoubleToObject<V> compoundIndexedOp
7643     (final DoubleToObject<? extends U> fst,
7644     final IntAndObjectToObject<? super U, ? extends V> snd) {
7645     return new IntAndDoubleToObject<V>() {
7646     public V op(int i, double a) { return snd.op(i, fst.op(a)); }
7647     };
7648     }
7649    
7650     static <U> IntAndDoubleToDouble compoundIndexedOp
7651     (final DoubleToObject<? extends U> fst,
7652     final IntAndObjectToDouble<? super U> snd) {
7653     return new IntAndDoubleToDouble() {
7654     public double op(int i, double a) { return snd.op(i, fst.op(a)); }
7655     };
7656     }
7657    
7658     static <U> IntAndDoubleToLong compoundIndexedOp
7659     (final DoubleToObject<? extends U> fst,
7660     final IntAndObjectToLong<? super U> snd) {
7661     return new IntAndDoubleToLong() {
7662     public long op(int i, double a) { return snd.op(i, fst.op(a)); }
7663     };
7664     }
7665    
7666     static <U,V> IntAndLongToObject<V> compoundIndexedOp
7667     (final LongToObject<? extends U> fst,
7668     final IntAndObjectToObject<? super U, ? extends V> snd) {
7669     return new IntAndLongToObject<V>() {
7670     public V op(int i, long a) { return snd.op(i, fst.op(a)); }
7671     };
7672     }
7673    
7674     static <U> IntAndLongToDouble compoundIndexedOp
7675     (final LongToObject<? extends U> fst,
7676     final IntAndObjectToDouble<? super U> snd) {
7677     return new IntAndLongToDouble() {
7678     public double op(int i, long a) { return snd.op(i, fst.op(a)); }
7679     };
7680     }
7681    
7682     static <U> IntAndLongToLong compoundIndexedOp
7683     (final LongToObject<? extends U> fst,
7684     final IntAndObjectToLong<? super U> snd) {
7685     return new IntAndLongToLong() {
7686     public long op(int i, long a) { return snd.op(i, fst.op(a)); }
7687     };
7688     }
7689    
7690     static <T,V> IntAndObjectToObject<T,V> compoundIndexedOp
7691     (final ObjectToDouble<? super T> fst,
7692     final IntAndDoubleToObject<? extends V> snd) {
7693     return new IntAndObjectToObject<T,V>() {
7694     public V op(int i, T a) { return snd.op(i, fst.op(a)); }
7695     };
7696     }
7697    
7698     static <T> IntAndObjectToDouble<T> compoundIndexedOp
7699     (final ObjectToDouble<? super T> fst, final IntAndDoubleToDouble snd) {
7700     return new IntAndObjectToDouble<T>() {
7701     public double op(int i, T a) { return snd.op(i, fst.op(a)); }
7702     };
7703     }
7704    
7705     static <T> IntAndObjectToLong<T> compoundIndexedOp
7706     (final ObjectToDouble<? super T> fst, final IntAndDoubleToLong snd) {
7707     return new IntAndObjectToLong<T>() {
7708     public long op(int i, T a) { return snd.op(i, fst.op(a)); }
7709     };
7710     }
7711    
7712     static <V> IntAndDoubleToObject<V> compoundIndexedOp
7713     (final DoubleOp fst, final IntAndDoubleToObject<? extends V> snd) {
7714     return new IntAndDoubleToObject<V>() {
7715     public V op(int i, double a) { return snd.op(i, fst.op(a)); }
7716     };
7717     }
7718    
7719     static IntAndDoubleToDouble compoundIndexedOp
7720     (final DoubleOp fst, final IntAndDoubleToDouble snd) {
7721     return new IntAndDoubleToDouble() {
7722     public double op(int i, double a) { return snd.op(i, fst.op(a)); }
7723     };
7724     }
7725    
7726     static IntAndDoubleToLong compoundIndexedOp
7727     (final DoubleOp fst, final IntAndDoubleToLong snd) {
7728     return new IntAndDoubleToLong() {
7729     public long op(int i, double a) { return snd.op(i, fst.op(a)); }
7730     };
7731     }
7732    
7733     static <V> IntAndLongToObject<V> compoundIndexedOp
7734     (final LongToDouble fst, final IntAndDoubleToObject<? extends V> snd) {
7735     return new IntAndLongToObject<V>() {
7736     public V op(int i, long a) { return snd.op(i, fst.op(a)); }
7737     };
7738     }
7739    
7740     static IntAndLongToDouble compoundIndexedOp
7741     (final LongToDouble fst, final IntAndDoubleToDouble snd) {
7742     return new IntAndLongToDouble() {
7743     public double op(int i, long a) { return snd.op(i, fst.op(a)); }
7744     };
7745     }
7746    
7747     static IntAndLongToLong compoundIndexedOp
7748     (final LongToDouble fst, final IntAndDoubleToLong snd) {
7749     return new IntAndLongToLong() {
7750     public long op(int i, long a) { return snd.op(i, fst.op(a)); }
7751     };
7752     }
7753    
7754     static <T,V> IntAndObjectToObject<T,V> compoundIndexedOp
7755     (final ObjectToLong<? super T> fst,
7756     final IntAndLongToObject<? extends V> snd) {
7757     return new IntAndObjectToObject<T,V>() {
7758     public V op(int i, T a) { return snd.op(i, fst.op(a)); }
7759     };
7760     }
7761    
7762     static <T> IntAndObjectToDouble<T> compoundIndexedOp
7763     (final ObjectToLong<? super T> fst, final IntAndLongToDouble snd) {
7764     return new IntAndObjectToDouble<T>() {
7765     public double op(int i, T a) { return snd.op(i, fst.op(a)); }
7766     };
7767     }
7768    
7769     static <T> IntAndObjectToLong<T> compoundIndexedOp
7770     (final ObjectToLong<? super T> fst, final IntAndLongToLong snd) {
7771     return new IntAndObjectToLong<T>() {
7772     public long op(int i, T a) { return snd.op(i, fst.op(a)); }
7773     };
7774     }
7775    
7776     static <V> IntAndDoubleToObject<V> compoundIndexedOp
7777     (final DoubleToLong fst, final IntAndLongToObject<? extends V> snd) {
7778     return new IntAndDoubleToObject<V>() {
7779     public V op(int i, double a) { return snd.op(i, fst.op(a)); }
7780     };
7781     }
7782    
7783     static IntAndDoubleToDouble compoundIndexedOp
7784     (final DoubleToLong fst, final IntAndLongToDouble snd) {
7785     return new IntAndDoubleToDouble() {
7786     public double op(int i, double a) { return snd.op(i, fst.op(a)); }
7787     };
7788     }
7789    
7790     static IntAndDoubleToLong compoundIndexedOp
7791     (final DoubleToLong fst, final IntAndLongToLong snd) {
7792     return new IntAndDoubleToLong() {
7793     public long op(int i, double a) { return snd.op(i, fst.op(a)); }
7794     };
7795     }
7796    
7797     static <V> IntAndLongToObject<V> compoundIndexedOp
7798     (final LongOp fst, final IntAndLongToObject<? extends V> snd) {
7799     return new IntAndLongToObject<V>() {
7800     public V op(int i, long a) { return snd.op(i, fst.op(a)); }
7801     };
7802     }
7803    
7804     static IntAndLongToDouble compoundIndexedOp
7805     (final LongOp fst, final IntAndLongToDouble snd) {
7806     return new IntAndLongToDouble() {
7807     public double op(int i, long a) { return snd.op(i, fst.op(a)); }
7808     };
7809     }
7810    
7811     static IntAndLongToLong compoundIndexedOp
7812     (final LongOp fst, final IntAndLongToLong snd) {
7813     return new IntAndLongToLong() {
7814     public long op(int i, long a) { return snd.op(i, fst.op(a)); }
7815     };
7816     }
7817    
7818     // binary predicates
7819    
7820     static <T,U,W> IntAndObjectPredicate<T> indexedSelector
7821     (final BinaryPredicate<? super T, ? super U> bp,
7822     final ParallelArrayWithMapping<W,U> u, final int origin) {
7823     return new IntAndObjectPredicate<T>() {
7824     final int offset = u.origin - origin;
7825     public boolean op(int i, T a) {
7826     int k = i + offset;
7827     return u.isSelected(k) && bp.op(a, (U)(u.oget(k)));
7828     }
7829     };
7830     }
7831    
7832     static IntAndDoublePredicate indexedSelector
7833     (final BinaryDoublePredicate bp,
7834     final ParallelDoubleArrayWithDoubleMapping u, final int origin) {
7835     return new IntAndDoublePredicate() {
7836     final int offset = u.origin - origin;
7837     public boolean op(int i, double a) {
7838     int k = i + offset;
7839     return u.isSelected(k) && bp.op(a, u.dget(k));
7840     }
7841     };
7842     }
7843    
7844     static IntAndLongPredicate indexedSelector
7845     (final BinaryLongPredicate bp,
7846     final ParallelLongArrayWithLongMapping u, final int origin) {
7847     return new IntAndLongPredicate() {
7848     final int offset = u.origin - origin;
7849     public boolean op(int i, long a) {
7850     int k = i + offset;
7851     return u.isSelected(k) && bp.op(a, u.lget(k));
7852     }
7853     };
7854     }
7855    
7856     static <S, T extends S> IntAndObjectPredicate<T> compoundIndexedSelector
7857     (final Predicate<S> fst, final IntAndObjectPredicate<? super T> snd) {
7858     return new IntAndObjectPredicate<T>() {
7859     public boolean op(int i, T a) { return fst.op(a) && snd.op(i, a); }
7860     };
7861     }
7862    
7863     static <S, T extends S> IntAndObjectPredicate<T> compoundIndexedSelector
7864     (final IntAndObjectPredicate<S> fst,
7865     final IntAndObjectPredicate<? super T> snd) {
7866     return new IntAndObjectPredicate<T>() {
7867     public boolean op(int i, T a) { return fst.op(i, a) && snd.op(i, a); }
7868     };
7869     }
7870    
7871     static <S, T extends S> IntAndObjectPredicate<T> compoundIndexedSelector
7872     (final IntAndObjectPredicate<S> fst, final Predicate<? super T> snd) {
7873     return new IntAndObjectPredicate<T>() {
7874     public boolean op(int i, T a) { return fst.op(i, a) && snd.op(a); }
7875     };
7876     }
7877    
7878     static IntAndDoublePredicate compoundIndexedSelector
7879     (final DoublePredicate fst, final IntAndDoublePredicate snd) {
7880     return new IntAndDoublePredicate() {
7881     public boolean op(int i, double a) { return fst.op(a) && snd.op(i, a); }
7882     };
7883     }
7884    
7885     static IntAndDoublePredicate compoundIndexedSelector
7886     (final IntAndDoublePredicate fst, final IntAndDoublePredicate snd) {
7887     return new IntAndDoublePredicate() {
7888     public boolean op(int i, double a) { return fst.op(i, a) && snd.op(i, a); }
7889     };
7890     }
7891    
7892     static IntAndDoublePredicate compoundIndexedSelector
7893     (final IntAndDoublePredicate fst, final DoublePredicate snd) {
7894     return new IntAndDoublePredicate() {
7895     public boolean op(int i, double a) { return fst.op(i, a) && snd.op(a); }
7896     };
7897     }
7898    
7899     static IntAndLongPredicate compoundIndexedSelector
7900     (final LongPredicate fst, final IntAndLongPredicate snd) {
7901     return new IntAndLongPredicate() {
7902     public boolean op(int i, long a) { return fst.op(a) && snd.op(i, a); }
7903     };
7904     }
7905    
7906     static IntAndLongPredicate compoundIndexedSelector
7907     (final IntAndLongPredicate fst, final IntAndLongPredicate snd) {
7908     return new IntAndLongPredicate() {
7909     public boolean op(int i, long a) { return fst.op(i, a) && snd.op(i, a); }
7910     };
7911     }
7912    
7913     static IntAndLongPredicate compoundIndexedSelector
7914     (final IntAndLongPredicate fst, final LongPredicate snd) {
7915     return new IntAndLongPredicate() {
7916     public boolean op(int i, long a) { return fst.op(i, a) && snd.op(a); }
7917     };
7918     }
7919    
7920     }