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 junit ArraysEqCmpTest
29 */
30
31
32 import java.lang.invoke.MethodHandle;
33 import java.lang.invoke.MethodHandles;
34 import java.lang.invoke.MethodType;
35 import java.lang.reflect.Array;
36 import java.util.Arrays;
37 import java.util.Comparator;
38 import java.util.HashMap;
39 import java.util.List;
40 import java.util.Map;
41 import java.util.Objects;
42 import java.util.function.BiFunction;
43 import java.util.function.LongFunction;
44 import java.util.stream.IntStream;
45
46 import org.junit.jupiter.api.Assertions;
47 import org.junit.jupiter.api.Test;
48 import org.junit.jupiter.api.TestInstance;
49 import org.junit.jupiter.params.ParameterizedTest;
50 import org.junit.jupiter.params.provider.MethodSource;
51
52 @TestInstance(TestInstance.Lifecycle.PER_CLASS)
53 public class ArraysEqCmpTest {
54
55 // Maximum width in bits
56 static final int MAX_WIDTH = 512;
57
58 static final Map<Class, Integer> typeToWidth;
59
60 static {
61 typeToWidth = new HashMap<>();
62 typeToWidth.put(boolean.class, Byte.SIZE);
63 typeToWidth.put(byte.class, Byte.SIZE);
64 typeToWidth.put(short.class, Short.SIZE);
65 typeToWidth.put(char.class, Character.SIZE);
66 typeToWidth.put(int.class, Integer.SIZE);
67 typeToWidth.put(long.class, Long.SIZE);
68 typeToWidth.put(float.class, Float.SIZE);
69 typeToWidth.put(double.class, Double.SIZE);
70 typeToWidth.put(Object.class, Integer.SIZE); // @@@ 32 or 64?
71 }
72
73 static int arraySizeFor(Class<?> type) {
74 type = type.isPrimitive() ? type : Object.class;
75 return 4 * MAX_WIDTH / typeToWidth.get(type);
76 }
77
78 static abstract class ArrayType<T> {
79 final Class<?> arrayType;
571
572 static class Doubles extends ArrayType<double[]> {
573 public Doubles() {
574 super(double[].class);
575 }
576
577 @Override
578 void set(Object a, int i, Object v) {
579 double pv;
580 if (v instanceof Double) {
581 pv = (Double) v;
582 }
583 else if (v instanceof Integer) {
584 pv = ((Integer) v).doubleValue();
585 }
586 else throw new IllegalStateException();
587
588 ((double[]) a)[i] = pv;
589 }
590 }
591 }
592
593 static Object[][] arrayTypes;
594
595 public static Object[][] arrayTypesProvider() {
596 if (arrayTypes == null) {
597 arrayTypes = new Object[][]{
598 new Object[]{new ArrayType.BoxedIntegers()},
599 new Object[]{new ArrayType.BoxedIntegersWithReverseComparator()},
600 new Object[]{new ArrayType.Booleans()},
601 new Object[]{new ArrayType.Bytes(false)},
602 new Object[]{new ArrayType.Bytes(true)},
603 new Object[]{new ArrayType.Characters()},
604 new Object[]{new ArrayType.Shorts(false)},
605 new Object[]{new ArrayType.Shorts(true)},
606 new Object[]{new ArrayType.Integers(false)},
607 new Object[]{new ArrayType.Integers(true)},
608 new Object[]{new ArrayType.Longs(false)},
609 new Object[]{new ArrayType.Longs(true)},
610 new Object[]{new ArrayType.Floats()},
611 new Object[]{new ArrayType.Doubles()},
612 };
613 }
614 return arrayTypes;
615 }
616
617 static Object[][] floatArrayTypes;
618
619 public static Object[][] floatArrayTypesProvider() {
620 if (floatArrayTypes == null) {
621 LongFunction<Object> bTof = rb -> Float.intBitsToFloat((int) rb);
622 LongFunction<Object> bToD = Double::longBitsToDouble;
623
624 floatArrayTypes = new Object[][]{
625 new Object[]{new ArrayType.Floats(), 0x7fc00000L, 0x7f800001L, bTof},
626 new Object[]{new ArrayType.Doubles(), 0x7ff8000000000000L, 0x7ff0000000000001L, bToD},
627 };
628 }
629 return floatArrayTypes;
630 }
631
632 static Object[][] objectArrayTypes;
633
634 public static Object[][] objectArrayTypesProvider() {
635 if (objectArrayTypes == null) {
636 LongFunction<Object> bTof = rb -> Float.intBitsToFloat((int) rb);
637 LongFunction<Object> bToD = Double::longBitsToDouble;
638
639 objectArrayTypes = new Object[][]{
640 new Object[]{new ArrayType.BoxedIntegers()},
641 new Object[]{new ArrayType.BoxedIntegersWithReverseComparator()},
642 };
643 }
644 return objectArrayTypes;
645 }
646
647
648 static Object[][] signedUnsignedArrayTypes;
649
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
750 at.set(a, x, v == 0 ? null : v);
751 }
752 return a;
753 },
754 cloner);
755
756 Integer[] a = new Integer[]{null, 0};
757 Integer[] b = new Integer[]{0, 0};
758 Assertions.assertTrue(Arrays.compare(a, b) < 0);
759 Assertions.assertTrue(Arrays.compare(b, a) > 0);
760 }
761
762 @ParameterizedTest
763 @MethodSource("objectArrayTypesProvider")
764 public void testSameRefElementsInObjectArray(ArrayType<?> arrayType) {
765 BiFunction<ArrayType<?>, Object, Object> cloner = ArrayType::copyOf;
766
767 // One ref
768 Integer one = 1;
769 testArrayType(arrayType,
770 (at, s) -> {
771 Integer[] a = (Integer[]) at.construct(s);
772 for (int x = 0; x < s; x++) {
773 a[x] = one;
774 }
775 return a;
776 },
777 cloner);
778
779 // All ref
780 testArrayType(arrayType,
781 (at, s) -> {
782 Integer[] a = (Integer[]) at.construct(s);
783 for (int x = 0; x < s; x++) {
784 a[x] = Integer.valueOf(s);
785 }
786 return a;
787 },
788 cloner);
789
790 // Some same ref
791 testArrayType(arrayType,
792 (at, s) -> {
793 Integer[] a = (Integer[]) at.construct(s);
794 for (int x = 0; x < s; x++) {
795 int v = x % 8;
796 a[x] = v == 1 ? one : new Integer(v);
797 }
798 return a;
799 },
800 cloner);
801 }
802
803 @ParameterizedTest
804 @MethodSource("signedUnsignedArrayTypes")
805 public void testSignedUnsignedArray(ArrayType<?> sat, ArrayType<?> uat) {
806 BiFunction<ArrayType<?>, Integer, Object> constructor = (at, s) -> {
807 Object a = at.construct(s);
808 for (int x = 0; x < s; x++) {
809 at.set(a, x, 1);
810 }
811 return a;
812 };
813
814 int n = arraySizeFor(sat.componentType);
815
816 for (int s : ranges(0, n)) {
817 Object a = constructor.apply(sat, s);
818
819 for (int aFrom : ranges(0, s)) {
820 for (int aTo : ranges(aFrom, s)) {
1105
1106 static void testIAE(Runnable r) {
1107 testThrowable(r, IllegalArgumentException.class);
1108 }
1109
1110 static void testAIOBE(Runnable r) {
1111 testThrowable(r, ArrayIndexOutOfBoundsException.class);
1112 }
1113
1114 static void testThrowable(Runnable r, Class<? extends Throwable> expected) {
1115 Throwable caught = null;
1116 try {
1117 r.run();
1118 }
1119 catch (Throwable t) {
1120 caught = t;
1121 }
1122 Assertions.assertNotNull(caught);
1123 Assertions.assertTrue(expected.isInstance(caught));
1124 }
1125 }
|
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 * @library /test/lib
29 * @run junit ArraysEqCmpTest
30 */
31
32 import java.lang.invoke.MethodHandle;
33 import java.lang.invoke.MethodHandles;
34 import java.lang.invoke.MethodType;
35 import java.lang.reflect.Array;
36 import java.util.Arrays;
37 import java.util.Comparator;
38 import java.util.HashMap;
39 import java.util.List;
40 import java.util.Map;
41 import java.util.Objects;
42 import java.util.function.BiFunction;
43 import java.util.function.LongFunction;
44 import java.util.stream.IntStream;
45
46 import jdk.test.lib.valueclass.AsValueClass;
47
48 import org.junit.jupiter.api.Assertions;
49 import org.junit.jupiter.api.Test;
50 import org.junit.jupiter.api.TestInstance;
51 import org.junit.jupiter.params.ParameterizedTest;
52 import org.junit.jupiter.params.provider.MethodSource;
53
54 @TestInstance(TestInstance.Lifecycle.PER_CLASS)
55 public class ArraysEqCmpTest {
56
57 // Maximum width in bits
58 static final int MAX_WIDTH = 512;
59
60 static final Map<Class, Integer> typeToWidth;
61
62 @AsValueClass
63 record Point(int x, int y) implements Comparable<Point> {
64 @Override
65 public int compareTo(Point o) {
66 int r = Integer.compare(this.x, o.x);
67 return (r != 0) ? r : Integer.compare(this.y, o.y);
68 }
69 }
70
71 @AsValueClass
72 record BoxedPoint(Integer x, Integer y) implements Comparable<BoxedPoint> {
73 @Override
74 public int compareTo(BoxedPoint o) {
75 int r = Integer.compare(this.x, o.x);
76 return (r != 0) ? r : Integer.compare(this.y, o.y);
77 }
78 }
79
80 static {
81 typeToWidth = new HashMap<>();
82 typeToWidth.put(boolean.class, Byte.SIZE);
83 typeToWidth.put(byte.class, Byte.SIZE);
84 typeToWidth.put(short.class, Short.SIZE);
85 typeToWidth.put(char.class, Character.SIZE);
86 typeToWidth.put(int.class, Integer.SIZE);
87 typeToWidth.put(long.class, Long.SIZE);
88 typeToWidth.put(float.class, Float.SIZE);
89 typeToWidth.put(double.class, Double.SIZE);
90 typeToWidth.put(Object.class, Integer.SIZE); // @@@ 32 or 64?
91 }
92
93 static int arraySizeFor(Class<?> type) {
94 type = type.isPrimitive() ? type : Object.class;
95 return 4 * MAX_WIDTH / typeToWidth.get(type);
96 }
97
98 static abstract class ArrayType<T> {
99 final Class<?> arrayType;
591
592 static class Doubles extends ArrayType<double[]> {
593 public Doubles() {
594 super(double[].class);
595 }
596
597 @Override
598 void set(Object a, int i, Object v) {
599 double pv;
600 if (v instanceof Double) {
601 pv = (Double) v;
602 }
603 else if (v instanceof Integer) {
604 pv = ((Integer) v).doubleValue();
605 }
606 else throw new IllegalStateException();
607
608 ((double[]) a)[i] = pv;
609 }
610 }
611
612 static class ValuePoints extends ArrayType<Point[]> {
613 public ValuePoints() {
614 super(Point[].class);
615 }
616
617 @Override
618 void set(Object a, int i, Object v) {
619 if (v == null) {
620 ((Point[]) a)[i] = null;
621 } else if (v instanceof Point) {
622 ((Point[]) a)[i] = (Point) v;
623 } else if (v instanceof Integer) {
624 int val = (Integer) v;
625 ((Point[]) a)[i] = new Point(val, val);
626 } else throw new IllegalStateException();
627 }
628 }
629
630 static class ValueBoxedPoints extends ArrayType<BoxedPoint[]> {
631 public ValueBoxedPoints() {
632 super(BoxedPoint[].class);
633 }
634
635 @Override
636 void set(Object a, int i, Object v) {
637 if (v == null) {
638 ((BoxedPoint[]) a)[i] = null;
639 } else if (v instanceof BoxedPoint) {
640 ((BoxedPoint[]) a)[i] = (BoxedPoint) v;
641 } else if (v instanceof Integer) {
642 int val = (Integer) v;
643 ((BoxedPoint[]) a)[i] = new BoxedPoint(val, val);
644 } else throw new IllegalStateException();
645 }
646 }
647 }
648
649 static Object[][] arrayTypes;
650
651 public static Object[][] arrayTypesProvider() {
652 if (arrayTypes == null) {
653 arrayTypes = new Object[][]{
654 new Object[]{new ArrayType.BoxedIntegers()},
655 new Object[]{new ArrayType.BoxedIntegersWithReverseComparator()},
656 new Object[]{new ArrayType.Booleans()},
657 new Object[]{new ArrayType.Bytes(false)},
658 new Object[]{new ArrayType.Bytes(true)},
659 new Object[]{new ArrayType.Characters()},
660 new Object[]{new ArrayType.Shorts(false)},
661 new Object[]{new ArrayType.Shorts(true)},
662 new Object[]{new ArrayType.Integers(false)},
663 new Object[]{new ArrayType.Integers(true)},
664 new Object[]{new ArrayType.Longs(false)},
665 new Object[]{new ArrayType.Longs(true)},
666 new Object[]{new ArrayType.Floats()},
667 new Object[]{new ArrayType.Doubles()},
668 new Object[]{new ArrayType.ValuePoints()},
669 new Object[]{new ArrayType.ValueBoxedPoints()}
670 };
671 }
672 return arrayTypes;
673 }
674
675 static Object[][] floatArrayTypes;
676
677 public static Object[][] floatArrayTypesProvider() {
678 if (floatArrayTypes == null) {
679 LongFunction<Object> bTof = rb -> Float.intBitsToFloat((int) rb);
680 LongFunction<Object> bToD = Double::longBitsToDouble;
681
682 floatArrayTypes = new Object[][]{
683 new Object[]{new ArrayType.Floats(), 0x7fc00000L, 0x7f800001L, bTof},
684 new Object[]{new ArrayType.Doubles(), 0x7ff8000000000000L, 0x7ff0000000000001L, bToD},
685 };
686 }
687 return floatArrayTypes;
688 }
689
690 static Object[][] objectArrayTypes;
691
692 public static Object[][] objectArrayTypesProvider() {
693 if (objectArrayTypes == null) {
694 LongFunction<Object> bTof = rb -> Float.intBitsToFloat((int) rb);
695 LongFunction<Object> bToD = Double::longBitsToDouble;
696
697 objectArrayTypes = new Object[][]{
698 new Object[]{new ArrayType.BoxedIntegers()},
699 new Object[]{new ArrayType.BoxedIntegersWithReverseComparator()},
700 new Object[]{new ArrayType.ValuePoints()},
701 new Object[]{new ArrayType.ValueBoxedPoints()},
702 };
703 }
704 return objectArrayTypes;
705 }
706
707
708 static Object[][] signedUnsignedArrayTypes;
709
710 public static Object[][] signedUnsignedArrayTypes() {
711 if (signedUnsignedArrayTypes == null) {
712 signedUnsignedArrayTypes = new Object[][]{
713 new Object[]{new ArrayType.Bytes(false), new ArrayType.Bytes(true)},
714 new Object[]{new ArrayType.Shorts(false), new ArrayType.Shorts(true)},
715 new Object[]{new ArrayType.Integers(false), new ArrayType.Integers(true)},
716 new Object[]{new ArrayType.Longs(false), new ArrayType.Longs(true)},
717 };
718 }
719 return signedUnsignedArrayTypes;
720 }
721
810 at.set(a, x, v == 0 ? null : v);
811 }
812 return a;
813 },
814 cloner);
815
816 Integer[] a = new Integer[]{null, 0};
817 Integer[] b = new Integer[]{0, 0};
818 Assertions.assertTrue(Arrays.compare(a, b) < 0);
819 Assertions.assertTrue(Arrays.compare(b, a) > 0);
820 }
821
822 @ParameterizedTest
823 @MethodSource("objectArrayTypesProvider")
824 public void testSameRefElementsInObjectArray(ArrayType<?> arrayType) {
825 BiFunction<ArrayType<?>, Object, Object> cloner = ArrayType::copyOf;
826
827 // One ref
828 Integer one = 1;
829 testArrayType(arrayType,
830 (at, s) -> {
831 Object a = at.construct(s);
832 for (int x = 0; x < s; x++) {
833 at.set(a, x, one);
834 }
835 return a;
836 },
837 cloner);
838
839 // All ref
840 testArrayType(arrayType,
841 (at, s) -> {
842 Object a = at.construct(s);
843 for (int x = 0; x < s; x++) {
844 at.set(a, x, s);
845 }
846 return a;
847 },
848 cloner);
849
850 // Some same ref
851 testArrayType(arrayType,
852 (at, s) -> {
853 Object a = at.construct(s);
854 for (int x = 0; x < s; x++) {
855 int v = x % 8;
856 at.set(a, x, v == 1 ? one : v);
857 }
858 return a;
859 },
860 cloner);
861 }
862
863 @ParameterizedTest
864 @MethodSource("signedUnsignedArrayTypes")
865 public void testSignedUnsignedArray(ArrayType<?> sat, ArrayType<?> uat) {
866 BiFunction<ArrayType<?>, Integer, Object> constructor = (at, s) -> {
867 Object a = at.construct(s);
868 for (int x = 0; x < s; x++) {
869 at.set(a, x, 1);
870 }
871 return a;
872 };
873
874 int n = arraySizeFor(sat.componentType);
875
876 for (int s : ranges(0, n)) {
877 Object a = constructor.apply(sat, s);
878
879 for (int aFrom : ranges(0, s)) {
880 for (int aTo : ranges(aFrom, s)) {
1165
1166 static void testIAE(Runnable r) {
1167 testThrowable(r, IllegalArgumentException.class);
1168 }
1169
1170 static void testAIOBE(Runnable r) {
1171 testThrowable(r, ArrayIndexOutOfBoundsException.class);
1172 }
1173
1174 static void testThrowable(Runnable r, Class<? extends Throwable> expected) {
1175 Throwable caught = null;
1176 try {
1177 r.run();
1178 }
1179 catch (Throwable t) {
1180 caught = t;
1181 }
1182 Assertions.assertNotNull(caught);
1183 Assertions.assertTrue(expected.isInstance(caught));
1184 }
1185 }
|