package de.take_weiland.mods.commons.internal;
import com.google.common.base.Objects;
import com.google.common.collect.MapMaker;
import java.lang.invoke.MethodHandle;
import java.util.concurrent.ConcurrentMap;
import static com.google.common.base.Preconditions.checkArgument;
import static java.lang.invoke.MethodHandles.lookup;
import static java.lang.invoke.MethodHandles.publicLookup;
import static java.lang.invoke.MethodType.methodType;
/**
* @author diesieben07
*/
public final class MethodHandleHelpers {
private static ConcurrentMap<Class<?>, MethodHandle> cache;
public static synchronized MethodHandle equal(Class<?> type) {
checkArgument(type != void.class);
Class<?> erased = type.isPrimitive() ? type : Object.class;
if (cache == null) {
cache = new MapMaker().concurrencyLevel(2).makeMap();
}
MethodHandle result = cache.get(erased);
if (result == null) {
try {
result = lookup().findStatic(MethodHandleHelpers.class, "eq", methodType(boolean.class, erased, erased));
} catch (NoSuchMethodException | IllegalAccessException e) {
throw new AssertionError(); // these all exist
}
cache.put(erased, result);
}
return result.asType(methodType(boolean.class, type, type));
}
private static MethodHandle objectEquals;
public static synchronized MethodHandle objectEquals(Class<?> clazz) {
checkArgument(!clazz.isPrimitive());
if (objectEquals == null) {
try {
objectEquals = publicLookup().findStatic(Objects.class, "equal", methodType(boolean.class, Object.class, Object.class));
} catch (NoSuchMethodException | IllegalAccessException e) {
throw new RuntimeException("missing method in guava", e);
}
}
return objectEquals.asType(methodType(boolean.class, clazz, clazz));
}
private static boolean eq(Object a, Object b) {
return a == b;
}
private static boolean eq(boolean a, boolean b) {
return a == b;
}
private static boolean eq(byte a, byte b) {
return a == b;
}
private static boolean eq(char a, char b) {
return a == b;
}
private static boolean eq(short a, short b) {
return a == b;
}
private static boolean eq(int a, int b) {
return a == b;
}
private static boolean eq(long a, long b) {
return a == b;
}
private static boolean eq(float a, float b) {
return a == b;
}
private static boolean eq(double a, double b) {
return a == b;
}
}