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 }