1 /* 2 * Copyright (c) 2024, 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 * @run testng TestPrimitiveCast 27 */ 28 29 import org.testng.Assert; 30 import org.testng.annotations.DataProvider; 31 import org.testng.annotations.Test; 32 33 import java.lang.reflect.code.op.CoreOp; 34 import java.lang.reflect.code.interpreter.Interpreter; 35 import java.lang.invoke.MethodHandles; 36 import java.lang.reflect.Method; 37 import java.lang.runtime.CodeReflection; 38 import java.util.Optional; 39 import java.util.function.Function; 40 import java.util.stream.Stream; 41 42 import static java.util.stream.Collectors.joining; 43 44 public class TestPrimitiveCast { 45 46 static final Function<Object, String> FROM_DOUBLE = v -> fromDouble((double) v); 47 48 @CodeReflection 49 @SuppressWarnings("cast") 50 static String fromDouble(double v) { 51 double d = (double) v; 52 float f = (float) v; 53 long l = (long) v; 54 int i = (int) v; 55 short s = (short) v; 56 char c = (char) v; 57 byte b = (byte) v; 58 return collect(d, f, l, i, s, c, b); 59 } 60 61 static final Function<Object, String> FROM_FLOAT = v -> fromFloat((float) v); 62 63 @CodeReflection 64 @SuppressWarnings("cast") 65 static String fromFloat(float v) { 66 double d = (double) v; 67 float f = (float) v; 68 long l = (long) v; 69 int i = (int) v; 70 short s = (short) v; 71 char c = (char) v; 72 byte b = (byte) v; 73 return collect(d, f, l, i, s, c, b); 74 } 75 76 static final Function<Object, String> FROM_LONG = v -> fromLong((long) v); 77 78 @CodeReflection 79 @SuppressWarnings("cast") 80 static String fromLong(long v) { 81 double d = (double) v; 82 float f = (float) v; 83 long l = (long) v; 84 int i = (int) v; 85 short s = (short) v; 86 char c = (char) v; 87 byte b = (byte) v; 88 return collect(d, f, l, i, s, c, b); 89 } 90 91 static final Function<Object, String> FROM_INT = v -> fromInt((int) v); 92 93 @CodeReflection 94 @SuppressWarnings("cast") 95 static String fromInt(int v) { 96 double d = (double) v; 97 float f = (float) v; 98 long l = (long) v; 99 int i = (int) v; 100 short s = (short) v; 101 char c = (char) v; 102 byte b = (byte) v; 103 return collect(d, f, l, i, s, c, b); 104 } 105 106 static final Function<Object, String> FROM_SHORT = v -> fromShort((short) v); 107 108 @CodeReflection 109 @SuppressWarnings("cast") 110 static String fromShort(short v) { 111 double d = (double) v; 112 float f = (float) v; 113 long l = (long) v; 114 int i = (int) v; 115 short s = (short) v; 116 char c = (char) v; 117 byte b = (byte) v; 118 return collect(d, f, l, i, s, c, b); 119 } 120 121 static final Function<Object, String> FROM_CHAR = v -> fromChar((char) v); 122 123 @CodeReflection 124 @SuppressWarnings("cast") 125 static String fromChar(char v) { 126 double d = (double) v; 127 float f = (float) v; 128 long l = (long) v; 129 int i = (int) v; 130 short s = (short) v; 131 char c = (char) v; 132 byte b = (byte) v; 133 return collect(d, f, l, i, s, c, b); 134 } 135 136 static final Function<Object, String> FROM_BYTE = v -> fromByte((byte) v); 137 138 @CodeReflection 139 @SuppressWarnings("cast") 140 static String fromByte(byte v) { 141 double d = (double) v; 142 float f = (float) v; 143 long l = (long) v; 144 int i = (int) v; 145 short s = (short) v; 146 char c = (char) v; 147 byte b = (byte) v; 148 return collect(d, f, l, i, s, c, b); 149 } 150 151 @DataProvider 152 static Object[][] fromMethods() { 153 return new Object[][] { 154 { "fromDouble", Math.PI, FROM_DOUBLE}, 155 { "fromDouble", 65.1, FROM_DOUBLE}, 156 { "fromFloat", (float) Math.PI, FROM_FLOAT}, 157 { "fromFloat", 65.1f, FROM_FLOAT}, 158 { "fromLong", Long.MAX_VALUE, FROM_LONG}, 159 { "fromInt", Integer.MAX_VALUE, FROM_INT}, 160 { "fromShort", Short.MAX_VALUE, FROM_SHORT}, 161 { "fromChar", Character.MAX_VALUE, FROM_CHAR}, 162 { "fromByte", Byte.MAX_VALUE, FROM_BYTE}, 163 }; 164 }; 165 166 @Test(dataProvider = "fromMethods") 167 public void testFromDouble(String name, Object value, Function<Object, String> m) { 168 CoreOp.FuncOp f = getFuncOp(name); 169 Assert.assertEquals(Interpreter.invoke(MethodHandles.lookup(), f, value), m.apply(value)); 170 } 171 172 173 static String collect(Object... values) { 174 return Stream.of(values).map(Object::toString).collect(joining(" ")); 175 } 176 177 static CoreOp.FuncOp getFuncOp(String name) { 178 Optional<Method> om = Stream.of(TestPrimitiveCast.class.getDeclaredMethods()) 179 .filter(m -> m.getName().equals(name)) 180 .findFirst(); 181 182 Method m = om.get(); 183 return m.getCodeModel().get(); 184 } 185 }