intersection method

Range<C> intersection(
  1. Range<C> connectedRange
)

Returns the maximal range {@linkplain #encloses enclosed} by both this range and {@code connectedRange}, if such a range exists.

For example, the intersection of {@code [1..5]} and {@code (3..7)} is {@code (3..5]}. The resulting range may be empty; for example, {@code [1..5)} intersected with {@code [5..7)} yields the empty range {@code [5..5)}.

The intersection exists if and only if the two ranges are {@linkplain #isConnected connected}.

The intersection operation is commutative, associative and idempotent, and its identity element is {@link Range#all}).

@throws IllegalArgumentException if {@code isConnected(connectedRange)} is {@code false}

Implementation

Range<C> intersection(Range<C> connectedRange) {
  int lowerCmp = lowerBound.compareTo(connectedRange.lowerBound);
  int upperCmp = upperBound.compareTo(connectedRange.upperBound);
  if (lowerCmp >= 0 && upperCmp <= 0) {
    return this;
  } else if (lowerCmp <= 0 && upperCmp >= 0) {
    return connectedRange;
  } else {
    Cut<C> newLower =
        (lowerCmp >= 0) ? lowerBound : connectedRange.lowerBound;
    Cut<C> newUpper =
        (upperCmp <= 0) ? upperBound : connectedRange.upperBound;

    // create() would catch this, but give a confusing error message
    checkArgument(
      newLower.compareTo(newUpper) <= 0,
      message:
          "intersection is undefined for disconnected ranges $this and $connectedRange",
    );

    // TODO(kevinb): all the precondition checks in the constructor are redundant...
    return create(newLower, newUpper);
  }
}