345 throw new NullPointerException(messageSupplier.get()); |
347 throw new NullPointerException(messageSupplier.get()); |
346 return obj; |
348 return obj; |
347 } |
349 } |
348 |
350 |
349 /** |
351 /** |
350 * Maps out of bounds values to a runtime exception. |
352 * Maps out-of-bounds values to a runtime exception. |
351 * |
353 * |
352 * @param a the first out of bound value |
354 * @param checkKind the kind of bounds check, whose name may correspond |
353 * @param b the second out of bound value |
355 * to the name of one of the range check methods, checkIndex, |
354 * @param oobe the exception mapping function that when applied with out of |
356 * checkFromToIndex, checkFromIndexSize |
355 * bounds arguments returns a runtime exception. If {@code null} |
357 * @param args the out-of-bounds arguments that failed the range check. |
356 * then, it is as if an exception mapping function was supplied that |
358 * If the checkKind corresponds a the name of a range check method |
357 * returns {@link IndexOutOfBoundsException} for any given arguments. |
359 * then the bounds arguments are those that can be passed in order |
|
360 * to the method. |
|
361 * @param oobef the exception formatter that when applied with a checkKind |
|
362 * and a list out-of-bounds arguments returns a runtime exception. |
|
363 * If {@code null} then, it is as if an exception formatter was |
|
364 * supplied that returns {@link IndexOutOfBoundsException} for any |
|
365 * given arguments. |
358 * @return the runtime exception |
366 * @return the runtime exception |
359 */ |
367 */ |
360 private static RuntimeException outOfBounds( |
368 private static RuntimeException outOfBounds( |
361 int a, int b, BiFunction<Integer, Integer, ? extends RuntimeException> oobe) { |
369 BiFunction<String, List<Integer>, ? extends RuntimeException> oobef, |
362 RuntimeException e = oobe == null |
370 String checkKind, |
363 ? null : oobe.apply(a, b); |
371 Integer... args) { |
|
372 List<Integer> largs = List.of(args); |
|
373 RuntimeException e = oobef == null |
|
374 ? null : oobef.apply(checkKind, largs); |
364 return e == null |
375 return e == null |
365 ? new IndexOutOfBoundsException(a, b) : e; |
376 ? new IndexOutOfBoundsException(outOfBoundsMessage(checkKind, largs)) : e; |
|
377 } |
|
378 |
|
379 // Specific out-of-bounds exception producing methods that avoid |
|
380 // the varargs-based code in the critical methods there by reducing their |
|
381 // the byte code size, and therefore less likely to peturb inlining |
|
382 |
|
383 private static RuntimeException outOfBoundsCheckIndex( |
|
384 BiFunction<String, List<Integer>, ? extends RuntimeException> oobe, |
|
385 int index, int length) { |
|
386 return outOfBounds(oobe, "checkIndex", index, length); |
|
387 } |
|
388 |
|
389 private static RuntimeException outOfBoundsCheckFromToIndex( |
|
390 BiFunction<String, List<Integer>, ? extends RuntimeException> oobe, |
|
391 int fromIndex, int toIndex, int length) { |
|
392 return outOfBounds(oobe, "checkFromToIndex", fromIndex, toIndex, length); |
|
393 } |
|
394 |
|
395 private static RuntimeException outOfBoundsCheckFromIndexSize( |
|
396 BiFunction<String, List<Integer>, ? extends RuntimeException> oobe, |
|
397 int fromIndex, int size, int length) { |
|
398 return outOfBounds(oobe, "checkFromIndexSize", fromIndex, size, length); |
|
399 } |
|
400 |
|
401 /** |
|
402 * Returns an out-of-bounds exception formatter from an given exception |
|
403 * factory. The exception formatter is a function that formats an |
|
404 * out-of-bounds message from its arguments and applies that message to the |
|
405 * given exception factory to produce and relay an exception. |
|
406 * |
|
407 * <p>The exception formatter accepts two arguments: a {@code String} |
|
408 * describing the out-of-bounds range check that failed, referred to as the |
|
409 * <em>check kind</em>; and a {@code List<Integer>} containing the |
|
410 * out-of-bound integer values that failed the check. The list of |
|
411 * out-of-bound values is not modified. |
|
412 * |
|
413 * <p>Three check kinds are supported {@code checkIndex}, |
|
414 * {@code checkFromToIndex} and {@code checkFromIndexSize} corresponding |
|
415 * respectively to the specified application of an exception formatter as an |
|
416 * argument to the out-of-bounds range check methods |
|
417 * {@link #checkIndex(int, int, BiFunction) checkIndex}, |
|
418 * {@link #checkFromToIndex(int, int, int, BiFunction) checkFromToIndex}, and |
|
419 * {@link #checkFromIndexSize(int, int, int, BiFunction) checkFromIndexSize}. |
|
420 * Thus a supported check kind corresponds to a method name and the |
|
421 * out-of-bound integer values correspond to method argument values, in |
|
422 * order, preceding the exception formatter argument (similar in many |
|
423 * respects to the form of arguments required for a reflective invocation of |
|
424 * such a range check method). |
|
425 * |
|
426 * <p>Formatter arguments conforming to such supported check kinds will |
|
427 * produce specific exception messages describing failed out-of-bounds |
|
428 * checks. Otherwise, more generic exception messages will be produced in |
|
429 * any of the following cases: the check kind is supported but fewer |
|
430 * or more out-of-bounds values are supplied, the check kind is not |
|
431 * supported, the check kind is {@code null}, or the list of out-of-bound |
|
432 * values is {@code null}. |
|
433 * |
|
434 * @apiNote |
|
435 * This method produces an out-of-bounds exception formatter that can be |
|
436 * passed as an argument to any of the supported out-of-bounds range check |
|
437 * methods declared by {@code Objects}. For example, a formatter producing |
|
438 * an {@code ArrayIndexOutOfBoundsException} may be produced and stored on a |
|
439 * {@code static final} field as follows: |
|
440 * <pre>{@code |
|
441 * static final |
|
442 * BiFunction<String, List<Integer>, ArrayIndexOutOfBoundsException> AIOOBEF = |
|
443 * outOfBoundsExceptionFormatter(ArrayIndexOutOfBoundsException::new); |
|
444 * }</pre> |
|
445 * The formatter instance {@code AIOOBEF} may be passed as an argument to an |
|
446 * out-of-bounds range check method, such as checking if an {@code index} |
|
447 * is within the bounds of a {@code limit}: |
|
448 * <pre>{@code |
|
449 * checkIndex(index, limit, AIOOBEF); |
|
450 * }</pre> |
|
451 * If the bounds check fails then the range check method will throw an |
|
452 * {@code ArrayIndexOutOfBoundsException} with an appropriate exception |
|
453 * message that is a produced from {@code AIOOBEF} as follows: |
|
454 * <pre>{@code |
|
455 * AIOOBEF.apply("checkIndex", List.of(index, limit)); |
|
456 * }</pre> |
|
457 * |
|
458 * @param f the exception factory, that produces an exception from a message |
|
459 * where the message is produced and formatted by the returned |
|
460 * exception formatter. If this factory is stateless and side-effect |
|
461 * free then so is the returned formatter. |
|
462 * Exceptions thrown by the factory are relayed to the caller |
|
463 * of the returned formatter. |
|
464 * @param <X> the type of runtime exception to be returned by the given |
|
465 * exception factory and relayed by the exception formatter |
|
466 * @return the out-of-bounds exception formatter |
|
467 */ |
|
468 public static <X extends RuntimeException> |
|
469 BiFunction<String, List<Integer>, X> outOfBoundsExceptionFormatter(Function<String, X> f) { |
|
470 // Use anonymous class to avoid bootstrap issues if this method is |
|
471 // used early in startup |
|
472 return new BiFunction<String, List<Integer>, X>() { |
|
473 @Override |
|
474 public X apply(String checkKind, List<Integer> args) { |
|
475 return f.apply(outOfBoundsMessage(checkKind, args)); |
|
476 } |
|
477 }; |
|
478 } |
|
479 |
|
480 private static String outOfBoundsMessage(String checkKind, List<Integer> args) { |
|
481 if (checkKind == null && args == null) { |
|
482 return String.format("Range check failed"); |
|
483 } else if (checkKind == null) { |
|
484 return String.format("Range check failed: %s", args); |
|
485 } else if (args == null) { |
|
486 return String.format("Range check failed: %s", checkKind); |
|
487 } |
|
488 |
|
489 int argSize = 0; |
|
490 switch (checkKind) { |
|
491 case "checkIndex": |
|
492 argSize = 2; |
|
493 break; |
|
494 case "checkFromToIndex": |
|
495 case "checkFromIndexSize": |
|
496 argSize = 3; |
|
497 break; |
|
498 default: |
|
499 } |
|
500 |
|
501 // Switch to default if fewer or more arguments than required are supplied |
|
502 switch ((args.size() != argSize) ? "" : checkKind) { |
|
503 case "checkIndex": |
|
504 return String.format("Index %d out-of-bounds for length %d", |
|
505 args.get(0), args.get(1)); |
|
506 case "checkFromToIndex": |
|
507 return String.format("Range [%d, %d) out-of-bounds for length %d", |
|
508 args.get(0), args.get(1), args.get(2)); |
|
509 case "checkFromIndexSize": |
|
510 return String.format("Range [%d, %<d + %d) out-of-bounds for length %d", |
|
511 args.get(0), args.get(1), args.get(2)); |
|
512 default: |
|
513 return String.format("Range check failed: %s %s", checkKind, args); |
|
514 } |
366 } |
515 } |
367 |
516 |
368 /** |
517 /** |
369 * Checks if the {@code index} is within the bounds of the range from |
518 * Checks if the {@code index} is within the bounds of the range from |
370 * {@code 0} (inclusive) to {@code length} (exclusive). |
519 * {@code 0} (inclusive) to {@code length} (exclusive). |
371 * |
520 * |
372 * <p>The {@code index} is defined to be out of bounds if any of the |
521 * <p>The {@code index} is defined to be out-of-bounds if any of the |
373 * following inequalities is true: |
522 * following inequalities is true: |
374 * <ul> |
523 * <ul> |
375 * <li>{@code index < 0}</li> |
524 * <li>{@code index < 0}</li> |
376 * <li>{@code index >= length}</li> |
525 * <li>{@code index >= length}</li> |
377 * <li>{@code length < 0}, which is implied from the former inequalities</li> |
526 * <li>{@code length < 0}, which is implied from the former inequalities</li> |
378 * </ul> |
527 * </ul> |
379 * |
528 * |
|
529 * <p>This method behaves as if {@link #checkIndex(int, int, BiFunction)} |
|
530 * was called with same out-of-bounds arguments and an exception formatter |
|
531 * argument produced from an invocation of |
|
532 * {@code outOfBoundsExceptionFormatter(IndexOutOfBounds::new)} (though it may |
|
533 * be more efficient). |
|
534 * |
380 * @param index the index |
535 * @param index the index |
381 * @param length the upper-bound (exclusive) of the range |
536 * @param length the upper-bound (exclusive) of the range |
382 * @return {@code index} if it is within bounds of the range |
537 * @return {@code index} if it is within bounds of the range |
383 * @throws IndexOutOfBoundsException if the {@code index} is out of bounds |
538 * @throws IndexOutOfBoundsException if the {@code index} is out-of-bounds |
384 * @since 9 |
539 * @since 9 |
385 */ |
540 */ |
386 public static |
541 public static |
387 int checkIndex(int index, int length) throws IndexOutOfBoundsException { |
542 int checkIndex(int index, int length) { |
388 return checkIndex(index, length, null); |
543 return checkIndex(index, length, null); |
389 } |
544 } |
390 |
545 |
391 /** |
546 /** |
392 * Checks if the {@code index} is within the bounds of the range from |
547 * Checks if the {@code index} is within the bounds of the range from |
393 * {@code 0} (inclusive) to {@code length} (exclusive). |
548 * {@code 0} (inclusive) to {@code length} (exclusive). |
394 * |
549 * |
395 * <p>The {@code index} is defined to be out of bounds if any of the |
550 * <p>The {@code index} is defined to be out-of-bounds if any of the |
396 * following inequalities is true: |
551 * following inequalities is true: |
397 * <ul> |
552 * <ul> |
398 * <li>{@code index < 0}</li> |
553 * <li>{@code index < 0}</li> |
399 * <li>{@code index >= length}</li> |
554 * <li>{@code index >= length}</li> |
400 * <li>{@code length < 0}, which is implied from the former inequalities</li> |
555 * <li>{@code length < 0}, which is implied from the former inequalities</li> |
401 * </ul> |
556 * </ul> |
402 * |
557 * |
403 * <p>If the {@code index} is out of bounds, then a runtime exception is |
558 * <p>If the {@code index} is out-of-bounds, then a runtime exception is |
404 * thrown that is the result of applying the arguments {@code index} and |
559 * thrown that is the result of applying the following arguments to the |
405 * {@code length} to the given exception mapping function. |
560 * exception formatter: the name of this method, {@code checkIndex}; |
406 * |
561 * and an unmodifiable list integers whose values are, in order, the |
407 * @param <T> the type of runtime exception to throw if the arguments are |
562 * out-of-bounds arguments {@code index} and {@code length}. |
408 * out of bounds |
563 * |
|
564 * @param <X> the type of runtime exception to throw if the arguments are |
|
565 * out-of-bounds |
409 * @param index the index |
566 * @param index the index |
410 * @param length the upper-bound (exclusive) of the range |
567 * @param length the upper-bound (exclusive) of the range |
411 * @param oobe the exception mapping function that when applied with out |
568 * @param oobef the exception formatter that when applied with this |
412 * of bounds arguments returns a runtime exception. If {@code null} |
569 * method name and out-of-bounds arguments returns a runtime |
413 * or returns {@code null} then, it is as if an exception mapping |
570 * exception. If {@code null} or returns {@code null} then, it is as |
414 * function was supplied that returns |
571 * if an exception formatter produced from an invocation of |
415 * {@link IndexOutOfBoundsException} for any given arguments. |
572 * {@code outOfBoundsExceptionFormatter(IndexOutOfBounds::new)} is used |
416 * Exceptions thrown by the function are relayed to the caller. |
573 * instead (though it may be more efficient). |
|
574 * Exceptions thrown by the formatter are relayed to the caller. |
417 * @return {@code index} if it is within bounds of the range |
575 * @return {@code index} if it is within bounds of the range |
418 * @throws T if the {@code index} is out of bounds, then a runtime exception |
576 * @throws X if the {@code index} is out-of-bounds and the exception |
419 * is thrown that is the result of applying the out of bounds |
577 * formatter is non-{@code null} |
420 * arguments to the exception mapping function. |
578 * @throws IndexOutOfBoundsException if the {@code index} is out-of-bounds |
421 * @throws IndexOutOfBoundsException if the {@code index} is out of bounds |
579 * and the exception formatter is {@code null} |
422 * and the exception mapping function is {@code null} |
|
423 * @since 9 |
580 * @since 9 |
424 * |
581 * |
425 * @implNote |
582 * @implNote |
426 * This method is made intrinsic in optimizing compilers to guide |
583 * This method is made intrinsic in optimizing compilers to guide them to |
427 * them to perform unsigned comparisons of the index and length |
584 * perform unsigned comparisons of the index and length when it is known the |
428 * when it is known the length is a non-negative value (such as |
585 * length is a non-negative value (such as that of an array length or from |
429 * that of an array length or from the upper bound of a loop) |
586 * the upper bound of a loop) |
430 */ |
587 */ |
431 @HotSpotIntrinsicCandidate |
588 @HotSpotIntrinsicCandidate |
432 public static <T extends RuntimeException> |
589 public static <X extends RuntimeException> |
433 int checkIndex(int index, int length, |
590 int checkIndex(int index, int length, |
434 BiFunction<Integer, Integer, T> oobe) throws T, IndexOutOfBoundsException { |
591 BiFunction<String, List<Integer>, X> oobef) { |
435 if (index < 0 || index >= length) |
592 if (index < 0 || index >= length) |
436 throw outOfBounds(index, length, oobe); |
593 throw outOfBoundsCheckIndex(oobef, index, length); |
437 return index; |
594 return index; |
438 } |
595 } |
439 |
596 |
440 /** |
597 /** |
441 * Checks if the sub-range from {@code fromIndex} (inclusive) to |
598 * Checks if the sub-range from {@code fromIndex} (inclusive) to |
442 * {@code toIndex} (exclusive) is within the bounds of range from {@code 0} |
599 * {@code toIndex} (exclusive) is within the bounds of range from {@code 0} |
443 * (inclusive) to {@code length} (exclusive). |
600 * (inclusive) to {@code length} (exclusive). |
444 * |
601 * |
445 * <p>The sub-range is defined to be out of bounds if any of the following |
602 * <p>The sub-range is defined to be out-of-bounds if any of the following |
446 * inequalities is true: |
603 * inequalities is true: |
447 * <ul> |
604 * <ul> |
448 * <li>{@code fromIndex < 0}</li> |
605 * <li>{@code fromIndex < 0}</li> |
449 * <li>{@code fromIndex > toIndex}</li> |
606 * <li>{@code fromIndex > toIndex}</li> |
450 * <li>{@code toIndex > length}</li> |
607 * <li>{@code toIndex > length}</li> |
451 * <li>{@code length < 0}, which is implied from the former inequalities</li> |
608 * <li>{@code length < 0}, which is implied from the former inequalities</li> |
452 * </ul> |
609 * </ul> |
453 * |
610 * |
|
611 * <p>This method behaves as if {@link #checkFromToIndex(int, int, int, BiFunction)} |
|
612 * was called with same out-of-bounds arguments and an exception formatter |
|
613 * argument produced from an invocation of |
|
614 * {@code outOfBoundsExceptionFormatter(IndexOutOfBounds::new)} (though it may |
|
615 * be more efficient). |
|
616 * |
454 * @param fromIndex the lower-bound (inclusive) of the sub-range |
617 * @param fromIndex the lower-bound (inclusive) of the sub-range |
455 * @param toIndex the upper-bound (exclusive) of the sub-range |
618 * @param toIndex the upper-bound (exclusive) of the sub-range |
456 * @param length the upper-bound (exclusive) the range |
619 * @param length the upper-bound (exclusive) the range |
457 * @return {@code fromIndex} if the sub-range within bounds of the range |
620 * @return {@code fromIndex} if the sub-range within bounds of the range |
458 * @throws IndexOutOfBoundsException if the sub-range is out of bounds |
621 * @throws IndexOutOfBoundsException if the sub-range is out-of-bounds |
459 * @since 9 |
622 * @since 9 |
460 */ |
623 */ |
461 public static |
624 public static |
462 int checkFromToIndex(int fromIndex, int toIndex, int length) throws IndexOutOfBoundsException { |
625 int checkFromToIndex(int fromIndex, int toIndex, int length) { |
463 return checkFromToIndex(fromIndex, toIndex, length, null); |
626 return checkFromToIndex(fromIndex, toIndex, length, null); |
464 } |
627 } |
465 |
628 |
466 /** |
629 /** |
467 * Checks if the sub-range from {@code fromIndex} (inclusive) to |
630 * Checks if the sub-range from {@code fromIndex} (inclusive) to |
468 * {@code toIndex} (exclusive) is within the bounds of range from {@code 0} |
631 * {@code toIndex} (exclusive) is within the bounds of range from {@code 0} |
469 * (inclusive) to {@code length} (exclusive). |
632 * (inclusive) to {@code length} (exclusive). |
470 * |
633 * |
471 * <p>The sub-range is defined to be out of bounds if any of the following |
634 * <p>The sub-range is defined to be out-of-bounds if any of the following |
472 * inequalities is true: |
635 * inequalities is true: |
473 * <ul> |
636 * <ul> |
474 * <li>{@code fromIndex < 0}</li> |
637 * <li>{@code fromIndex < 0}</li> |
475 * <li>{@code fromIndex > toIndex}</li> |
638 * <li>{@code fromIndex > toIndex}</li> |
476 * <li>{@code toIndex > length}</li> |
639 * <li>{@code toIndex > length}</li> |
477 * <li>{@code length < 0}, which is implied from the former inequalities</li> |
640 * <li>{@code length < 0}, which is implied from the former inequalities</li> |
478 * </ul> |
641 * </ul> |
479 * |
642 * |
480 * <p>If the sub-range is out of bounds, then a runtime exception is thrown |
643 * <p>If the sub-range is out-of-bounds, then a runtime exception is |
481 * that is the result of applying the arguments {@code fromIndex} and |
644 * thrown that is the result of applying the following arguments to the |
482 * {@code toIndex} to the given exception mapping function. |
645 * exception formatter: the name of this method, {@code checkFromToIndex}; |
483 * |
646 * and an unmodifiable list integers whose values are, in order, the |
484 * @param <T> the type of runtime exception to throw if the arguments are |
647 * out-of-bounds arguments {@code fromIndex}, {@code toIndex}, and {@code length}. |
485 * out of bounds |
648 * |
|
649 * @param <X> the type of runtime exception to throw if the arguments are |
|
650 * out-of-bounds |
486 * @param fromIndex the lower-bound (inclusive) of the sub-range |
651 * @param fromIndex the lower-bound (inclusive) of the sub-range |
487 * @param toIndex the upper-bound (exclusive) of the sub-range |
652 * @param toIndex the upper-bound (exclusive) of the sub-range |
488 * @param length the upper-bound (exclusive) the range |
653 * @param length the upper-bound (exclusive) the range |
489 * @param oobe the exception mapping function that when applied with out |
654 * @param oobef the exception formatter that when applied with this |
490 * of bounds arguments returns a runtime exception. If {@code null} |
655 * method name and out-of-bounds arguments returns a runtime |
491 * or returns {@code null} then, it is as if an exception mapping |
656 * exception. If {@code null} or returns {@code null} then, it is as |
492 * function was supplied that returns |
657 * if an exception formatter produced from an invocation of |
493 * {@link IndexOutOfBoundsException} for any given arguments. |
658 * {@code outOfBoundsExceptionFormatter(IndexOutOfBounds::new)} is used |
494 * Exceptions thrown by the function are relayed to the caller. |
659 * instead (though it may be more efficient). |
|
660 * Exceptions thrown by the formatter are relayed to the caller. |
495 * @return {@code fromIndex} if the sub-range within bounds of the range |
661 * @return {@code fromIndex} if the sub-range within bounds of the range |
496 * @throws T if the sub-range is out of bounds, then a runtime exception is |
662 * @throws X if the sub-range is out-of-bounds and the exception factory |
497 * thrown that is the result of applying the out of bounds arguments |
663 * function is non-{@code null} |
498 * to the exception mapping function. |
664 * @throws IndexOutOfBoundsException if the sub-range is out-of-bounds and |
499 * @throws IndexOutOfBoundsException if the sub-range is out of bounds and |
665 * the exception factory function is {@code null} |
500 * the exception mapping function is {@code null} |
|
501 * @since 9 |
666 * @since 9 |
502 */ |
667 */ |
503 public static <T extends RuntimeException> |
668 public static <X extends RuntimeException> |
504 int checkFromToIndex(int fromIndex, int toIndex, int length, |
669 int checkFromToIndex(int fromIndex, int toIndex, int length, |
505 BiFunction<Integer, Integer, T> oobe) throws T, IndexOutOfBoundsException { |
670 BiFunction<String, List<Integer>, X> oobef) { |
506 if (fromIndex < 0 || fromIndex > toIndex || toIndex > length) |
671 if (fromIndex < 0 || fromIndex > toIndex || toIndex > length) |
507 throw outOfBounds(fromIndex, toIndex, oobe); |
672 throw outOfBoundsCheckFromToIndex(oobef, fromIndex, toIndex, length); |
508 return fromIndex; |
673 return fromIndex; |
509 } |
674 } |
510 |
675 |
511 /** |
676 /** |
512 * Checks if the sub-range from {@code fromIndex} (inclusive) to |
677 * Checks if the sub-range from {@code fromIndex} (inclusive) to |
513 * {@code fromIndex + size} (exclusive) is within the bounds of range from |
678 * {@code fromIndex + size} (exclusive) is within the bounds of range from |
514 * {@code 0} (inclusive) to {@code length} (exclusive). |
679 * {@code 0} (inclusive) to {@code length} (exclusive). |
515 * |
680 * |
516 * <p>The sub-range is defined to be out of bounds if any of the following |
681 * <p>The sub-range is defined to be out-of-bounds if any of the following |
517 * inequalities is true: |
682 * inequalities is true: |
518 * <ul> |
683 * <ul> |
519 * <li>{@code fromIndex < 0}</li> |
684 * <li>{@code fromIndex < 0}</li> |
520 * <li>{@code size < 0}</li> |
685 * <li>{@code size < 0}</li> |
521 * <li>{@code fromIndex + size > length}, taking into account integer overflow</li> |
686 * <li>{@code fromIndex + size > length}, taking into account integer overflow</li> |
522 * <li>{@code length < 0}, which is implied from the former inequalities</li> |
687 * <li>{@code length < 0}, which is implied from the former inequalities</li> |
523 * </ul> |
688 * </ul> |
524 * |
689 * |
|
690 * <p>This method behaves as if {@link #checkFromIndexSize(int, int, int, BiFunction)} |
|
691 * was called with same out-of-bounds arguments and an exception formatter |
|
692 * argument produced from an invocation of |
|
693 * {@code outOfBoundsExceptionFormatter(IndexOutOfBounds::new)} (though it may |
|
694 * be more efficient). |
|
695 * |
525 * @param fromIndex the lower-bound (inclusive) of the sub-interval |
696 * @param fromIndex the lower-bound (inclusive) of the sub-interval |
526 * @param size the size of the sub-range |
697 * @param size the size of the sub-range |
527 * @param length the upper-bound (exclusive) of the range |
698 * @param length the upper-bound (exclusive) of the range |
528 * @return {@code fromIndex} if the sub-range within bounds of the range |
699 * @return {@code fromIndex} if the sub-range within bounds of the range |
529 * @throws IndexOutOfBoundsException if the sub-range is out of bounds |
700 * @throws IndexOutOfBoundsException if the sub-range is out-of-bounds |
530 * @since 9 |
701 * @since 9 |
531 */ |
702 */ |
532 public static |
703 public static |
533 int checkFromIndexSize(int fromIndex, int size, int length) throws IndexOutOfBoundsException { |
704 int checkFromIndexSize(int fromIndex, int size, int length) { |
534 return checkFromIndexSize(fromIndex, size, length, null); |
705 return checkFromIndexSize(fromIndex, size, length, null); |
535 } |
706 } |
536 |
707 |
537 /** |
708 /** |
538 * Checks if the sub-range from {@code fromIndex} (inclusive) to |
709 * Checks if the sub-range from {@code fromIndex} (inclusive) to |
539 * {@code fromIndex + size} (exclusive) is within the bounds of range from |
710 * {@code fromIndex + size} (exclusive) is within the bounds of range from |
540 * {@code 0} (inclusive) to {@code length} (exclusive). |
711 * {@code 0} (inclusive) to {@code length} (exclusive). |
541 * |
712 * |
542 * <p>The sub-range is defined to be out of bounds if any of the following |
713 * <p>The sub-range is defined to be out-of-bounds if any of the following |
543 * inequalities is true: |
714 * inequalities is true: |
544 * <ul> |
715 * <ul> |
545 * <li>{@code fromIndex < 0}</li> |
716 * <li>{@code fromIndex < 0}</li> |
546 * <li>{@code size < 0}</li> |
717 * <li>{@code size < 0}</li> |
547 * <li>{@code fromIndex + size > length}, taking into account integer overflow</li> |
718 * <li>{@code fromIndex + size > length}, taking into account integer overflow</li> |
548 * <li>{@code length < 0}, which is implied from the former inequalities</li> |
719 * <li>{@code length < 0}, which is implied from the former inequalities</li> |
549 * </ul> |
720 * </ul> |
550 * |
721 * |
551 * <p>If the sub-range is out of bounds then, a runtime exception is thrown |
722 * <p>If the sub-range is out-of-bounds, then a runtime exception is |
552 * that is the result of applying the arguments {@code fromIndex} and |
723 * thrown that is the result of applying the following arguments to the |
553 * {@code size} to the given exception mapping function. |
724 * exception formatter: the name of this method, {@code checkFromIndexSize}; |
554 * |
725 * and an unmodifiable list integers whose values are, in order, the |
555 * @param <T> the type of runtime exception to throw if the arguments are |
726 * out-of-bounds arguments {@code fromIndex}, {@code size}, and |
556 * out of bounds |
727 * {@code length}. |
|
728 * |
|
729 * @param <X> the type of runtime exception to throw if the arguments are |
|
730 * out-of-bounds |
557 * @param fromIndex the lower-bound (inclusive) of the sub-interval |
731 * @param fromIndex the lower-bound (inclusive) of the sub-interval |
558 * @param size the size of the sub-range |
732 * @param size the size of the sub-range |
559 * @param length the upper-bound (exclusive) of the range |
733 * @param length the upper-bound (exclusive) of the range |
560 * @param oobe the exception mapping function that when applied with out |
734 * @param oobef the exception formatter that when applied with this |
561 * of bounds arguments returns a runtime exception. If {@code null} |
735 * method name and out-of-bounds arguments returns a runtime |
562 * or returns {@code null} then, it is as if an exception mapping |
736 * exception. If {@code null} or returns {@code null} then, it is as |
563 * function was supplied that returns |
737 * if an exception formatter produced from an invocation of |
564 * {@link IndexOutOfBoundsException} for any given arguments. |
738 * {@code outOfBoundsExceptionFormatter(IndexOutOfBounds::new)} is used |
565 * Exceptions thrown by the function are relayed to the caller. |
739 * instead (though it may be more efficient). |
|
740 * Exceptions thrown by the formatter are relayed to the caller. |
566 * @return {@code fromIndex} if the sub-range within bounds of the range |
741 * @return {@code fromIndex} if the sub-range within bounds of the range |
567 * @throws T if the sub-range is out of bounds, then a runtime exception is |
742 * @throws X if the sub-range is out-of-bounds and the exception factory |
568 * thrown that is the result of applying the out of bounds arguments |
743 * function is non-{@code null} |
569 * to the exception mapping function. |
744 * @throws IndexOutOfBoundsException if the sub-range is out-of-bounds and |
570 * @throws IndexOutOfBoundsException if the sub-range is out of bounds and |
745 * the exception factory function is {@code null} |
571 * the exception mapping function is {@code null} |
|
572 * @since 9 |
746 * @since 9 |
573 */ |
747 */ |
574 public static <T extends RuntimeException> |
748 public static <X extends RuntimeException> |
575 int checkFromIndexSize(int fromIndex, int size, int length, |
749 int checkFromIndexSize(int fromIndex, int size, int length, |
576 BiFunction<Integer, Integer, T> oobe) throws T, IndexOutOfBoundsException { |
750 BiFunction<String, List<Integer>, X> oobef) { |
577 if ((length | fromIndex | size) < 0 || size > length - fromIndex) |
751 if ((length | fromIndex | size) < 0 || size > length - fromIndex) |
578 throw outOfBounds(fromIndex, size, oobe); |
752 throw outOfBoundsCheckFromIndexSize(oobef, fromIndex, size, length); |
579 return fromIndex; |
753 return fromIndex; |
580 } |
754 } |
581 } |
755 } |