ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/jsr166/jsr166/src/extra166y/AbstractParallelAnyArray.java
Revision: 1.1
Committed: Tue Jan 6 14:30:57 2009 UTC (15 years, 4 months ago) by dl
Branch: MAIN
Log Message:
Repackaged parallel collection classes

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