11d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert/* 21d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * Copyright (C) 2009 The Guava Authors 31d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 41d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except 51d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * in compliance with the License. You may obtain a copy of the License at 61d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 71d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * http://www.apache.org/licenses/LICENSE-2.0 81d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 91d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * Unless required by applicable law or agreed to in writing, software distributed under the License 101d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express 111d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * or implied. See the License for the specific language governing permissions and limitations under 121d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * the License. 131d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert */ 141d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 151d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertpackage com.google.common.collect; 161d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 171d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport static com.google.common.base.Preconditions.checkNotNull; 181d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 191d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport com.google.common.annotations.GwtCompatible; 201d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport com.google.common.primitives.Booleans; 211d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 221d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport java.io.Serializable; 231d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport java.util.NoSuchElementException; 241d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 251d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport javax.annotation.Nullable; 261d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 271d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert/** 281d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * Implementation detail for the internal structure of {@link Range} instances. Represents 291d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * a unique way of "cutting" a "number line" (actually of instances of type {@code C}, not 301d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * necessarily "numbers") into two sections; this can be done below a certain value, above 311d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * a certain value, below all values or above all values. With this object defined in this 321d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * way, an interval can always be represented by a pair of {@code Cut} instances. 331d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * 341d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * @author Kevin Bourrillion 351d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert */ 361d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert@GwtCompatible 371d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertabstract class Cut<C extends Comparable> implements Comparable<Cut<C>>, Serializable { 381d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert final C endpoint; 391d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 401d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Cut(@Nullable C endpoint) { 411d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert this.endpoint = endpoint; 421d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 431d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 441d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert abstract boolean isLessThan(C value); 451d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 461d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert abstract BoundType typeAsLowerBound(); 471d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert abstract BoundType typeAsUpperBound(); 481d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 491d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert abstract Cut<C> withLowerBoundType(BoundType boundType, DiscreteDomain<C> domain); 501d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert abstract Cut<C> withUpperBoundType(BoundType boundType, DiscreteDomain<C> domain); 511d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 521d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert abstract void describeAsLowerBound(StringBuilder sb); 531d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert abstract void describeAsUpperBound(StringBuilder sb); 541d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 551d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert abstract C leastValueAbove(DiscreteDomain<C> domain); 561d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert abstract C greatestValueBelow(DiscreteDomain<C> domain); 571d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 581d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert /* 591d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * The canonical form is a BelowValue cut whenever possible, otherwise ABOVE_ALL, or 601d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * (only in the case of types that are unbounded below) BELOW_ALL. 611d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert */ 621d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Cut<C> canonical(DiscreteDomain<C> domain) { 631d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return this; 641d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 651d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 661d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert // note: overriden by {BELOW,ABOVE}_ALL 671d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override 681d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert public int compareTo(Cut<C> that) { 691d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert if (that == belowAll()) { 701d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return 1; 711d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 721d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert if (that == aboveAll()) { 731d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return -1; 741d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 751d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert int result = Range.compareOrThrow(endpoint, that.endpoint); 761d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert if (result != 0) { 771d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return result; 781d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 791d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert // same value. below comes before above 801d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return Booleans.compare( 811d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert this instanceof AboveValue, that instanceof AboveValue); 821d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 831d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 841d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert C endpoint() { 851d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return endpoint; 861d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 871d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 881d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @SuppressWarnings("unchecked") // catching CCE 891d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public boolean equals(Object obj) { 901d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert if (obj instanceof Cut) { 911d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert // It might not really be a Cut<C>, but we'll catch a CCE if it's not 921d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert Cut<C> that = (Cut<C>) obj; 931d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert try { 941d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert int compareResult = compareTo(that); 951d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return compareResult == 0; 961d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } catch (ClassCastException ignored) { 971d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 981d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 991d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return false; 1001d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 1011d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 1021d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert /* 1031d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * The implementation neither produces nor consumes any non-null instance of type C, so 1041d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * casting the type parameter is safe. 1051d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert */ 1061d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @SuppressWarnings("unchecked") 1071d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert static <C extends Comparable> Cut<C> belowAll() { 1081d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return (Cut<C>) BelowAll.INSTANCE; 1091d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 1101d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 1111d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert private static final long serialVersionUID = 0; 1121d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 1131d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert private static final class BelowAll extends Cut<Comparable<?>> { 1141d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert private static final BelowAll INSTANCE = new BelowAll(); 1151d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 1161d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert private BelowAll() { 1171d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert super(null); 1181d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 1191d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override Comparable<?> endpoint() { 1201d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert throw new IllegalStateException("range unbounded on this side"); 1211d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 1221d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override boolean isLessThan(Comparable<?> value) { 1231d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return true; 1241d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 1251d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override BoundType typeAsLowerBound() { 1261d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert throw new IllegalStateException(); 1271d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 1281d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override BoundType typeAsUpperBound() { 1291d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert throw new AssertionError("this statement should be unreachable"); 1301d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 1311d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override Cut<Comparable<?>> withLowerBoundType(BoundType boundType, 1321d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert DiscreteDomain<Comparable<?>> domain) { 1331d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert throw new IllegalStateException(); 1341d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 1351d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override Cut<Comparable<?>> withUpperBoundType(BoundType boundType, 1361d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert DiscreteDomain<Comparable<?>> domain) { 1371d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert throw new AssertionError("this statement should be unreachable"); 1381d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 1391d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override void describeAsLowerBound(StringBuilder sb) { 1401d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert sb.append("(-\u221e"); 1411d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 1421d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override void describeAsUpperBound(StringBuilder sb) { 1431d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert throw new AssertionError(); 1441d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 1451d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override Comparable<?> leastValueAbove( 1461d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert DiscreteDomain<Comparable<?>> domain) { 1471d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return domain.minValue(); 1481d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 1491d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override Comparable<?> greatestValueBelow( 1501d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert DiscreteDomain<Comparable<?>> domain) { 1511d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert throw new AssertionError(); 1521d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 1531d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override Cut<Comparable<?>> canonical( 1541d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert DiscreteDomain<Comparable<?>> domain) { 1551d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert try { 1561d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return Cut.<Comparable<?>>belowValue(domain.minValue()); 1571d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } catch (NoSuchElementException e) { 1581d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return this; 1591d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 1601d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 1611d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public int compareTo(Cut<Comparable<?>> o) { 1621d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return (o == this) ? 0 : -1; 1631d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 1641d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert private Object readResolve() { 1651d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return INSTANCE; 1661d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 1671d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert private static final long serialVersionUID = 0; 1681d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 1691d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 1701d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert /* 1711d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * The implementation neither produces nor consumes any non-null instance of 1721d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * type C, so casting the type parameter is safe. 1731d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert */ 1741d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @SuppressWarnings("unchecked") 1751d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert static <C extends Comparable> Cut<C> aboveAll() { 1761d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return (Cut<C>) AboveAll.INSTANCE; 1771d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 1781d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 1791d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert private static final class AboveAll extends Cut<Comparable<?>> { 1801d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert private static final AboveAll INSTANCE = new AboveAll(); 1811d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 1821d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert private AboveAll() { 1831d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert super(null); 1841d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 1851d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override Comparable<?> endpoint() { 1861d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert throw new IllegalStateException("range unbounded on this side"); 1871d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 1881d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override boolean isLessThan(Comparable<?> value) { 1891d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return false; 1901d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 1911d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override BoundType typeAsLowerBound() { 1921d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert throw new AssertionError("this statement should be unreachable"); 1931d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 1941d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override BoundType typeAsUpperBound() { 1951d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert throw new IllegalStateException(); 1961d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 1971d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override Cut<Comparable<?>> withLowerBoundType(BoundType boundType, 1981d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert DiscreteDomain<Comparable<?>> domain) { 1991d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert throw new AssertionError("this statement should be unreachable"); 2001d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 2011d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override Cut<Comparable<?>> withUpperBoundType(BoundType boundType, 2021d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert DiscreteDomain<Comparable<?>> domain) { 2031d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert throw new IllegalStateException(); 2041d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 2051d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override void describeAsLowerBound(StringBuilder sb) { 2061d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert throw new AssertionError(); 2071d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 2081d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override void describeAsUpperBound(StringBuilder sb) { 2091d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert sb.append("+\u221e)"); 2101d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 2111d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override Comparable<?> leastValueAbove( 2121d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert DiscreteDomain<Comparable<?>> domain) { 2131d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert throw new AssertionError(); 2141d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 2151d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override Comparable<?> greatestValueBelow( 2161d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert DiscreteDomain<Comparable<?>> domain) { 2171d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return domain.maxValue(); 2181d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 2191d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public int compareTo(Cut<Comparable<?>> o) { 2201d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return (o == this) ? 0 : 1; 2211d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 2221d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert private Object readResolve() { 2231d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return INSTANCE; 2241d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 2251d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert private static final long serialVersionUID = 0; 2261d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 2271d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 2281d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert static <C extends Comparable> Cut<C> belowValue(C endpoint) { 2291d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return new BelowValue<C>(endpoint); 2301d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 2311d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 2321d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert private static final class BelowValue<C extends Comparable> extends Cut<C> { 2331d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert BelowValue(C endpoint) { 2341d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert super(checkNotNull(endpoint)); 2351d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 2361d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 2371d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override boolean isLessThan(C value) { 2381d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return Range.compareOrThrow(endpoint, value) <= 0; 2391d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 2401d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override BoundType typeAsLowerBound() { 2411d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return BoundType.CLOSED; 2421d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 2431d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override BoundType typeAsUpperBound() { 2441d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return BoundType.OPEN; 2451d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 2461d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override Cut<C> withLowerBoundType(BoundType boundType, DiscreteDomain<C> domain) { 2471d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert switch (boundType) { 2481d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert case CLOSED: 2491d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return this; 2501d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert case OPEN: 2511d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Nullable C previous = domain.previous(endpoint); 2521d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return (previous == null) ? Cut.<C>belowAll() : new AboveValue<C>(previous); 2531d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert default: 2541d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert throw new AssertionError(); 2551d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 2561d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 2571d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override Cut<C> withUpperBoundType(BoundType boundType, DiscreteDomain<C> domain) { 2581d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert switch (boundType) { 2591d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert case CLOSED: 2601d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Nullable C previous = domain.previous(endpoint); 2611d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return (previous == null) ? Cut.<C>aboveAll() : new AboveValue<C>(previous); 2621d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert case OPEN: 2631d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return this; 2641d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert default: 2651d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert throw new AssertionError(); 2661d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 2671d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 2681d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override void describeAsLowerBound(StringBuilder sb) { 2691d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert sb.append('[').append(endpoint); 2701d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 2711d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override void describeAsUpperBound(StringBuilder sb) { 2721d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert sb.append(endpoint).append(')'); 2731d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 2741d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override C leastValueAbove(DiscreteDomain<C> domain) { 2751d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return endpoint; 2761d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 2771d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override C greatestValueBelow(DiscreteDomain<C> domain) { 2781d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return domain.previous(endpoint); 2791d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 2801d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public int hashCode() { 2811d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return endpoint.hashCode(); 2821d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 2831d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert private static final long serialVersionUID = 0; 2841d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 2851d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 2861d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert static <C extends Comparable> Cut<C> aboveValue(C endpoint) { 2871d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return new AboveValue<C>(endpoint); 2881d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 2891d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 2901d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert private static final class AboveValue<C extends Comparable> extends Cut<C> { 2911d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert AboveValue(C endpoint) { 2921d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert super(checkNotNull(endpoint)); 2931d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 2941d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert 2951d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override boolean isLessThan(C value) { 2961d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return Range.compareOrThrow(endpoint, value) < 0; 2971d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 2981d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override BoundType typeAsLowerBound() { 2991d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return BoundType.OPEN; 3001d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 3011d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override BoundType typeAsUpperBound() { 3021d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return BoundType.CLOSED; 3031d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 3041d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override Cut<C> withLowerBoundType(BoundType boundType, DiscreteDomain<C> domain) { 3051d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert switch (boundType) { 3061d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert case OPEN: 3071d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return this; 3081d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert case CLOSED: 3091d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Nullable C next = domain.next(endpoint); 3101d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return (next == null) ? Cut.<C>belowAll() : belowValue(next); 3111d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert default: 3121d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert throw new AssertionError(); 3131d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 3141d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 3151d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override Cut<C> withUpperBoundType(BoundType boundType, DiscreteDomain<C> domain) { 3161d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert switch (boundType) { 3171d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert case OPEN: 3181d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Nullable C next = domain.next(endpoint); 3191d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return (next == null) ? Cut.<C>aboveAll() : belowValue(next); 3201d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert case CLOSED: 3211d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return this; 3221d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert default: 3231d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert throw new AssertionError(); 3241d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 3251d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 3261d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override void describeAsLowerBound(StringBuilder sb) { 3271d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert sb.append('(').append(endpoint); 3281d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 3291d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override void describeAsUpperBound(StringBuilder sb) { 3301d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert sb.append(endpoint).append(']'); 3311d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 3321d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override C leastValueAbove(DiscreteDomain<C> domain) { 3331d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return domain.next(endpoint); 3341d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 3351d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override C greatestValueBelow(DiscreteDomain<C> domain) { 3361d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return endpoint; 3371d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 3381d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override Cut<C> canonical(DiscreteDomain<C> domain) { 3391d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert C next = leastValueAbove(domain); 3401d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return (next != null) ? belowValue(next) : Cut.<C>aboveAll(); 3411d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 3421d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert @Override public int hashCode() { 3431d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert return ~endpoint.hashCode(); 3441d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 3451d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert private static final long serialVersionUID = 0; 3461d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert } 3471d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert} 348