8155794: Move Objects.checkIndex BiFunction accepting methods to an internal package
Reviewed-by: chegar, shade, forax, vlivanov
--- a/jdk/src/java.base/share/classes/java/lang/invoke/VarHandle.java Wed May 04 17:17:28 2016 +0300
+++ b/jdk/src/java.base/share/classes/java/lang/invoke/VarHandle.java Thu May 05 18:14:47 2016 -0700
@@ -26,6 +26,7 @@
package java.lang.invoke;
import jdk.internal.HotSpotIntrinsicCandidate;
+import jdk.internal.util.Preconditions;
import jdk.internal.vm.annotation.ForceInline;
import java.lang.reflect.Method;
@@ -34,7 +35,6 @@
import java.util.HashMap;
import java.util.List;
import java.util.Map;
-import java.util.Objects;
import java.util.function.BiFunction;
import java.util.function.Function;
@@ -1380,7 +1380,7 @@
}
static final BiFunction<String, List<Integer>, ArrayIndexOutOfBoundsException>
- AIOOBE_SUPPLIER = Objects.outOfBoundsExceptionFormatter(
+ AIOOBE_SUPPLIER = Preconditions.outOfBoundsExceptionFormatter(
new Function<String, ArrayIndexOutOfBoundsException>() {
@Override
public ArrayIndexOutOfBoundsException apply(String s) {
--- a/jdk/src/java.base/share/classes/java/lang/invoke/X-VarHandle.java.template Wed May 04 17:17:28 2016 +0300
+++ b/jdk/src/java.base/share/classes/java/lang/invoke/X-VarHandle.java.template Thu May 05 18:14:47 2016 -0700
@@ -24,8 +24,10 @@
*/
package java.lang.invoke;
+import jdk.internal.util.Preconditions;
+import jdk.internal.vm.annotation.ForceInline;
+
import java.util.Objects;
-import jdk.internal.vm.annotation.ForceInline;
import static java.lang.invoke.MethodHandleStatics.UNSAFE;
@@ -407,7 +409,7 @@
$type$[] array = ($type$[]) oarray;
#end[Object]
return UNSAFE.get$Type$Volatile(array,
- (((long) Objects.checkIndex(index, array.length, AIOOBE_SUPPLIER)) << handle.ashift) + handle.abase);
+ (((long) Preconditions.checkIndex(index, array.length, AIOOBE_SUPPLIER)) << handle.ashift) + handle.abase);
}
@ForceInline
@@ -418,7 +420,7 @@
$type$[] array = ($type$[]) oarray;
#end[Object]
UNSAFE.put$Type$Volatile(array,
- (((long) Objects.checkIndex(index, array.length, AIOOBE_SUPPLIER)) << handle.ashift) + handle.abase,
+ (((long) Preconditions.checkIndex(index, array.length, AIOOBE_SUPPLIER)) << handle.ashift) + handle.abase,
{#if[Object]?handle.componentType.cast(value):value});
}
@@ -430,7 +432,7 @@
$type$[] array = ($type$[]) oarray;
#end[Object]
return UNSAFE.get$Type$Opaque(array,
- (((long) Objects.checkIndex(index, array.length, AIOOBE_SUPPLIER)) << handle.ashift) + handle.abase);
+ (((long) Preconditions.checkIndex(index, array.length, AIOOBE_SUPPLIER)) << handle.ashift) + handle.abase);
}
@ForceInline
@@ -441,7 +443,7 @@
$type$[] array = ($type$[]) oarray;
#end[Object]
UNSAFE.put$Type$Opaque(array,
- (((long) Objects.checkIndex(index, array.length, AIOOBE_SUPPLIER)) << handle.ashift) + handle.abase,
+ (((long) Preconditions.checkIndex(index, array.length, AIOOBE_SUPPLIER)) << handle.ashift) + handle.abase,
{#if[Object]?handle.componentType.cast(value):value});
}
@@ -453,7 +455,7 @@
$type$[] array = ($type$[]) oarray;
#end[Object]
return UNSAFE.get$Type$Acquire(array,
- (((long) Objects.checkIndex(index, array.length, AIOOBE_SUPPLIER)) << handle.ashift) + handle.abase);
+ (((long) Preconditions.checkIndex(index, array.length, AIOOBE_SUPPLIER)) << handle.ashift) + handle.abase);
}
@ForceInline
@@ -464,7 +466,7 @@
$type$[] array = ($type$[]) oarray;
#end[Object]
UNSAFE.put$Type$Release(array,
- (((long) Objects.checkIndex(index, array.length, AIOOBE_SUPPLIER)) << handle.ashift) + handle.abase,
+ (((long) Preconditions.checkIndex(index, array.length, AIOOBE_SUPPLIER)) << handle.ashift) + handle.abase,
{#if[Object]?handle.componentType.cast(value):value});
}
#if[CAS]
@@ -477,7 +479,7 @@
$type$[] array = ($type$[]) oarray;
#end[Object]
return UNSAFE.compareAndSwap$Type$(array,
- (((long) Objects.checkIndex(index, array.length, AIOOBE_SUPPLIER)) << handle.ashift) + handle.abase,
+ (((long) Preconditions.checkIndex(index, array.length, AIOOBE_SUPPLIER)) << handle.ashift) + handle.abase,
{#if[Object]?handle.componentType.cast(expected):expected},
{#if[Object]?handle.componentType.cast(value):value});
}
@@ -490,7 +492,7 @@
$type$[] array = ($type$[]) oarray;
#end[Object]
return UNSAFE.compareAndExchange$Type$Volatile(array,
- (((long) Objects.checkIndex(index, array.length, AIOOBE_SUPPLIER)) << handle.ashift) + handle.abase,
+ (((long) Preconditions.checkIndex(index, array.length, AIOOBE_SUPPLIER)) << handle.ashift) + handle.abase,
{#if[Object]?handle.componentType.cast(expected):expected},
{#if[Object]?handle.componentType.cast(value):value});
}
@@ -503,7 +505,7 @@
$type$[] array = ($type$[]) oarray;
#end[Object]
return UNSAFE.compareAndExchange$Type$Acquire(array,
- (((long) Objects.checkIndex(index, array.length, AIOOBE_SUPPLIER)) << handle.ashift) + handle.abase,
+ (((long) Preconditions.checkIndex(index, array.length, AIOOBE_SUPPLIER)) << handle.ashift) + handle.abase,
{#if[Object]?handle.componentType.cast(expected):expected},
{#if[Object]?handle.componentType.cast(value):value});
}
@@ -516,7 +518,7 @@
$type$[] array = ($type$[]) oarray;
#end[Object]
return UNSAFE.compareAndExchange$Type$Release(array,
- (((long) Objects.checkIndex(index, array.length, AIOOBE_SUPPLIER)) << handle.ashift) + handle.abase,
+ (((long) Preconditions.checkIndex(index, array.length, AIOOBE_SUPPLIER)) << handle.ashift) + handle.abase,
{#if[Object]?handle.componentType.cast(expected):expected},
{#if[Object]?handle.componentType.cast(value):value});
}
@@ -529,7 +531,7 @@
$type$[] array = ($type$[]) oarray;
#end[Object]
return UNSAFE.weakCompareAndSwap$Type$(array,
- (((long) Objects.checkIndex(index, array.length, AIOOBE_SUPPLIER)) << handle.ashift) + handle.abase,
+ (((long) Preconditions.checkIndex(index, array.length, AIOOBE_SUPPLIER)) << handle.ashift) + handle.abase,
{#if[Object]?handle.componentType.cast(expected):expected},
{#if[Object]?handle.componentType.cast(value):value});
}
@@ -542,7 +544,7 @@
$type$[] array = ($type$[]) oarray;
#end[Object]
return UNSAFE.weakCompareAndSwap$Type$Acquire(array,
- (((long) Objects.checkIndex(index, array.length, AIOOBE_SUPPLIER)) << handle.ashift) + handle.abase,
+ (((long) Preconditions.checkIndex(index, array.length, AIOOBE_SUPPLIER)) << handle.ashift) + handle.abase,
{#if[Object]?handle.componentType.cast(expected):expected},
{#if[Object]?handle.componentType.cast(value):value});
}
@@ -555,7 +557,7 @@
$type$[] array = ($type$[]) oarray;
#end[Object]
return UNSAFE.weakCompareAndSwap$Type$Release(array,
- (((long) Objects.checkIndex(index, array.length, AIOOBE_SUPPLIER)) << handle.ashift) + handle.abase,
+ (((long) Preconditions.checkIndex(index, array.length, AIOOBE_SUPPLIER)) << handle.ashift) + handle.abase,
{#if[Object]?handle.componentType.cast(expected):expected},
{#if[Object]?handle.componentType.cast(value):value});
}
@@ -568,7 +570,7 @@
$type$[] array = ($type$[]) oarray;
#end[Object]
return UNSAFE.getAndSet$Type$(array,
- (((long) Objects.checkIndex(index, array.length, AIOOBE_SUPPLIER)) << handle.ashift) + handle.abase,
+ (((long) Preconditions.checkIndex(index, array.length, AIOOBE_SUPPLIER)) << handle.ashift) + handle.abase,
{#if[Object]?handle.componentType.cast(value):value});
}
#end[CAS]
@@ -582,7 +584,7 @@
$type$[] array = ($type$[]) oarray;
#end[Object]
return UNSAFE.getAndAdd$Type$(array,
- (((long) Objects.checkIndex(index, array.length, AIOOBE_SUPPLIER)) << handle.ashift) + handle.abase,
+ (((long) Preconditions.checkIndex(index, array.length, AIOOBE_SUPPLIER)) << handle.ashift) + handle.abase,
value);
}
@@ -594,7 +596,7 @@
$type$[] array = ($type$[]) oarray;
#end[Object]
return UNSAFE.getAndAdd$Type$(array,
- (((long) Objects.checkIndex(index, array.length, AIOOBE_SUPPLIER)) << handle.ashift) + handle.abase,
+ (((long) Preconditions.checkIndex(index, array.length, AIOOBE_SUPPLIER)) << handle.ashift) + handle.abase,
value) + value;
}
#end[AtomicAdd]
--- a/jdk/src/java.base/share/classes/java/lang/invoke/X-VarHandleByteArrayView.java.template Wed May 04 17:17:28 2016 +0300
+++ b/jdk/src/java.base/share/classes/java/lang/invoke/X-VarHandleByteArrayView.java.template Thu May 05 18:14:47 2016 -0700
@@ -25,6 +25,7 @@
package java.lang.invoke;
import jdk.internal.misc.Unsafe;
+import jdk.internal.util.Preconditions;
import jdk.internal.vm.annotation.ForceInline;
import java.nio.ByteBuffer;
@@ -78,7 +79,7 @@
@ForceInline
static int index(byte[] ba, int index) {
- return Objects.checkIndex(index, ba.length - ALIGN, null);
+ return Preconditions.checkIndex(index, ba.length - ALIGN, null);
}
@ForceInline
@@ -287,14 +288,14 @@
@ForceInline
static int index(ByteBuffer bb, int index) {
- return Objects.checkIndex(index, UNSAFE.getInt(bb, BUFFER_LIMIT) - ALIGN, null);
+ return Preconditions.checkIndex(index, UNSAFE.getInt(bb, BUFFER_LIMIT) - ALIGN, null);
}
@ForceInline
static int indexRO(ByteBuffer bb, int index) {
if (UNSAFE.getBoolean(bb, BYTE_BUFFER_IS_READ_ONLY))
throw new ReadOnlyBufferException();
- return Objects.checkIndex(index, UNSAFE.getInt(bb, BUFFER_LIMIT) - ALIGN, null);
+ return Preconditions.checkIndex(index, UNSAFE.getInt(bb, BUFFER_LIMIT) - ALIGN, null);
}
@ForceInline
--- a/jdk/src/java.base/share/classes/java/util/Objects.java Wed May 04 17:17:28 2016 +0300
+++ b/jdk/src/java.base/share/classes/java/util/Objects.java Thu May 05 18:14:47 2016 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2009, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2009, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -25,10 +25,9 @@
package java.util;
-import jdk.internal.HotSpotIntrinsicCandidate;
+import jdk.internal.util.Preconditions;
+import jdk.internal.vm.annotation.ForceInline;
-import java.util.function.BiFunction;
-import java.util.function.Function;
import java.util.function.Supplier;
/**
@@ -349,172 +348,6 @@
}
/**
- * Maps out-of-bounds values to a runtime exception.
- *
- * @param checkKind the kind of bounds check, whose name may correspond
- * to the name of one of the range check methods, checkIndex,
- * checkFromToIndex, checkFromIndexSize
- * @param args the out-of-bounds arguments that failed the range check.
- * If the checkKind corresponds a the name of a range check method
- * then the bounds arguments are those that can be passed in order
- * to the method.
- * @param oobef the exception formatter that when applied with a checkKind
- * and a list out-of-bounds arguments returns a runtime exception.
- * If {@code null} then, it is as if an exception formatter was
- * supplied that returns {@link IndexOutOfBoundsException} for any
- * given arguments.
- * @return the runtime exception
- */
- private static RuntimeException outOfBounds(
- BiFunction<String, List<Integer>, ? extends RuntimeException> oobef,
- String checkKind,
- Integer... args) {
- List<Integer> largs = List.of(args);
- RuntimeException e = oobef == null
- ? null : oobef.apply(checkKind, largs);
- return e == null
- ? new IndexOutOfBoundsException(outOfBoundsMessage(checkKind, largs)) : e;
- }
-
- // Specific out-of-bounds exception producing methods that avoid
- // the varargs-based code in the critical methods there by reducing their
- // the byte code size, and therefore less likely to peturb inlining
-
- private static RuntimeException outOfBoundsCheckIndex(
- BiFunction<String, List<Integer>, ? extends RuntimeException> oobe,
- int index, int length) {
- return outOfBounds(oobe, "checkIndex", index, length);
- }
-
- private static RuntimeException outOfBoundsCheckFromToIndex(
- BiFunction<String, List<Integer>, ? extends RuntimeException> oobe,
- int fromIndex, int toIndex, int length) {
- return outOfBounds(oobe, "checkFromToIndex", fromIndex, toIndex, length);
- }
-
- private static RuntimeException outOfBoundsCheckFromIndexSize(
- BiFunction<String, List<Integer>, ? extends RuntimeException> oobe,
- int fromIndex, int size, int length) {
- return outOfBounds(oobe, "checkFromIndexSize", fromIndex, size, length);
- }
-
- /**
- * Returns an out-of-bounds exception formatter from an given exception
- * factory. The exception formatter is a function that formats an
- * out-of-bounds message from its arguments and applies that message to the
- * given exception factory to produce and relay an exception.
- *
- * <p>The exception formatter accepts two arguments: a {@code String}
- * describing the out-of-bounds range check that failed, referred to as the
- * <em>check kind</em>; and a {@code List<Integer>} containing the
- * out-of-bound integer values that failed the check. The list of
- * out-of-bound values is not modified.
- *
- * <p>Three check kinds are supported {@code checkIndex},
- * {@code checkFromToIndex} and {@code checkFromIndexSize} corresponding
- * respectively to the specified application of an exception formatter as an
- * argument to the out-of-bounds range check methods
- * {@link #checkIndex(int, int, BiFunction) checkIndex},
- * {@link #checkFromToIndex(int, int, int, BiFunction) checkFromToIndex}, and
- * {@link #checkFromIndexSize(int, int, int, BiFunction) checkFromIndexSize}.
- * Thus a supported check kind corresponds to a method name and the
- * out-of-bound integer values correspond to method argument values, in
- * order, preceding the exception formatter argument (similar in many
- * respects to the form of arguments required for a reflective invocation of
- * such a range check method).
- *
- * <p>Formatter arguments conforming to such supported check kinds will
- * produce specific exception messages describing failed out-of-bounds
- * checks. Otherwise, more generic exception messages will be produced in
- * any of the following cases: the check kind is supported but fewer
- * or more out-of-bounds values are supplied, the check kind is not
- * supported, the check kind is {@code null}, or the list of out-of-bound
- * values is {@code null}.
- *
- * @apiNote
- * This method produces an out-of-bounds exception formatter that can be
- * passed as an argument to any of the supported out-of-bounds range check
- * methods declared by {@code Objects}. For example, a formatter producing
- * an {@code ArrayIndexOutOfBoundsException} may be produced and stored on a
- * {@code static final} field as follows:
- * <pre>{@code
- * static final
- * BiFunction<String, List<Integer>, ArrayIndexOutOfBoundsException> AIOOBEF =
- * outOfBoundsExceptionFormatter(ArrayIndexOutOfBoundsException::new);
- * }</pre>
- * The formatter instance {@code AIOOBEF} may be passed as an argument to an
- * out-of-bounds range check method, such as checking if an {@code index}
- * is within the bounds of a {@code limit}:
- * <pre>{@code
- * checkIndex(index, limit, AIOOBEF);
- * }</pre>
- * If the bounds check fails then the range check method will throw an
- * {@code ArrayIndexOutOfBoundsException} with an appropriate exception
- * message that is a produced from {@code AIOOBEF} as follows:
- * <pre>{@code
- * AIOOBEF.apply("checkIndex", List.of(index, limit));
- * }</pre>
- *
- * @param f the exception factory, that produces an exception from a message
- * where the message is produced and formatted by the returned
- * exception formatter. If this factory is stateless and side-effect
- * free then so is the returned formatter.
- * Exceptions thrown by the factory are relayed to the caller
- * of the returned formatter.
- * @param <X> the type of runtime exception to be returned by the given
- * exception factory and relayed by the exception formatter
- * @return the out-of-bounds exception formatter
- */
- public static <X extends RuntimeException>
- BiFunction<String, List<Integer>, X> outOfBoundsExceptionFormatter(Function<String, X> f) {
- // Use anonymous class to avoid bootstrap issues if this method is
- // used early in startup
- return new BiFunction<String, List<Integer>, X>() {
- @Override
- public X apply(String checkKind, List<Integer> args) {
- return f.apply(outOfBoundsMessage(checkKind, args));
- }
- };
- }
-
- private static String outOfBoundsMessage(String checkKind, List<Integer> args) {
- if (checkKind == null && args == null) {
- return String.format("Range check failed");
- } else if (checkKind == null) {
- return String.format("Range check failed: %s", args);
- } else if (args == null) {
- return String.format("Range check failed: %s", checkKind);
- }
-
- int argSize = 0;
- switch (checkKind) {
- case "checkIndex":
- argSize = 2;
- break;
- case "checkFromToIndex":
- case "checkFromIndexSize":
- argSize = 3;
- break;
- default:
- }
-
- // Switch to default if fewer or more arguments than required are supplied
- switch ((args.size() != argSize) ? "" : checkKind) {
- case "checkIndex":
- return String.format("Index %d out-of-bounds for length %d",
- args.get(0), args.get(1));
- case "checkFromToIndex":
- return String.format("Range [%d, %d) out-of-bounds for length %d",
- args.get(0), args.get(1), args.get(2));
- case "checkFromIndexSize":
- return String.format("Range [%d, %<d + %d) out-of-bounds for length %d",
- args.get(0), args.get(1), args.get(2));
- default:
- return String.format("Range check failed: %s %s", checkKind, args);
- }
- }
-
- /**
* Checks if the {@code index} is within the bounds of the range from
* {@code 0} (inclusive) to {@code length} (exclusive).
*
@@ -526,72 +359,16 @@
* <li>{@code length < 0}, which is implied from the former inequalities</li>
* </ul>
*
- * <p>This method behaves as if {@link #checkIndex(int, int, BiFunction)}
- * was called with same out-of-bounds arguments and an exception formatter
- * argument produced from an invocation of
- * {@code outOfBoundsExceptionFormatter(IndexOutOfBounds::new)} (though it may
- * be more efficient).
- *
* @param index the index
* @param length the upper-bound (exclusive) of the range
* @return {@code index} if it is within bounds of the range
* @throws IndexOutOfBoundsException if the {@code index} is out-of-bounds
* @since 9
*/
+ @ForceInline
public static
int checkIndex(int index, int length) {
- return checkIndex(index, length, null);
- }
-
- /**
- * Checks if the {@code index} is within the bounds of the range from
- * {@code 0} (inclusive) to {@code length} (exclusive).
- *
- * <p>The {@code index} is defined to be out-of-bounds if any of the
- * following inequalities is true:
- * <ul>
- * <li>{@code index < 0}</li>
- * <li>{@code index >= length}</li>
- * <li>{@code length < 0}, which is implied from the former inequalities</li>
- * </ul>
- *
- * <p>If the {@code index} is out-of-bounds, then a runtime exception is
- * thrown that is the result of applying the following arguments to the
- * exception formatter: the name of this method, {@code checkIndex};
- * and an unmodifiable list integers whose values are, in order, the
- * out-of-bounds arguments {@code index} and {@code length}.
- *
- * @param <X> the type of runtime exception to throw if the arguments are
- * out-of-bounds
- * @param index the index
- * @param length the upper-bound (exclusive) of the range
- * @param oobef the exception formatter that when applied with this
- * method name and out-of-bounds arguments returns a runtime
- * exception. If {@code null} or returns {@code null} then, it is as
- * if an exception formatter produced from an invocation of
- * {@code outOfBoundsExceptionFormatter(IndexOutOfBounds::new)} is used
- * instead (though it may be more efficient).
- * Exceptions thrown by the formatter are relayed to the caller.
- * @return {@code index} if it is within bounds of the range
- * @throws X if the {@code index} is out-of-bounds and the exception
- * formatter is non-{@code null}
- * @throws IndexOutOfBoundsException if the {@code index} is out-of-bounds
- * and the exception formatter is {@code null}
- * @since 9
- *
- * @implNote
- * This method is made intrinsic in optimizing compilers to guide them to
- * perform unsigned comparisons of the index and length when it is known the
- * length is a non-negative value (such as that of an array length or from
- * the upper bound of a loop)
- */
- @HotSpotIntrinsicCandidate
- public static <X extends RuntimeException>
- int checkIndex(int index, int length,
- BiFunction<String, List<Integer>, X> oobef) {
- if (index < 0 || index >= length)
- throw outOfBoundsCheckIndex(oobef, index, length);
- return index;
+ return Preconditions.checkIndex(index, length, null);
}
/**
@@ -608,12 +385,6 @@
* <li>{@code length < 0}, which is implied from the former inequalities</li>
* </ul>
*
- * <p>This method behaves as if {@link #checkFromToIndex(int, int, int, BiFunction)}
- * was called with same out-of-bounds arguments and an exception formatter
- * argument produced from an invocation of
- * {@code outOfBoundsExceptionFormatter(IndexOutOfBounds::new)} (though it may
- * be more efficient).
- *
* @param fromIndex the lower-bound (inclusive) of the sub-range
* @param toIndex the upper-bound (exclusive) of the sub-range
* @param length the upper-bound (exclusive) the range
@@ -623,54 +394,7 @@
*/
public static
int checkFromToIndex(int fromIndex, int toIndex, int length) {
- return checkFromToIndex(fromIndex, toIndex, length, null);
- }
-
- /**
- * Checks if the sub-range from {@code fromIndex} (inclusive) to
- * {@code toIndex} (exclusive) is within the bounds of range from {@code 0}
- * (inclusive) to {@code length} (exclusive).
- *
- * <p>The sub-range is defined to be out-of-bounds if any of the following
- * inequalities is true:
- * <ul>
- * <li>{@code fromIndex < 0}</li>
- * <li>{@code fromIndex > toIndex}</li>
- * <li>{@code toIndex > length}</li>
- * <li>{@code length < 0}, which is implied from the former inequalities</li>
- * </ul>
- *
- * <p>If the sub-range is out-of-bounds, then a runtime exception is
- * thrown that is the result of applying the following arguments to the
- * exception formatter: the name of this method, {@code checkFromToIndex};
- * and an unmodifiable list integers whose values are, in order, the
- * out-of-bounds arguments {@code fromIndex}, {@code toIndex}, and {@code length}.
- *
- * @param <X> the type of runtime exception to throw if the arguments are
- * out-of-bounds
- * @param fromIndex the lower-bound (inclusive) of the sub-range
- * @param toIndex the upper-bound (exclusive) of the sub-range
- * @param length the upper-bound (exclusive) the range
- * @param oobef the exception formatter that when applied with this
- * method name and out-of-bounds arguments returns a runtime
- * exception. If {@code null} or returns {@code null} then, it is as
- * if an exception formatter produced from an invocation of
- * {@code outOfBoundsExceptionFormatter(IndexOutOfBounds::new)} is used
- * instead (though it may be more efficient).
- * Exceptions thrown by the formatter are relayed to the caller.
- * @return {@code fromIndex} if the sub-range within bounds of the range
- * @throws X if the sub-range is out-of-bounds and the exception factory
- * function is non-{@code null}
- * @throws IndexOutOfBoundsException if the sub-range is out-of-bounds and
- * the exception factory function is {@code null}
- * @since 9
- */
- public static <X extends RuntimeException>
- int checkFromToIndex(int fromIndex, int toIndex, int length,
- BiFunction<String, List<Integer>, X> oobef) {
- if (fromIndex < 0 || fromIndex > toIndex || toIndex > length)
- throw outOfBoundsCheckFromToIndex(oobef, fromIndex, toIndex, length);
- return fromIndex;
+ return Preconditions.checkFromToIndex(fromIndex, toIndex, length, null);
}
/**
@@ -687,12 +411,6 @@
* <li>{@code length < 0}, which is implied from the former inequalities</li>
* </ul>
*
- * <p>This method behaves as if {@link #checkFromIndexSize(int, int, int, BiFunction)}
- * was called with same out-of-bounds arguments and an exception formatter
- * argument produced from an invocation of
- * {@code outOfBoundsExceptionFormatter(IndexOutOfBounds::new)} (though it may
- * be more efficient).
- *
* @param fromIndex the lower-bound (inclusive) of the sub-interval
* @param size the size of the sub-range
* @param length the upper-bound (exclusive) of the range
@@ -702,54 +420,7 @@
*/
public static
int checkFromIndexSize(int fromIndex, int size, int length) {
- return checkFromIndexSize(fromIndex, size, length, null);
+ return Preconditions.checkFromIndexSize(fromIndex, size, length, null);
}
- /**
- * Checks if the sub-range from {@code fromIndex} (inclusive) to
- * {@code fromIndex + size} (exclusive) is within the bounds of range from
- * {@code 0} (inclusive) to {@code length} (exclusive).
- *
- * <p>The sub-range is defined to be out-of-bounds if any of the following
- * inequalities is true:
- * <ul>
- * <li>{@code fromIndex < 0}</li>
- * <li>{@code size < 0}</li>
- * <li>{@code fromIndex + size > length}, taking into account integer overflow</li>
- * <li>{@code length < 0}, which is implied from the former inequalities</li>
- * </ul>
- *
- * <p>If the sub-range is out-of-bounds, then a runtime exception is
- * thrown that is the result of applying the following arguments to the
- * exception formatter: the name of this method, {@code checkFromIndexSize};
- * and an unmodifiable list integers whose values are, in order, the
- * out-of-bounds arguments {@code fromIndex}, {@code size}, and
- * {@code length}.
- *
- * @param <X> the type of runtime exception to throw if the arguments are
- * out-of-bounds
- * @param fromIndex the lower-bound (inclusive) of the sub-interval
- * @param size the size of the sub-range
- * @param length the upper-bound (exclusive) of the range
- * @param oobef the exception formatter that when applied with this
- * method name and out-of-bounds arguments returns a runtime
- * exception. If {@code null} or returns {@code null} then, it is as
- * if an exception formatter produced from an invocation of
- * {@code outOfBoundsExceptionFormatter(IndexOutOfBounds::new)} is used
- * instead (though it may be more efficient).
- * Exceptions thrown by the formatter are relayed to the caller.
- * @return {@code fromIndex} if the sub-range within bounds of the range
- * @throws X if the sub-range is out-of-bounds and the exception factory
- * function is non-{@code null}
- * @throws IndexOutOfBoundsException if the sub-range is out-of-bounds and
- * the exception factory function is {@code null}
- * @since 9
- */
- public static <X extends RuntimeException>
- int checkFromIndexSize(int fromIndex, int size, int length,
- BiFunction<String, List<Integer>, X> oobef) {
- if ((length | fromIndex | size) < 0 || size > length - fromIndex)
- throw outOfBoundsCheckFromIndexSize(oobef, fromIndex, size, length);
- return fromIndex;
- }
}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/java.base/share/classes/jdk/internal/util/Preconditions.java Thu May 05 18:14:47 2016 -0700
@@ -0,0 +1,346 @@
+/*
+ * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package jdk.internal.util;
+
+import jdk.internal.HotSpotIntrinsicCandidate;
+
+import java.util.List;
+import java.util.function.BiFunction;
+import java.util.function.Function;
+
+/**
+ * Utility methods to check if state or arguments are correct.
+ *
+ */
+public class Preconditions {
+
+ /**
+ * Maps out-of-bounds values to a runtime exception.
+ *
+ * @param checkKind the kind of bounds check, whose name may correspond
+ * to the name of one of the range check methods, checkIndex,
+ * checkFromToIndex, checkFromIndexSize
+ * @param args the out-of-bounds arguments that failed the range check.
+ * If the checkKind corresponds a the name of a range check method
+ * then the bounds arguments are those that can be passed in order
+ * to the method.
+ * @param oobef the exception formatter that when applied with a checkKind
+ * and a list out-of-bounds arguments returns a runtime exception.
+ * If {@code null} then, it is as if an exception formatter was
+ * supplied that returns {@link IndexOutOfBoundsException} for any
+ * given arguments.
+ * @return the runtime exception
+ */
+ private static RuntimeException outOfBounds(
+ BiFunction<String, List<Integer>, ? extends RuntimeException> oobef,
+ String checkKind,
+ Integer... args) {
+ List<Integer> largs = List.of(args);
+ RuntimeException e = oobef == null
+ ? null : oobef.apply(checkKind, largs);
+ return e == null
+ ? new IndexOutOfBoundsException(outOfBoundsMessage(checkKind, largs)) : e;
+ }
+
+ private static RuntimeException outOfBoundsCheckIndex(
+ BiFunction<String, List<Integer>, ? extends RuntimeException> oobe,
+ int index, int length) {
+ return outOfBounds(oobe, "checkIndex", index, length);
+ }
+
+ private static RuntimeException outOfBoundsCheckFromToIndex(
+ BiFunction<String, List<Integer>, ? extends RuntimeException> oobe,
+ int fromIndex, int toIndex, int length) {
+ return outOfBounds(oobe, "checkFromToIndex", fromIndex, toIndex, length);
+ }
+
+ private static RuntimeException outOfBoundsCheckFromIndexSize(
+ BiFunction<String, List<Integer>, ? extends RuntimeException> oobe,
+ int fromIndex, int size, int length) {
+ return outOfBounds(oobe, "checkFromIndexSize", fromIndex, size, length);
+ }
+
+ /**
+ * Returns an out-of-bounds exception formatter from an given exception
+ * factory. The exception formatter is a function that formats an
+ * out-of-bounds message from its arguments and applies that message to the
+ * given exception factory to produce and relay an exception.
+ *
+ * <p>The exception formatter accepts two arguments: a {@code String}
+ * describing the out-of-bounds range check that failed, referred to as the
+ * <em>check kind</em>; and a {@code List<Integer>} containing the
+ * out-of-bound integer values that failed the check. The list of
+ * out-of-bound values is not modified.
+ *
+ * <p>Three check kinds are supported {@code checkIndex},
+ * {@code checkFromToIndex} and {@code checkFromIndexSize} corresponding
+ * respectively to the specified application of an exception formatter as an
+ * argument to the out-of-bounds range check methods
+ * {@link #checkIndex(int, int, BiFunction) checkIndex},
+ * {@link #checkFromToIndex(int, int, int, BiFunction) checkFromToIndex}, and
+ * {@link #checkFromIndexSize(int, int, int, BiFunction) checkFromIndexSize}.
+ * Thus a supported check kind corresponds to a method name and the
+ * out-of-bound integer values correspond to method argument values, in
+ * order, preceding the exception formatter argument (similar in many
+ * respects to the form of arguments required for a reflective invocation of
+ * such a range check method).
+ *
+ * <p>Formatter arguments conforming to such supported check kinds will
+ * produce specific exception messages describing failed out-of-bounds
+ * checks. Otherwise, more generic exception messages will be produced in
+ * any of the following cases: the check kind is supported but fewer
+ * or more out-of-bounds values are supplied, the check kind is not
+ * supported, the check kind is {@code null}, or the list of out-of-bound
+ * values is {@code null}.
+ *
+ * @apiNote
+ * This method produces an out-of-bounds exception formatter that can be
+ * passed as an argument to any of the supported out-of-bounds range check
+ * methods declared by {@code Objects}. For example, a formatter producing
+ * an {@code ArrayIndexOutOfBoundsException} may be produced and stored on a
+ * {@code static final} field as follows:
+ * <pre>{@code
+ * static final
+ * BiFunction<String, List<Integer>, ArrayIndexOutOfBoundsException> AIOOBEF =
+ * outOfBoundsExceptionFormatter(ArrayIndexOutOfBoundsException::new);
+ * }</pre>
+ * The formatter instance {@code AIOOBEF} may be passed as an argument to an
+ * out-of-bounds range check method, such as checking if an {@code index}
+ * is within the bounds of a {@code limit}:
+ * <pre>{@code
+ * checkIndex(index, limit, AIOOBEF);
+ * }</pre>
+ * If the bounds check fails then the range check method will throw an
+ * {@code ArrayIndexOutOfBoundsException} with an appropriate exception
+ * message that is a produced from {@code AIOOBEF} as follows:
+ * <pre>{@code
+ * AIOOBEF.apply("checkIndex", List.of(index, limit));
+ * }</pre>
+ *
+ * @param f the exception factory, that produces an exception from a message
+ * where the message is produced and formatted by the returned
+ * exception formatter. If this factory is stateless and side-effect
+ * free then so is the returned formatter.
+ * Exceptions thrown by the factory are relayed to the caller
+ * of the returned formatter.
+ * @param <X> the type of runtime exception to be returned by the given
+ * exception factory and relayed by the exception formatter
+ * @return the out-of-bounds exception formatter
+ */
+ public static <X extends RuntimeException>
+ BiFunction<String, List<Integer>, X> outOfBoundsExceptionFormatter(Function<String, X> f) {
+ // Use anonymous class to avoid bootstrap issues if this method is
+ // used early in startup
+ return new BiFunction<String, List<Integer>, X>() {
+ @Override
+ public X apply(String checkKind, List<Integer> args) {
+ return f.apply(outOfBoundsMessage(checkKind, args));
+ }
+ };
+ }
+
+ private static String outOfBoundsMessage(String checkKind, List<Integer> args) {
+ if (checkKind == null && args == null) {
+ return String.format("Range check failed");
+ } else if (checkKind == null) {
+ return String.format("Range check failed: %s", args);
+ } else if (args == null) {
+ return String.format("Range check failed: %s", checkKind);
+ }
+
+ int argSize = 0;
+ switch (checkKind) {
+ case "checkIndex":
+ argSize = 2;
+ break;
+ case "checkFromToIndex":
+ case "checkFromIndexSize":
+ argSize = 3;
+ break;
+ default:
+ }
+
+ // Switch to default if fewer or more arguments than required are supplied
+ switch ((args.size() != argSize) ? "" : checkKind) {
+ case "checkIndex":
+ return String.format("Index %d out-of-bounds for length %d",
+ args.get(0), args.get(1));
+ case "checkFromToIndex":
+ return String.format("Range [%d, %d) out-of-bounds for length %d",
+ args.get(0), args.get(1), args.get(2));
+ case "checkFromIndexSize":
+ return String.format("Range [%d, %<d + %d) out-of-bounds for length %d",
+ args.get(0), args.get(1), args.get(2));
+ default:
+ return String.format("Range check failed: %s %s", checkKind, args);
+ }
+ }
+
+ /**
+ * Checks if the {@code index} is within the bounds of the range from
+ * {@code 0} (inclusive) to {@code length} (exclusive).
+ *
+ * <p>The {@code index} is defined to be out-of-bounds if any of the
+ * following inequalities is true:
+ * <ul>
+ * <li>{@code index < 0}</li>
+ * <li>{@code index >= length}</li>
+ * <li>{@code length < 0}, which is implied from the former inequalities</li>
+ * </ul>
+ *
+ * <p>If the {@code index} is out-of-bounds, then a runtime exception is
+ * thrown that is the result of applying the following arguments to the
+ * exception formatter: the name of this method, {@code checkIndex};
+ * and an unmodifiable list integers whose values are, in order, the
+ * out-of-bounds arguments {@code index} and {@code length}.
+ *
+ * @param <X> the type of runtime exception to throw if the arguments are
+ * out-of-bounds
+ * @param index the index
+ * @param length the upper-bound (exclusive) of the range
+ * @param oobef the exception formatter that when applied with this
+ * method name and out-of-bounds arguments returns a runtime
+ * exception. If {@code null} or returns {@code null} then, it is as
+ * if an exception formatter produced from an invocation of
+ * {@code outOfBoundsExceptionFormatter(IndexOutOfBounds::new)} is used
+ * instead (though it may be more efficient).
+ * Exceptions thrown by the formatter are relayed to the caller.
+ * @return {@code index} if it is within bounds of the range
+ * @throws X if the {@code index} is out-of-bounds and the exception
+ * formatter is non-{@code null}
+ * @throws IndexOutOfBoundsException if the {@code index} is out-of-bounds
+ * and the exception formatter is {@code null}
+ * @since 9
+ *
+ * @implNote
+ * This method is made intrinsic in optimizing compilers to guide them to
+ * perform unsigned comparisons of the index and length when it is known the
+ * length is a non-negative value (such as that of an array length or from
+ * the upper bound of a loop)
+ */
+ @HotSpotIntrinsicCandidate
+ public static <X extends RuntimeException>
+ int checkIndex(int index, int length,
+ BiFunction<String, List<Integer>, X> oobef) {
+ if (index < 0 || index >= length)
+ throw outOfBoundsCheckIndex(oobef, index, length);
+ return index;
+ }
+
+ /**
+ * Checks if the sub-range from {@code fromIndex} (inclusive) to
+ * {@code toIndex} (exclusive) is within the bounds of range from {@code 0}
+ * (inclusive) to {@code length} (exclusive).
+ *
+ * <p>The sub-range is defined to be out-of-bounds if any of the following
+ * inequalities is true:
+ * <ul>
+ * <li>{@code fromIndex < 0}</li>
+ * <li>{@code fromIndex > toIndex}</li>
+ * <li>{@code toIndex > length}</li>
+ * <li>{@code length < 0}, which is implied from the former inequalities</li>
+ * </ul>
+ *
+ * <p>If the sub-range is out-of-bounds, then a runtime exception is
+ * thrown that is the result of applying the following arguments to the
+ * exception formatter: the name of this method, {@code checkFromToIndex};
+ * and an unmodifiable list integers whose values are, in order, the
+ * out-of-bounds arguments {@code fromIndex}, {@code toIndex}, and {@code length}.
+ *
+ * @param <X> the type of runtime exception to throw if the arguments are
+ * out-of-bounds
+ * @param fromIndex the lower-bound (inclusive) of the sub-range
+ * @param toIndex the upper-bound (exclusive) of the sub-range
+ * @param length the upper-bound (exclusive) the range
+ * @param oobef the exception formatter that when applied with this
+ * method name and out-of-bounds arguments returns a runtime
+ * exception. If {@code null} or returns {@code null} then, it is as
+ * if an exception formatter produced from an invocation of
+ * {@code outOfBoundsExceptionFormatter(IndexOutOfBounds::new)} is used
+ * instead (though it may be more efficient).
+ * Exceptions thrown by the formatter are relayed to the caller.
+ * @return {@code fromIndex} if the sub-range within bounds of the range
+ * @throws X if the sub-range is out-of-bounds and the exception factory
+ * function is non-{@code null}
+ * @throws IndexOutOfBoundsException if the sub-range is out-of-bounds and
+ * the exception factory function is {@code null}
+ * @since 9
+ */
+ public static <X extends RuntimeException>
+ int checkFromToIndex(int fromIndex, int toIndex, int length,
+ BiFunction<String, List<Integer>, X> oobef) {
+ if (fromIndex < 0 || fromIndex > toIndex || toIndex > length)
+ throw outOfBoundsCheckFromToIndex(oobef, fromIndex, toIndex, length);
+ return fromIndex;
+ }
+
+ /**
+ * Checks if the sub-range from {@code fromIndex} (inclusive) to
+ * {@code fromIndex + size} (exclusive) is within the bounds of range from
+ * {@code 0} (inclusive) to {@code length} (exclusive).
+ *
+ * <p>The sub-range is defined to be out-of-bounds if any of the following
+ * inequalities is true:
+ * <ul>
+ * <li>{@code fromIndex < 0}</li>
+ * <li>{@code size < 0}</li>
+ * <li>{@code fromIndex + size > length}, taking into account integer overflow</li>
+ * <li>{@code length < 0}, which is implied from the former inequalities</li>
+ * </ul>
+ *
+ * <p>If the sub-range is out-of-bounds, then a runtime exception is
+ * thrown that is the result of applying the following arguments to the
+ * exception formatter: the name of this method, {@code checkFromIndexSize};
+ * and an unmodifiable list integers whose values are, in order, the
+ * out-of-bounds arguments {@code fromIndex}, {@code size}, and
+ * {@code length}.
+ *
+ * @param <X> the type of runtime exception to throw if the arguments are
+ * out-of-bounds
+ * @param fromIndex the lower-bound (inclusive) of the sub-interval
+ * @param size the size of the sub-range
+ * @param length the upper-bound (exclusive) of the range
+ * @param oobef the exception formatter that when applied with this
+ * method name and out-of-bounds arguments returns a runtime
+ * exception. If {@code null} or returns {@code null} then, it is as
+ * if an exception formatter produced from an invocation of
+ * {@code outOfBoundsExceptionFormatter(IndexOutOfBounds::new)} is used
+ * instead (though it may be more efficient).
+ * Exceptions thrown by the formatter are relayed to the caller.
+ * @return {@code fromIndex} if the sub-range within bounds of the range
+ * @throws X if the sub-range is out-of-bounds and the exception factory
+ * function is non-{@code null}
+ * @throws IndexOutOfBoundsException if the sub-range is out-of-bounds and
+ * the exception factory function is {@code null}
+ * @since 9
+ */
+ public static <X extends RuntimeException>
+ int checkFromIndexSize(int fromIndex, int size, int length,
+ BiFunction<String, List<Integer>, X> oobef) {
+ if ((length | fromIndex | size) < 0 || size > length - fromIndex)
+ throw outOfBoundsCheckFromIndexSize(oobef, fromIndex, size, length);
+ return fromIndex;
+ }
+}
--- a/jdk/test/java/util/Objects/CheckIndex.java Wed May 04 17:17:28 2016 +0300
+++ b/jdk/test/java/util/Objects/CheckIndex.java Thu May 05 18:14:47 2016 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 2016 Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -23,11 +23,13 @@
/**
* @test
- * @summary IndexOutOfBoundsException check index tests
+ * @summary Objects.checkIndex/jdk.internal.util.Preconditions.checkIndex tests
* @run testng CheckIndex
- * @bug 8135248 8142493
+ * @bug 8135248 8142493 8155794
+ * @modules java.base/jdk.internal.util
*/
+import jdk.internal.util.Preconditions;
import org.testng.annotations.DataProvider;
import org.testng.annotations.Test;
@@ -95,7 +97,7 @@
public void testCheckIndex(int index, int length, boolean withinBounds) {
String expectedMessage = withinBounds
? null
- : Objects.outOfBoundsExceptionFormatter(IndexOutOfBoundsException::new).
+ : Preconditions.outOfBoundsExceptionFormatter(IndexOutOfBoundsException::new).
apply("checkIndex", List.of(index, length)).getMessage();
BiConsumer<Class<? extends RuntimeException>, IntSupplier> checker = (ec, s) -> {
@@ -117,21 +119,21 @@
};
checker.accept(AssertingOutOfBoundsException.class,
- () -> Objects.checkIndex(index, length,
- assertingOutOfBounds(expectedMessage, "checkIndex", index, length)));
+ () -> Preconditions.checkIndex(index, length,
+ assertingOutOfBounds(expectedMessage, "checkIndex", index, length)));
checker.accept(IndexOutOfBoundsException.class,
- () -> Objects.checkIndex(index, length,
- assertingOutOfBoundsReturnNull("checkIndex", index, length)));
+ () -> Preconditions.checkIndex(index, length,
+ assertingOutOfBoundsReturnNull("checkIndex", index, length)));
checker.accept(IndexOutOfBoundsException.class,
- () -> Objects.checkIndex(index, length, null));
+ () -> Preconditions.checkIndex(index, length, null));
checker.accept(IndexOutOfBoundsException.class,
() -> Objects.checkIndex(index, length));
checker.accept(ArrayIndexOutOfBoundsException.class,
- () -> Objects.checkIndex(index, length,
- Objects.outOfBoundsExceptionFormatter(ArrayIndexOutOfBoundsException::new)));
+ () -> Preconditions.checkIndex(index, length,
+ Preconditions.outOfBoundsExceptionFormatter(ArrayIndexOutOfBoundsException::new)));
checker.accept(StringIndexOutOfBoundsException.class,
- () -> Objects.checkIndex(index, length,
- Objects.outOfBoundsExceptionFormatter(StringIndexOutOfBoundsException::new)));
+ () -> Preconditions.checkIndex(index, length,
+ Preconditions.outOfBoundsExceptionFormatter(StringIndexOutOfBoundsException::new)));
}
@@ -157,7 +159,7 @@
public void testCheckFromToIndex(int fromIndex, int toIndex, int length, boolean withinBounds) {
String expectedMessage = withinBounds
? null
- : Objects.outOfBoundsExceptionFormatter(IndexOutOfBoundsException::new).
+ : Preconditions.outOfBoundsExceptionFormatter(IndexOutOfBoundsException::new).
apply("checkFromToIndex", List.of(fromIndex, toIndex, length)).getMessage();
BiConsumer<Class<? extends RuntimeException>, IntSupplier> check = (ec, s) -> {
@@ -179,21 +181,21 @@
};
check.accept(AssertingOutOfBoundsException.class,
- () -> Objects.checkFromToIndex(fromIndex, toIndex, length,
- assertingOutOfBounds(expectedMessage, "checkFromToIndex", fromIndex, toIndex, length)));
+ () -> Preconditions.checkFromToIndex(fromIndex, toIndex, length,
+ assertingOutOfBounds(expectedMessage, "checkFromToIndex", fromIndex, toIndex, length)));
check.accept(IndexOutOfBoundsException.class,
- () -> Objects.checkFromToIndex(fromIndex, toIndex, length,
- assertingOutOfBoundsReturnNull("checkFromToIndex", fromIndex, toIndex, length)));
+ () -> Preconditions.checkFromToIndex(fromIndex, toIndex, length,
+ assertingOutOfBoundsReturnNull("checkFromToIndex", fromIndex, toIndex, length)));
check.accept(IndexOutOfBoundsException.class,
- () -> Objects.checkFromToIndex(fromIndex, toIndex, length, null));
+ () -> Preconditions.checkFromToIndex(fromIndex, toIndex, length, null));
check.accept(IndexOutOfBoundsException.class,
() -> Objects.checkFromToIndex(fromIndex, toIndex, length));
check.accept(ArrayIndexOutOfBoundsException.class,
- () -> Objects.checkFromToIndex(fromIndex, toIndex, length,
- Objects.outOfBoundsExceptionFormatter(ArrayIndexOutOfBoundsException::new)));
+ () -> Preconditions.checkFromToIndex(fromIndex, toIndex, length,
+ Preconditions.outOfBoundsExceptionFormatter(ArrayIndexOutOfBoundsException::new)));
check.accept(StringIndexOutOfBoundsException.class,
- () -> Objects.checkFromToIndex(fromIndex, toIndex, length,
- Objects.outOfBoundsExceptionFormatter(StringIndexOutOfBoundsException::new)));
+ () -> Preconditions.checkFromToIndex(fromIndex, toIndex, length,
+ Preconditions.outOfBoundsExceptionFormatter(StringIndexOutOfBoundsException::new)));
}
@@ -226,7 +228,7 @@
public void testCheckFromIndexSize(int fromIndex, int size, int length, boolean withinBounds) {
String expectedMessage = withinBounds
? null
- : Objects.outOfBoundsExceptionFormatter(IndexOutOfBoundsException::new).
+ : Preconditions.outOfBoundsExceptionFormatter(IndexOutOfBoundsException::new).
apply("checkFromIndexSize", List.of(fromIndex, size, length)).getMessage();
BiConsumer<Class<? extends RuntimeException>, IntSupplier> check = (ec, s) -> {
@@ -248,27 +250,27 @@
};
check.accept(AssertingOutOfBoundsException.class,
- () -> Objects.checkFromIndexSize(fromIndex, size, length,
- assertingOutOfBounds(expectedMessage, "checkFromIndexSize", fromIndex, size, length)));
+ () -> Preconditions.checkFromIndexSize(fromIndex, size, length,
+ assertingOutOfBounds(expectedMessage, "checkFromIndexSize", fromIndex, size, length)));
check.accept(IndexOutOfBoundsException.class,
- () -> Objects.checkFromIndexSize(fromIndex, size, length,
- assertingOutOfBoundsReturnNull("checkFromIndexSize", fromIndex, size, length)));
+ () -> Preconditions.checkFromIndexSize(fromIndex, size, length,
+ assertingOutOfBoundsReturnNull("checkFromIndexSize", fromIndex, size, length)));
check.accept(IndexOutOfBoundsException.class,
- () -> Objects.checkFromIndexSize(fromIndex, size, length, null));
+ () -> Preconditions.checkFromIndexSize(fromIndex, size, length, null));
check.accept(IndexOutOfBoundsException.class,
() -> Objects.checkFromIndexSize(fromIndex, size, length));
check.accept(ArrayIndexOutOfBoundsException.class,
- () -> Objects.checkFromIndexSize(fromIndex, size, length,
- Objects.outOfBoundsExceptionFormatter(ArrayIndexOutOfBoundsException::new)));
+ () -> Preconditions.checkFromIndexSize(fromIndex, size, length,
+ Preconditions.outOfBoundsExceptionFormatter(ArrayIndexOutOfBoundsException::new)));
check.accept(StringIndexOutOfBoundsException.class,
- () -> Objects.checkFromIndexSize(fromIndex, size, length,
- Objects.outOfBoundsExceptionFormatter(StringIndexOutOfBoundsException::new)));
+ () -> Preconditions.checkFromIndexSize(fromIndex, size, length,
+ Preconditions.outOfBoundsExceptionFormatter(StringIndexOutOfBoundsException::new)));
}
@Test
public void uniqueMessagesForCheckKinds() {
BiFunction<String, List<Integer>, IndexOutOfBoundsException> f =
- Objects.outOfBoundsExceptionFormatter(IndexOutOfBoundsException::new);
+ Preconditions.outOfBoundsExceptionFormatter(IndexOutOfBoundsException::new);
List<String> messages = new ArrayList<>();
// Exact arguments