Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/mobile
Path: blob/master/test/jdk/java/util/Arrays/ArraysEqCmpTest.java
41152 views
1
/*
2
* Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
3
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4
*
5
* This code is free software; you can redistribute it and/or modify it
6
* under the terms of the GNU General Public License version 2 only, as
7
* published by the Free Software Foundation.
8
*
9
* This code is distributed in the hope that it will be useful, but WITHOUT
10
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12
* version 2 for more details (a copy is included in the LICENSE file that
13
* accompanied this code).
14
*
15
* You should have received a copy of the GNU General Public License version
16
* 2 along with this work; if not, write to the Free Software Foundation,
17
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18
*
19
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20
* or visit www.oracle.com if you need additional information or have any
21
* questions.
22
*/
23
24
/*
25
* @test
26
* @bug 8033148 8141409
27
* @summary tests for array equals and compare
28
* @run testng ArraysEqCmpTest
29
*/
30
31
import org.testng.Assert;
32
import org.testng.annotations.DataProvider;
33
import org.testng.annotations.Test;
34
35
import java.lang.invoke.MethodHandle;
36
import java.lang.invoke.MethodHandles;
37
import java.lang.invoke.MethodType;
38
import java.lang.reflect.Array;
39
import java.util.Arrays;
40
import java.util.Comparator;
41
import java.util.HashMap;
42
import java.util.List;
43
import java.util.Map;
44
import java.util.Objects;
45
import java.util.function.BiFunction;
46
import java.util.function.LongFunction;
47
import java.util.stream.IntStream;
48
49
public class ArraysEqCmpTest {
50
51
// Maximum width in bits
52
static final int MAX_WIDTH = 512;
53
54
static final Map<Class, Integer> typeToWidth;
55
56
static {
57
typeToWidth = new HashMap<>();
58
typeToWidth.put(boolean.class, Byte.SIZE);
59
typeToWidth.put(byte.class, Byte.SIZE);
60
typeToWidth.put(short.class, Short.SIZE);
61
typeToWidth.put(char.class, Character.SIZE);
62
typeToWidth.put(int.class, Integer.SIZE);
63
typeToWidth.put(long.class, Long.SIZE);
64
typeToWidth.put(float.class, Float.SIZE);
65
typeToWidth.put(double.class, Double.SIZE);
66
typeToWidth.put(Object.class, Integer.SIZE); // @@@ 32 or 64?
67
}
68
69
static int arraySizeFor(Class<?> type) {
70
type = type.isPrimitive() ? type : Object.class;
71
return 4 * MAX_WIDTH / typeToWidth.get(type);
72
}
73
74
static abstract class ArrayType<T> {
75
final Class<?> arrayType;
76
final Class<?> componentType;
77
final boolean unsigned;
78
79
final MethodHandle cpy;
80
81
final MethodHandle eq;
82
final MethodHandle eqr;
83
final MethodHandle cmp;
84
final MethodHandle cmpr;
85
final MethodHandle mm;
86
final MethodHandle mmr;
87
88
final MethodHandle getter;
89
90
final MethodHandle toString;
91
92
public ArrayType(Class<T> arrayType) {
93
this(arrayType, false);
94
}
95
96
public ArrayType(Class<T> arrayType, boolean unsigned) {
97
this.arrayType = arrayType;
98
this.componentType = arrayType.getComponentType();
99
this.unsigned = unsigned;
100
101
try {
102
MethodHandles.Lookup l = MethodHandles.lookup();
103
104
getter = MethodHandles.arrayElementGetter(arrayType);
105
106
if (componentType.isPrimitive()) {
107
cpy = l.findStatic(Arrays.class, "copyOfRange",
108
MethodType.methodType(arrayType, arrayType, int.class, int.class));
109
110
MethodType eqt = MethodType.methodType(
111
boolean.class, arrayType, arrayType);
112
MethodType eqrt = MethodType.methodType(
113
boolean.class, arrayType, int.class, int.class, arrayType, int.class, int.class);
114
115
eq = l.findStatic(Arrays.class, "equals", eqt);
116
eqr = l.findStatic(Arrays.class, "equals", eqrt);
117
118
String compareName = unsigned ? "compareUnsigned" : "compare";
119
cmp = l.findStatic(Arrays.class, compareName,
120
eqt.changeReturnType(int.class));
121
cmpr = l.findStatic(Arrays.class, compareName,
122
eqrt.changeReturnType(int.class));
123
124
mm = l.findStatic(Arrays.class, "mismatch",
125
eqt.changeReturnType(int.class));
126
mmr = l.findStatic(Arrays.class, "mismatch",
127
eqrt.changeReturnType(int.class));
128
129
toString = l.findStatic(Arrays.class, "toString",
130
MethodType.methodType(String.class, arrayType));
131
}
132
else {
133
cpy = l.findStatic(Arrays.class, "copyOfRange",
134
MethodType.methodType(Object[].class, Object[].class, int.class, int.class));
135
136
MethodType eqt = MethodType.methodType(
137
boolean.class, Object[].class, Object[].class);
138
MethodType eqrt = MethodType.methodType(
139
boolean.class, Object[].class, int.class, int.class, Object[].class, int.class, int.class);
140
141
eq = l.findStatic(Arrays.class, "equals", eqt);
142
eqr = l.findStatic(Arrays.class, "equals", eqrt);
143
144
MethodType cmpt = MethodType.methodType(
145
int.class, Comparable[].class, Comparable[].class);
146
MethodType cmprt = MethodType.methodType(
147
int.class, Comparable[].class, int.class, int.class, Comparable[].class, int.class, int.class);
148
149
cmp = l.findStatic(Arrays.class, "compare", cmpt);
150
cmpr = l.findStatic(Arrays.class, "compare", cmprt);
151
152
mm = l.findStatic(Arrays.class, "mismatch",
153
eqt.changeReturnType(int.class));
154
mmr = l.findStatic(Arrays.class, "mismatch",
155
eqrt.changeReturnType(int.class));
156
157
toString = l.findStatic(Arrays.class, "toString",
158
MethodType.methodType(String.class, Object[].class));
159
}
160
161
}
162
catch (Exception e) {
163
throw new Error(e);
164
}
165
}
166
167
@Override
168
public String toString() {
169
String s = arrayType.getCanonicalName();
170
return unsigned ? "unsigned " + s : s;
171
}
172
173
Object construct(int length) {
174
return Array.newInstance(componentType, length);
175
}
176
177
Object copyOf(Object a) {
178
return copyOf(a, 0, Array.getLength(a));
179
}
180
181
Object copyOf(Object a, int from, int to) {
182
try {
183
return (Object) cpy.invoke(a, from, to);
184
}
185
catch (RuntimeException | Error e) {
186
throw e;
187
}
188
catch (Throwable t) {
189
throw new Error(t);
190
}
191
}
192
193
Object get(Object a, int i) {
194
try {
195
return (Object) getter.invoke(a, i);
196
}
197
catch (RuntimeException | Error e) {
198
throw e;
199
}
200
catch (Throwable t) {
201
throw new Error(t);
202
}
203
}
204
205
abstract void set(Object a, int i, Object v);
206
207
boolean equals(Object a, Object b) {
208
try {
209
return (boolean) eq.invoke(a, b);
210
}
211
catch (RuntimeException | Error e) {
212
throw e;
213
}
214
catch (Throwable t) {
215
throw new Error(t);
216
}
217
}
218
219
boolean equals(Object a, int aFromIndex, int aToIndex,
220
Object b, int bFromIndex, int bToIndex) {
221
try {
222
return (boolean) eqr.invoke(a, aFromIndex, aToIndex, b, bFromIndex, bToIndex);
223
}
224
catch (RuntimeException | Error e) {
225
throw e;
226
}
227
catch (Throwable t) {
228
throw new Error(t);
229
}
230
}
231
232
int compare(Object a, Object b) {
233
try {
234
return (int) cmp.invoke(a, b);
235
}
236
catch (RuntimeException | Error e) {
237
throw e;
238
}
239
catch (Throwable t) {
240
throw new Error(t);
241
}
242
}
243
244
int compare(Object a, int aFromIndex, int aToIndex,
245
Object b, int bFromIndex, int bToIndex) {
246
try {
247
return (int) cmpr.invoke(a, aFromIndex, aToIndex, b, bFromIndex, bToIndex);
248
}
249
catch (RuntimeException | Error e) {
250
throw e;
251
}
252
catch (Throwable t) {
253
throw new Error(t);
254
}
255
}
256
257
int mismatch(Object a, Object b) {
258
try {
259
return (int) mm.invoke(a, b);
260
}
261
catch (RuntimeException | Error e) {
262
throw e;
263
}
264
catch (Throwable t) {
265
throw new Error(t);
266
}
267
}
268
269
int mismatch(Object a, int aFromIndex, int aToIndex,
270
Object b, int bFromIndex, int bToIndex) {
271
try {
272
return (int) mmr.invoke(a, aFromIndex, aToIndex, b, bFromIndex, bToIndex);
273
}
274
catch (RuntimeException | Error e) {
275
throw e;
276
}
277
catch (Throwable t) {
278
throw new Error(t);
279
}
280
}
281
282
String toString(Object a) {
283
try {
284
return (String) toString.invoke(a);
285
}
286
catch (RuntimeException | Error e) {
287
throw e;
288
}
289
catch (Throwable t) {
290
throw new Error(t);
291
}
292
}
293
294
static class BoxedIntegers extends ArrayType<Integer[]> {
295
public BoxedIntegers() {
296
super(Integer[].class);
297
}
298
299
@Override
300
void set(Object a, int i, Object v) {
301
// Ensure unique reference
302
((Integer[]) a)[i] = v != null ? new Integer((Integer) v) : null;
303
}
304
}
305
306
static class BoxedIntegersWithReverseComparator extends BoxedIntegers {
307
final Comparator<Integer> c = (a, b) -> {
308
// Nulls sort after non-nulls
309
if (a == null || b == null)
310
return a == null ? b == null ? 0 : 1 : -1;
311
312
return Integer.compare(b, a);
313
};
314
315
final MethodHandle eqc;
316
final MethodHandle eqcr;
317
final MethodHandle cmpc;
318
final MethodHandle cmpcr;
319
final MethodHandle mismatchc;
320
final MethodHandle mismatchcr;
321
322
public BoxedIntegersWithReverseComparator() {
323
try {
324
MethodHandles.Lookup l = MethodHandles.lookup();
325
326
MethodType cmpt = MethodType.methodType(
327
int.class, Object[].class, Object[].class, Comparator.class);
328
MethodType cmprt = MethodType.methodType(
329
int.class, Object[].class, int.class, int.class,
330
Object[].class, int.class, int.class, Comparator.class);
331
332
eqc = l.findStatic(Arrays.class, "equals", cmpt.changeReturnType(boolean.class));
333
eqcr = l.findStatic(Arrays.class, "equals", cmprt.changeReturnType(boolean.class));
334
cmpc = l.findStatic(Arrays.class, "compare", cmpt);
335
cmpcr = l.findStatic(Arrays.class, "compare", cmprt);
336
mismatchc = l.findStatic(Arrays.class, "mismatch", cmpt);
337
mismatchcr = l.findStatic(Arrays.class, "mismatch", cmprt);
338
}
339
catch (Exception e) {
340
throw new Error(e);
341
}
342
}
343
344
@Override
345
boolean equals(Object a, Object b) {
346
try {
347
return (boolean) eqc.invoke(a, b, c);
348
}
349
catch (RuntimeException | Error e) {
350
throw e;
351
}
352
catch (Throwable t) {
353
throw new Error(t);
354
}
355
}
356
357
@Override
358
boolean equals(Object a, int aFromIndex, int aToIndex,
359
Object b, int bFromIndex, int bToIndex) {
360
try {
361
return (boolean) eqcr.invoke(a, aFromIndex, aToIndex, b, bFromIndex, bToIndex, c);
362
}
363
catch (RuntimeException | Error e) {
364
throw e;
365
}
366
catch (Throwable t) {
367
throw new Error(t);
368
}
369
}
370
371
@Override
372
int compare(Object a, Object b) {
373
try {
374
return (int) cmpc.invoke(a, b, c);
375
}
376
catch (RuntimeException | Error e) {
377
throw e;
378
}
379
catch (Throwable t) {
380
throw new Error(t);
381
}
382
}
383
384
@Override
385
int compare(Object a, int aFromIndex, int aToIndex,
386
Object b, int bFromIndex, int bToIndex) {
387
try {
388
return (int) cmpcr.invoke(a, aFromIndex, aToIndex, b, bFromIndex, bToIndex, c);
389
}
390
catch (RuntimeException | Error e) {
391
throw e;
392
}
393
catch (Throwable t) {
394
throw new Error(t);
395
}
396
}
397
398
@Override
399
int mismatch(Object a, Object b) {
400
try {
401
return (int) mismatchc.invoke(a, b, c);
402
}
403
catch (RuntimeException | Error e) {
404
throw e;
405
}
406
catch (Throwable t) {
407
throw new Error(t);
408
}
409
}
410
411
@Override
412
int mismatch(Object a, int aFromIndex, int aToIndex,
413
Object b, int bFromIndex, int bToIndex) {
414
try {
415
return (int) mismatchcr.invoke(a, aFromIndex, aToIndex, b, bFromIndex, bToIndex, c);
416
}
417
catch (RuntimeException | Error e) {
418
throw e;
419
}
420
catch (Throwable t) {
421
throw new Error(t);
422
}
423
}
424
425
@Override
426
public String toString() {
427
return arrayType.getCanonicalName() + " with Comparator";
428
}
429
}
430
431
static class Booleans extends ArrayType<boolean[]> {
432
public Booleans() {
433
super(boolean[].class);
434
}
435
436
@Override
437
void set(Object a, int i, Object v) {
438
boolean pv;
439
if (v instanceof Boolean) {
440
pv = (Boolean) v;
441
}
442
else if (v instanceof Integer) {
443
pv = ((Integer) v) >= 0;
444
}
445
else throw new IllegalStateException();
446
447
((boolean[]) a)[i] = pv;
448
}
449
}
450
451
static class Bytes extends ArrayType<byte[]> {
452
public Bytes(boolean unsigned) {
453
super(byte[].class, unsigned);
454
}
455
456
@Override
457
void set(Object a, int i, Object v) {
458
byte pv;
459
if (v instanceof Byte) {
460
pv = (Byte) v;
461
}
462
else if (v instanceof Integer) {
463
pv = ((Integer) v).byteValue();
464
}
465
else throw new IllegalStateException();
466
467
((byte[]) a)[i] = pv;
468
}
469
}
470
471
static class Characters extends ArrayType<char[]> {
472
public Characters() {
473
super(char[].class);
474
}
475
476
@Override
477
void set(Object a, int i, Object v) {
478
char pv;
479
if (v instanceof Character) {
480
pv = (Character) v;
481
}
482
else if (v instanceof Integer) {
483
pv = (char) ((Integer) v).intValue();
484
}
485
else throw new IllegalStateException();
486
487
((char[]) a)[i] = pv;
488
}
489
}
490
491
static class Shorts extends ArrayType<short[]> {
492
public Shorts(boolean unsigned) {
493
super(short[].class, unsigned);
494
}
495
496
@Override
497
void set(Object a, int i, Object v) {
498
short pv;
499
if (v instanceof Short) {
500
pv = (Short) v;
501
}
502
else if (v instanceof Integer) {
503
pv = ((Integer) v).shortValue();
504
}
505
else throw new IllegalStateException();
506
507
((short[]) a)[i] = pv;
508
}
509
}
510
511
static class Integers extends ArrayType<int[]> {
512
public Integers(boolean unsigned) {
513
super(int[].class, unsigned);
514
}
515
516
@Override
517
void set(Object a, int i, Object v) {
518
int pv;
519
if (v instanceof Integer) {
520
pv = ((Integer) v).shortValue();
521
}
522
else throw new IllegalStateException();
523
524
((int[]) a)[i] = pv;
525
}
526
}
527
528
static class Longs extends ArrayType<long[]> {
529
public Longs(boolean unsigned) {
530
super(long[].class, unsigned);
531
}
532
533
@Override
534
void set(Object a, int i, Object v) {
535
long pv;
536
if (v instanceof Long) {
537
pv = (Long) v;
538
}
539
else if (v instanceof Integer) {
540
pv = ((Integer) v).longValue();
541
}
542
else throw new IllegalStateException();
543
544
((long[]) a)[i] = pv;
545
}
546
}
547
548
static class Floats extends ArrayType<float[]> {
549
public Floats() {
550
super(float[].class);
551
}
552
553
@Override
554
void set(Object a, int i, Object v) {
555
float pv;
556
if (v instanceof Float) {
557
pv = (Float) v;
558
}
559
else if (v instanceof Integer) {
560
pv = ((Integer) v).floatValue();
561
}
562
else throw new IllegalStateException();
563
564
((float[]) a)[i] = pv;
565
}
566
}
567
568
static class Doubles extends ArrayType<double[]> {
569
public Doubles() {
570
super(double[].class);
571
}
572
573
@Override
574
void set(Object a, int i, Object v) {
575
double pv;
576
if (v instanceof Double) {
577
pv = (Double) v;
578
}
579
else if (v instanceof Integer) {
580
pv = ((Integer) v).doubleValue();
581
}
582
else throw new IllegalStateException();
583
584
((double[]) a)[i] = pv;
585
}
586
}
587
}
588
589
static Object[][] arrayTypes;
590
591
@DataProvider
592
public static Object[][] arrayTypesProvider() {
593
if (arrayTypes == null) {
594
arrayTypes = new Object[][]{
595
new Object[]{new ArrayType.BoxedIntegers()},
596
new Object[]{new ArrayType.BoxedIntegersWithReverseComparator()},
597
new Object[]{new ArrayType.Booleans()},
598
new Object[]{new ArrayType.Bytes(false)},
599
new Object[]{new ArrayType.Bytes(true)},
600
new Object[]{new ArrayType.Characters()},
601
new Object[]{new ArrayType.Shorts(false)},
602
new Object[]{new ArrayType.Shorts(true)},
603
new Object[]{new ArrayType.Integers(false)},
604
new Object[]{new ArrayType.Integers(true)},
605
new Object[]{new ArrayType.Longs(false)},
606
new Object[]{new ArrayType.Longs(true)},
607
new Object[]{new ArrayType.Floats()},
608
new Object[]{new ArrayType.Doubles()},
609
};
610
}
611
return arrayTypes;
612
}
613
614
static Object[][] floatArrayTypes;
615
616
@DataProvider
617
public static Object[][] floatArrayTypesProvider() {
618
if (floatArrayTypes == null) {
619
LongFunction<Object> bTof = rb -> Float.intBitsToFloat((int) rb);
620
LongFunction<Object> bToD = Double::longBitsToDouble;
621
622
floatArrayTypes = new Object[][]{
623
new Object[]{new ArrayType.Floats(), 0x7fc00000L, 0x7f800001L, bTof},
624
new Object[]{new ArrayType.Doubles(), 0x7ff8000000000000L, 0x7ff0000000000001L, bToD},
625
};
626
}
627
return floatArrayTypes;
628
}
629
630
static Object[][] objectArrayTypes;
631
632
@DataProvider
633
public static Object[][] objectArrayTypesProvider() {
634
if (objectArrayTypes == null) {
635
LongFunction<Object> bTof = rb -> Float.intBitsToFloat((int) rb);
636
LongFunction<Object> bToD = Double::longBitsToDouble;
637
638
objectArrayTypes = new Object[][]{
639
new Object[]{new ArrayType.BoxedIntegers()},
640
new Object[]{new ArrayType.BoxedIntegersWithReverseComparator()},
641
};
642
}
643
return objectArrayTypes;
644
}
645
646
647
static Object[][] signedUnsignedArrayTypes;
648
649
@DataProvider
650
public static Object[][] signedUnsignedArrayTypes() {
651
if (signedUnsignedArrayTypes == null) {
652
signedUnsignedArrayTypes = new Object[][]{
653
new Object[]{new ArrayType.Bytes(false), new ArrayType.Bytes(true)},
654
new Object[]{new ArrayType.Shorts(false), new ArrayType.Shorts(true)},
655
new Object[]{new ArrayType.Integers(false), new ArrayType.Integers(true)},
656
new Object[]{new ArrayType.Longs(false), new ArrayType.Longs(true)},
657
};
658
}
659
return signedUnsignedArrayTypes;
660
}
661
662
// Equality and comparison tests
663
664
@Test(dataProvider = "arrayTypesProvider")
665
public void testArray(ArrayType<?> arrayType) {
666
BiFunction<ArrayType<?>, Integer, Object> constructor = (at, s) -> {
667
Object a = at.construct(s);
668
for (int x = 0; x < s; x++) {
669
at.set(a, x, x % 8);
670
}
671
return a;
672
};
673
674
BiFunction<ArrayType<?>, Object, Object> cloner = (at, a) ->
675
constructor.apply(at, Array.getLength(a));
676
677
testArrayType(arrayType, constructor, cloner);
678
}
679
680
@Test(dataProvider = "floatArrayTypesProvider")
681
public void testPrimitiveFloatArray(
682
ArrayType<?> arrayType,
683
long canonicalNanRawBits, long nonCanonicalNanRawBits,
684
LongFunction<Object> bitsToFloat) {
685
Object canonicalNan = bitsToFloat.apply(canonicalNanRawBits);
686
// If conversion is a signalling NaN it may be subject to conversion to a
687
// quiet NaN on some processors, even if a copy is performed
688
// The tests assume that if conversion occurs it does not convert to the
689
// canonical NaN
690
Object nonCanonicalNan = bitsToFloat.apply(nonCanonicalNanRawBits);
691
692
BiFunction<ArrayType<?>, Integer, Object> canonicalNaNs = (at, s) -> {
693
Object a = at.construct(s);
694
for (int x = 0; x < s; x++) {
695
at.set(a, x, canonicalNan);
696
}
697
return a;
698
};
699
700
BiFunction<ArrayType<?>, Object, Object> nonCanonicalNaNs = (at, a) -> {
701
int s = Array.getLength(a);
702
Object ac = at.construct(s);
703
for (int x = 0; x < s; x++) {
704
at.set(ac, x, nonCanonicalNan);
705
}
706
return ac;
707
};
708
709
BiFunction<ArrayType<?>, Object, Object> halfNonCanonicalNaNs = (at, a) -> {
710
int s = Array.getLength(a);
711
Object ac = at.construct(s);
712
for (int x = 0; x < s / 2; x++) {
713
at.set(ac, x, nonCanonicalNan);
714
}
715
for (int x = s / 2; x < s; x++) {
716
at.set(ac, x, 1);
717
}
718
return ac;
719
};
720
721
testArrayType(arrayType, canonicalNaNs, nonCanonicalNaNs);
722
testArrayType(arrayType, canonicalNaNs, halfNonCanonicalNaNs);
723
}
724
725
@Test(dataProvider = "objectArrayTypesProvider")
726
public void testNullElementsInObjectArray(ArrayType<?> arrayType) {
727
BiFunction<ArrayType<?>, Object, Object> cloner = ArrayType::copyOf;
728
729
// All nulls
730
testArrayType(arrayType,
731
(at, s) -> {
732
Object a = at.construct(s);
733
for (int x = 0; x < s; x++) {
734
at.set(a, x, null);
735
}
736
return a;
737
},
738
cloner);
739
740
741
// Some nulls
742
testArrayType(arrayType,
743
(at, s) -> {
744
Object a = at.construct(s);
745
for (int x = 0; x < s; x++) {
746
int v = x % 8;
747
at.set(a, x, v == 0 ? null : v);
748
}
749
return a;
750
},
751
cloner);
752
753
Integer[] a = new Integer[]{null, 0};
754
Integer[] b = new Integer[]{0, 0};
755
Assert.assertTrue(Arrays.compare(a, b) < 0);
756
Assert.assertTrue(Arrays.compare(b, a) > 0);
757
}
758
759
@Test(dataProvider = "objectArrayTypesProvider")
760
public void testSameRefElementsInObjectArray(ArrayType<?> arrayType) {
761
BiFunction<ArrayType<?>, Object, Object> cloner = ArrayType::copyOf;
762
763
// One ref
764
Integer one = 1;
765
testArrayType(arrayType,
766
(at, s) -> {
767
Integer[] a = (Integer[]) at.construct(s);
768
for (int x = 0; x < s; x++) {
769
a[x] = one;
770
}
771
return a;
772
},
773
cloner);
774
775
// All ref
776
testArrayType(arrayType,
777
(at, s) -> {
778
Integer[] a = (Integer[]) at.construct(s);
779
for (int x = 0; x < s; x++) {
780
a[x] = Integer.valueOf(s);
781
}
782
return a;
783
},
784
cloner);
785
786
// Some same ref
787
testArrayType(arrayType,
788
(at, s) -> {
789
Integer[] a = (Integer[]) at.construct(s);
790
for (int x = 0; x < s; x++) {
791
int v = x % 8;
792
a[x] = v == 1 ? one : new Integer(v);
793
}
794
return a;
795
},
796
cloner);
797
}
798
799
@Test(dataProvider = "signedUnsignedArrayTypes")
800
public void testSignedUnsignedArray(ArrayType<?> sat, ArrayType<?> uat) {
801
BiFunction<ArrayType<?>, Integer, Object> constructor = (at, s) -> {
802
Object a = at.construct(s);
803
for (int x = 0; x < s; x++) {
804
at.set(a, x, 1);
805
}
806
return a;
807
};
808
809
int n = arraySizeFor(sat.componentType);
810
811
for (int s : ranges(0, n)) {
812
Object a = constructor.apply(sat, s);
813
814
for (int aFrom : ranges(0, s)) {
815
for (int aTo : ranges(aFrom, s)) {
816
int aLength = aTo - aFrom;
817
818
if (aLength > 0) {
819
for (int i = aFrom; i < aTo; i++) {
820
Object ac = sat.copyOf(a);
821
// Create common prefix with a length of i - aFrom
822
sat.set(ac, i, -1);
823
824
int sc = sat.compare(ac, aFrom, aTo, a, aFrom, aTo);
825
int uc = uat.compare(ac, aFrom, aTo, a, aFrom, aTo);
826
827
Assert.assertTrue(sc < 0);
828
Assert.assertTrue(uc > 0);
829
}
830
}
831
}
832
}
833
}
834
}
835
836
void testArrayType(ArrayType<?> at,
837
BiFunction<ArrayType<?>, Integer, Object> constructor,
838
BiFunction<ArrayType<?>, Object, Object> cloner) {
839
int n = arraySizeFor(at.componentType);
840
841
for (int s : ranges(0, n)) {
842
Object a = constructor.apply(at, s);
843
Object b = cloner.apply(at, a);
844
845
for (int aFrom : ranges(0, s)) {
846
for (int aTo : ranges(aFrom, s)) {
847
int aLength = aTo - aFrom;
848
849
for (int bFrom : ranges(0, s)) {
850
for (int bTo : ranges(bFrom, s)) {
851
int bLength = bTo - bFrom;
852
853
Object anr = at.copyOf(a, aFrom, aTo);
854
Object bnr = at.copyOf(b, bFrom, bTo);
855
856
boolean eq = isEqual(at, a, aFrom, aTo, b, bFrom, bTo);
857
Assert.assertEquals(at.equals(a, aFrom, aTo, b, bFrom, bTo), eq);
858
Assert.assertEquals(at.equals(b, bFrom, bTo, a, aFrom, aTo), eq);
859
Assert.assertEquals(at.equals(anr, bnr), eq);
860
Assert.assertEquals(at.equals(bnr, anr), eq);
861
if (eq) {
862
Assert.assertEquals(at.compare(a, aFrom, aTo, b, bFrom, bTo), 0);
863
Assert.assertEquals(at.compare(b, bFrom, bTo, a, aFrom, aTo), 0);
864
Assert.assertEquals(at.compare(anr, bnr), 0);
865
Assert.assertEquals(at.compare(bnr, anr), 0);
866
867
Assert.assertEquals(at.mismatch(a, aFrom, aTo, b, bFrom, bTo), -1);
868
Assert.assertEquals(at.mismatch(b, bFrom, bTo, a, aFrom, aTo), -1);
869
Assert.assertEquals(at.mismatch(anr, bnr), -1);
870
Assert.assertEquals(at.mismatch(bnr, anr), -1);
871
}
872
else {
873
int aCb = at.compare(a, aFrom, aTo, b, bFrom, bTo);
874
int bCa = at.compare(b, bFrom, bTo, a, aFrom, aTo);
875
int v = Integer.signum(aCb) * Integer.signum(bCa);
876
Assert.assertTrue(v == -1);
877
878
int anrCbnr = at.compare(anr, bnr);
879
int bnrCanr = at.compare(bnr, anr);
880
Assert.assertEquals(anrCbnr, aCb);
881
Assert.assertEquals(bnrCanr, bCa);
882
883
884
int aMb = at.mismatch(a, aFrom, aTo, b, bFrom, bTo);
885
int bMa = at.mismatch(b, bFrom, bTo, a, aFrom, aTo);
886
int anrMbnr = at.mismatch(anr, bnr);
887
int bnrManr = at.mismatch(bnr, anr);
888
889
Assert.assertNotEquals(aMb, -1);
890
Assert.assertEquals(aMb, bMa);
891
Assert.assertNotEquals(anrMbnr, -1);
892
Assert.assertEquals(anrMbnr, bnrManr);
893
Assert.assertEquals(aMb, anrMbnr);
894
Assert.assertEquals(bMa, bnrManr);
895
896
// Common or proper prefix
897
Assert.assertTrue(at.equals(a, aFrom, aFrom + aMb, b, bFrom, bFrom + aMb));
898
if (aMb < Math.min(aLength, bLength)) {
899
// Common prefix
900
Assert.assertFalse(isEqual(at, a, aFrom + aMb, b, bFrom + aMb));
901
}
902
}
903
}
904
}
905
906
if (aLength > 0) {
907
for (int i = aFrom; i < aTo; i++) {
908
Object ac = at.copyOf(a);
909
// Create common prefix with a length of i - aFrom
910
at.set(ac, i, -1);
911
912
Object acnr = at.copyOf(ac, aFrom, aTo);
913
Object anr = at.copyOf(a, aFrom, aTo);
914
915
Assert.assertFalse(at.equals(ac, aFrom, aTo, a, aFrom, aTo));
916
Assert.assertFalse(at.equals(acnr, anr));
917
918
int acCa = at.compare(ac, aFrom, aTo, a, aFrom, aTo);
919
int aCac = at.compare(a, aFrom, aTo, ac, aFrom, aTo);
920
int v = Integer.signum(acCa) * Integer.signum(aCac);
921
Assert.assertTrue(v == -1);
922
923
int acnrCanr = at.compare(acnr, anr);
924
int anrCacnr = at.compare(anr, acnr);
925
Assert.assertEquals(acnrCanr, acCa);
926
Assert.assertEquals(anrCacnr, aCac);
927
928
929
int acMa = at.mismatch(ac, aFrom, aTo, a, aFrom, aTo);
930
int aMac = at.mismatch(a, aFrom, aTo, ac, aFrom, aTo);
931
Assert.assertEquals(acMa, aMac);
932
Assert.assertEquals(acMa, i - aFrom);
933
934
int acnrManr = at.mismatch(acnr, anr);
935
int anrMacnr = at.mismatch(anr, acnr);
936
Assert.assertEquals(acnrManr, anrMacnr);
937
Assert.assertEquals(acnrManr, i - aFrom);
938
}
939
}
940
}
941
}
942
}
943
}
944
945
static boolean isEqual(ArrayType<?> at, Object a, int aFromIndex, int aToIndex,
946
Object b, int bFromIndex, int bToIndex) {
947
int aLength = aToIndex - aFromIndex;
948
int bLength = bToIndex - bFromIndex;
949
if (aLength != bLength)
950
return false;
951
952
for (int i = 0; i < aLength; i++) {
953
Object av = at.get(a, aFromIndex++);
954
Object bv = at.get(b, bFromIndex++);
955
if (!Objects.equals(av, bv)) return false;
956
}
957
958
return true;
959
}
960
961
static boolean isEqual(ArrayType<?> at, Object a, int aFrom, Object b, int bFrom) {
962
Object av = at.get(a, aFrom);
963
Object bv = at.get(b, bFrom);
964
965
return Objects.equals(av, bv);
966
}
967
968
static int[] ranges(int from, int to) {
969
int width = to - from;
970
switch (width) {
971
case 0:
972
return new int[]{};
973
case 1:
974
return new int[]{from, to};
975
case 2:
976
return new int[]{from, from + 1, to};
977
case 3:
978
return new int[]{from, from + 1, from + 2, to};
979
default:
980
return IntStream.of(from, from + 1, from + 2, to / 2 - 1, to / 2, to / 2 + 1, to - 2, to - 1, to)
981
.filter(i -> i >= from && i <= to)
982
.distinct().toArray();
983
}
984
}
985
986
987
// Null array reference tests
988
989
@Test(dataProvider = "arrayTypesProvider")
990
public void testNullArrayRefs(ArrayType<?> arrayType) {
991
Object n = null;
992
Object a = arrayType.construct(0);
993
994
Assert.assertTrue(arrayType.equals(n, n));
995
Assert.assertFalse(arrayType.equals(n, a));
996
Assert.assertFalse(arrayType.equals(a, n));
997
998
Assert.assertEquals(arrayType.compare(n, n), 0);
999
Assert.assertTrue(arrayType.compare(n, a) < 0);
1000
Assert.assertTrue(arrayType.compare(a, n) > 0);
1001
}
1002
1003
1004
// Exception throwing tests
1005
1006
@Test(dataProvider = "arrayTypesProvider")
1007
public void testNPEs(ArrayType<?> arrayType) {
1008
Object[] values = new Object[]{null, arrayType.construct(0)};
1009
1010
for (Object o1 : values) {
1011
for (Object o2 : values) {
1012
if (o1 != null && o2 != null)
1013
continue;
1014
1015
testNPE(() -> arrayType.equals(o1, 0, 0, o2, 0, 0));
1016
testNPE(() -> arrayType.compare(o1, 0, 0, o2, 0, 0));
1017
testNPE(() -> arrayType.mismatch(o1, o2));
1018
testNPE(() -> arrayType.mismatch(o1, 0, 0, o2, 0, 0));
1019
}
1020
}
1021
}
1022
1023
@Test
1024
public void testObjectNPEs() {
1025
String[][] values = new String[][]{null, new String[0]};
1026
Comparator<String> c = String::compareTo;
1027
Comparator[] cs = new Comparator[]{null, c};
1028
1029
for (String[] o1 : values) {
1030
for (String[] o2 : values) {
1031
for (Comparator o3 : cs) {
1032
if (o1 != null && o2 != null && o3 != null)
1033
continue;
1034
1035
if (o3 == null) {
1036
testNPE(() -> Arrays.equals(o1, o2, o3));
1037
testNPE(() -> Arrays.compare(o1, o2, o3));
1038
testNPE(() -> Arrays.mismatch(o1, o2, o3));
1039
}
1040
1041
testNPE(() -> Arrays.equals(o1, 0, 0, o2, 0, 0, o3));
1042
testNPE(() -> Arrays.compare(o1, 0, 0, o2, 0, 0, o3));
1043
testNPE(() -> Arrays.mismatch(o1, 0, 0, o2, 0, 0, o3));
1044
}
1045
}
1046
}
1047
}
1048
1049
@Test(dataProvider = "arrayTypesProvider")
1050
public void testIAEs(ArrayType<?> arrayType) {
1051
List<Integer> values = Arrays.asList(0, 1);
1052
1053
for (int s : values) {
1054
Object a = arrayType.construct(s);
1055
1056
for (int o1 : values) {
1057
for (int o2 : values) {
1058
if (o1 <= o2) continue;
1059
1060
testIAE(() -> arrayType.equals(a, o1, 0, a, o2, 0));
1061
testIAE(() -> arrayType.compare(a, o1, 0, a, o2, 0));
1062
testIAE(() -> arrayType.mismatch(a, o1, 0, a, o2, 0));
1063
}
1064
}
1065
}
1066
}
1067
1068
@Test(dataProvider = "arrayTypesProvider")
1069
public void testAIOBEs(ArrayType<?> arrayType) {
1070
List<Integer> froms = Arrays.asList(-1, 0);
1071
1072
for (int s : Arrays.asList(0, 1)) {
1073
List<Integer> tos = Arrays.asList(s, s + 1);
1074
Object a = arrayType.construct(s);
1075
1076
for (int aFrom : froms) {
1077
for (int aTo : tos) {
1078
for (int bFrom : froms) {
1079
for (int bTo : tos) {
1080
if (aFrom >= 0 && aTo <= s &&
1081
bFrom >= 0 && bTo <= s) continue;
1082
1083
testAIOBE(() -> arrayType.equals(a, aFrom, aTo, a, bFrom, bTo));
1084
testAIOBE(() -> arrayType.compare(a, aFrom, aTo, a, bFrom, bTo));
1085
testAIOBE(() -> arrayType.mismatch(a, aFrom, aTo, a, bFrom, bTo));
1086
}
1087
}
1088
}
1089
}
1090
}
1091
}
1092
1093
static void testNPE(Runnable r) {
1094
testThrowable(r, NullPointerException.class);
1095
}
1096
1097
static void testIAE(Runnable r) {
1098
testThrowable(r, IllegalArgumentException.class);
1099
}
1100
1101
static void testAIOBE(Runnable r) {
1102
testThrowable(r, ArrayIndexOutOfBoundsException.class);
1103
}
1104
1105
static void testThrowable(Runnable r, Class<? extends Throwable> expected) {
1106
Throwable caught = null;
1107
try {
1108
r.run();
1109
}
1110
catch (Throwable t) {
1111
caught = t;
1112
}
1113
Assert.assertNotNull(caught);
1114
Assert.assertTrue(expected.isInstance(caught));
1115
}
1116
}
1117