blob: 566d8f2513fe99cbefdcd292f6d84598eb7edf06 [file] [log] [blame]
// Copyright (c) 2019, the R8 project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
package com.android.tools.r8.ir.desugar.backports;
import java.util.Arrays;
import java.util.Comparator;
import java.util.Objects;
import java.util.function.Supplier;
public final class ObjectsMethods {
public static <T> int compare(T a, T b, Comparator<? super T> c) {
return a == b ? 0 : c.compare(a, b);
}
public static boolean deepEquals(Object a, Object b) {
if (a == b) return true;
if (a == null) return false;
if (a instanceof boolean[]) {
return b instanceof boolean[] && Arrays.equals((boolean[]) a, (boolean[]) b);
}
if (a instanceof byte[]) {
return b instanceof byte[] && Arrays.equals((byte[]) a, (byte[]) b);
}
if (a instanceof char[]) {
return b instanceof char[] && Arrays.equals((char[]) a, (char[]) b);
}
if (a instanceof double[]) {
return b instanceof double[] && Arrays.equals((double[]) a, (double[]) b);
}
if (a instanceof float[]) {
return b instanceof float[] && Arrays.equals((float[]) a, (float[]) b);
}
if (a instanceof int[]) {
return b instanceof int[] && Arrays.equals((int[]) a, (int[]) b);
}
if (a instanceof long[]) {
return b instanceof long[] && Arrays.equals((long[]) a, (long[]) b);
}
if (a instanceof short[]) {
return b instanceof short[] && Arrays.equals((short[]) a, (short[]) b);
}
if (a instanceof Object[]) {
return b instanceof Object[] && Arrays.deepEquals((Object[]) a, (Object[]) b);
}
return a.equals(b);
}
public static boolean equals(Object a, Object b) {
return a == b || (a != null && a.equals(b));
}
public static int hashCode(Object o) {
return o == null ? 0 : o.hashCode();
}
public static boolean isNull(Object o) {
return o == null;
}
public static boolean nonNull(Object o) {
return o != null;
}
public static <T> T requireNonNullMessage(T obj, String message) {
if (obj == null) {
throw new NullPointerException(message);
}
return obj;
}
public static <T> T requireNonNullSupplier(T obj, Supplier<String> messageSupplier) {
if (obj == null) {
// While calling `messageSupplier.get()` unconditionally would produce the correct behavior,
// some ART versions add an exception message to seemingly-unintended null dereferences along
// the lines of "Attempted to invoke interface method Supplier.get() on a null reference"
// which we don't want to expose as the reference implementation has a null message.
String message = messageSupplier != null ? messageSupplier.get() : null;
throw new NullPointerException(message);
}
return obj;
}
public static <T> T requireNonNullElse(T obj, T defaultObj) {
if (obj != null) return obj;
return Objects.requireNonNull(defaultObj, "defaultObj");
}
public static <T> T requireNonNullElseGet(T obj, Supplier<? extends T> supplier) {
if (obj != null) return obj;
T defaultObj = Objects.requireNonNull(supplier, "supplier").get();
return Objects.requireNonNull(defaultObj, "supplier.get()");
}
public static String toString(Object o) {
return Objects.toString(o, "null");
}
public static String toStringDefault(Object o, String nullDefault) {
return o == null ? nullDefault : o.toString();
}
public static int checkIndex(int index, int length) {
if (index < 0 || index >= length) {
throw new IndexOutOfBoundsException("Index " + index + " out of bounds for length " + length);
}
return index;
}
public static int checkFromToIndex(int fromIndex, int toIndex, int length) {
if (fromIndex < 0 || fromIndex > toIndex || toIndex > length) {
throw new IndexOutOfBoundsException(
"Range [" + fromIndex + ", " + toIndex + ") out of bounds for length " + length);
}
return fromIndex;
}
public static int checkFromIndexSize(int fromIndex, int size, int length) {
if (fromIndex < 0 || size < 0 || length < 0 || fromIndex > length - size) {
throw new IndexOutOfBoundsException(
"Range ["
+ fromIndex
+ ", "
+ fromIndex
+ " + "
+ size
+ ") out of bounds for length "
+ length);
}
return fromIndex;
}
}