All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.google.common.collect.Cut Maven / Gradle / Ivy

Go to download

This artifact provides a single jar that contains all classes required to use remote EJB and JMS, including all dependencies. It is intended for use by those not using maven, maven users should just import the EJB and JMS BOM's instead (shaded JAR's cause lots of problems with maven, as it is very easy to inadvertently end up with different versions on classes on the class path).

The newest version!
/*
 * Copyright (C) 2009 The Guava Authors
 *
 * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
 * in compliance with the License. You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software distributed under the License
 * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
 * or implied. See the License for the specific language governing permissions and limitations under
 * the License.
 */

package com.google.common.collect;

import static com.google.common.base.Preconditions.checkNotNull;

import com.google.common.annotations.GwtCompatible;
import com.google.common.primitives.Booleans;
import java.io.Serializable;
import java.util.NoSuchElementException;
import javax.annotation.CheckForNull;

/**
 * Implementation detail for the internal structure of {@link Range} instances. Represents a unique
 * way of "cutting" a "number line" (actually of instances of type {@code C}, not necessarily
 * "numbers") into two sections; this can be done below a certain value, above a certain value,
 * below all values or above all values. With this object defined in this way, an interval can
 * always be represented by a pair of {@code Cut} instances.
 *
 * @author Kevin Bourrillion
 */
@GwtCompatible
@ElementTypesAreNonnullByDefault
abstract class Cut implements Comparable>, Serializable {
  final C endpoint;

  Cut(C endpoint) {
    this.endpoint = endpoint;
  }

  abstract boolean isLessThan(C value);

  abstract BoundType typeAsLowerBound();

  abstract BoundType typeAsUpperBound();

  abstract Cut withLowerBoundType(BoundType boundType, DiscreteDomain domain);

  abstract Cut withUpperBoundType(BoundType boundType, DiscreteDomain domain);

  abstract void describeAsLowerBound(StringBuilder sb);

  abstract void describeAsUpperBound(StringBuilder sb);

  @CheckForNull
  abstract C leastValueAbove(DiscreteDomain domain);

  @CheckForNull
  abstract C greatestValueBelow(DiscreteDomain domain);

  /*
   * The canonical form is a BelowValue cut whenever possible, otherwise ABOVE_ALL, or
   * (only in the case of types that are unbounded below) BELOW_ALL.
   */
  Cut canonical(DiscreteDomain domain) {
    return this;
  }

  // note: overridden by {BELOW,ABOVE}_ALL
  @Override
  public int compareTo(Cut that) {
    if (that == belowAll()) {
      return 1;
    }
    if (that == aboveAll()) {
      return -1;
    }
    int result = Range.compareOrThrow(endpoint, that.endpoint);
    if (result != 0) {
      return result;
    }
    // same value. below comes before above
    return Booleans.compare(this instanceof AboveValue, that instanceof AboveValue);
  }

  C endpoint() {
    return endpoint;
  }

  @SuppressWarnings("unchecked") // catching CCE
  @Override
  public boolean equals(@CheckForNull Object obj) {
    if (obj instanceof Cut) {
      // It might not really be a Cut, but we'll catch a CCE if it's not
      Cut that = (Cut) obj;
      try {
        int compareResult = compareTo(that);
        return compareResult == 0;
      } catch (ClassCastException wastNotComparableToOurType) {
        return false;
      }
    }
    return false;
  }

  // Prevent "missing hashCode" warning by explicitly forcing subclasses implement it
  @Override
  public abstract int hashCode();

  /*
   * The implementation neither produces nor consumes any non-null instance of type C, so
   * casting the type parameter is safe.
   */
  @SuppressWarnings("unchecked")
  static  Cut belowAll() {
    return (Cut) BelowAll.INSTANCE;
  }

  private static final long serialVersionUID = 0;

  private static final class BelowAll extends Cut> {
    private static final BelowAll INSTANCE = new BelowAll();

    private BelowAll() {
      /*
       * No code ever sees this bogus value for `endpoint`: This class overrides both methods that
       * use the `endpoint` field, compareTo() and endpoint(). Additionally, the main implementation
       * of Cut.compareTo checks for belowAll before reading accessing `endpoint` on another Cut
       * instance.
       */
      super("");
    }

    @Override
    Comparable endpoint() {
      throw new IllegalStateException("range unbounded on this side");
    }

    @Override
    boolean isLessThan(Comparable value) {
      return true;
    }

    @Override
    BoundType typeAsLowerBound() {
      throw new IllegalStateException();
    }

    @Override
    BoundType typeAsUpperBound() {
      throw new AssertionError("this statement should be unreachable");
    }

    @Override
    Cut> withLowerBoundType(
        BoundType boundType, DiscreteDomain> domain) {
      throw new IllegalStateException();
    }

    @Override
    Cut> withUpperBoundType(
        BoundType boundType, DiscreteDomain> domain) {
      throw new AssertionError("this statement should be unreachable");
    }

    @Override
    void describeAsLowerBound(StringBuilder sb) {
      sb.append("(-\u221e");
    }

    @Override
    void describeAsUpperBound(StringBuilder sb) {
      throw new AssertionError();
    }

    @Override
    Comparable leastValueAbove(DiscreteDomain> domain) {
      return domain.minValue();
    }

    @Override
    Comparable greatestValueBelow(DiscreteDomain> domain) {
      throw new AssertionError();
    }

    @Override
    Cut> canonical(DiscreteDomain> domain) {
      try {
        return Cut.>belowValue(domain.minValue());
      } catch (NoSuchElementException e) {
        return this;
      }
    }

    @Override
    public int compareTo(Cut> o) {
      return (o == this) ? 0 : -1;
    }

    @Override
    public int hashCode() {
      return System.identityHashCode(this);
    }

    @Override
    public String toString() {
      return "-\u221e";
    }

    private Object readResolve() {
      return INSTANCE;
    }

    private static final long serialVersionUID = 0;
  }

  /*
   * The implementation neither produces nor consumes any non-null instance of
   * type C, so casting the type parameter is safe.
   */
  @SuppressWarnings("unchecked")
  static  Cut aboveAll() {
    return (Cut) AboveAll.INSTANCE;
  }

  private static final class AboveAll extends Cut> {
    private static final AboveAll INSTANCE = new AboveAll();

    private AboveAll() {
      // For discussion of "", see BelowAll.
      super("");
    }

    @Override
    Comparable endpoint() {
      throw new IllegalStateException("range unbounded on this side");
    }

    @Override
    boolean isLessThan(Comparable value) {
      return false;
    }

    @Override
    BoundType typeAsLowerBound() {
      throw new AssertionError("this statement should be unreachable");
    }

    @Override
    BoundType typeAsUpperBound() {
      throw new IllegalStateException();
    }

    @Override
    Cut> withLowerBoundType(
        BoundType boundType, DiscreteDomain> domain) {
      throw new AssertionError("this statement should be unreachable");
    }

    @Override
    Cut> withUpperBoundType(
        BoundType boundType, DiscreteDomain> domain) {
      throw new IllegalStateException();
    }

    @Override
    void describeAsLowerBound(StringBuilder sb) {
      throw new AssertionError();
    }

    @Override
    void describeAsUpperBound(StringBuilder sb) {
      sb.append("+\u221e)");
    }

    @Override
    Comparable leastValueAbove(DiscreteDomain> domain) {
      throw new AssertionError();
    }

    @Override
    Comparable greatestValueBelow(DiscreteDomain> domain) {
      return domain.maxValue();
    }

    @Override
    public int compareTo(Cut> o) {
      return (o == this) ? 0 : 1;
    }

    @Override
    public int hashCode() {
      return System.identityHashCode(this);
    }

    @Override
    public String toString() {
      return "+\u221e";
    }

    private Object readResolve() {
      return INSTANCE;
    }

    private static final long serialVersionUID = 0;
  }

  static  Cut belowValue(C endpoint) {
    return new BelowValue<>(endpoint);
  }

  private static final class BelowValue extends Cut {
    BelowValue(C endpoint) {
      super(checkNotNull(endpoint));
    }

    @Override
    boolean isLessThan(C value) {
      return Range.compareOrThrow(endpoint, value) <= 0;
    }

    @Override
    BoundType typeAsLowerBound() {
      return BoundType.CLOSED;
    }

    @Override
    BoundType typeAsUpperBound() {
      return BoundType.OPEN;
    }

    @Override
    Cut withLowerBoundType(BoundType boundType, DiscreteDomain domain) {
      switch (boundType) {
        case CLOSED:
          return this;
        case OPEN:
          C previous = domain.previous(endpoint);
          return (previous == null) ? Cut.belowAll() : new AboveValue(previous);
        default:
          throw new AssertionError();
      }
    }

    @Override
    Cut withUpperBoundType(BoundType boundType, DiscreteDomain domain) {
      switch (boundType) {
        case CLOSED:
          C previous = domain.previous(endpoint);
          return (previous == null) ? Cut.aboveAll() : new AboveValue(previous);
        case OPEN:
          return this;
        default:
          throw new AssertionError();
      }
    }

    @Override
    void describeAsLowerBound(StringBuilder sb) {
      sb.append('[').append(endpoint);
    }

    @Override
    void describeAsUpperBound(StringBuilder sb) {
      sb.append(endpoint).append(')');
    }

    @Override
    C leastValueAbove(DiscreteDomain domain) {
      return endpoint;
    }

    @Override
    @CheckForNull
    C greatestValueBelow(DiscreteDomain domain) {
      return domain.previous(endpoint);
    }

    @Override
    public int hashCode() {
      return endpoint.hashCode();
    }

    @Override
    public String toString() {
      return "\\" + endpoint + "/";
    }

    private static final long serialVersionUID = 0;
  }

  static  Cut aboveValue(C endpoint) {
    return new AboveValue<>(endpoint);
  }

  private static final class AboveValue extends Cut {
    AboveValue(C endpoint) {
      super(checkNotNull(endpoint));
    }

    @Override
    boolean isLessThan(C value) {
      return Range.compareOrThrow(endpoint, value) < 0;
    }

    @Override
    BoundType typeAsLowerBound() {
      return BoundType.OPEN;
    }

    @Override
    BoundType typeAsUpperBound() {
      return BoundType.CLOSED;
    }

    @Override
    Cut withLowerBoundType(BoundType boundType, DiscreteDomain domain) {
      switch (boundType) {
        case OPEN:
          return this;
        case CLOSED:
          C next = domain.next(endpoint);
          return (next == null) ? Cut.belowAll() : belowValue(next);
        default:
          throw new AssertionError();
      }
    }

    @Override
    Cut withUpperBoundType(BoundType boundType, DiscreteDomain domain) {
      switch (boundType) {
        case OPEN:
          C next = domain.next(endpoint);
          return (next == null) ? Cut.aboveAll() : belowValue(next);
        case CLOSED:
          return this;
        default:
          throw new AssertionError();
      }
    }

    @Override
    void describeAsLowerBound(StringBuilder sb) {
      sb.append('(').append(endpoint);
    }

    @Override
    void describeAsUpperBound(StringBuilder sb) {
      sb.append(endpoint).append(']');
    }

    @Override
    @CheckForNull
    C leastValueAbove(DiscreteDomain domain) {
      return domain.next(endpoint);
    }

    @Override
    C greatestValueBelow(DiscreteDomain domain) {
      return endpoint;
    }

    @Override
    Cut canonical(DiscreteDomain domain) {
      C next = leastValueAbove(domain);
      return (next != null) ? belowValue(next) : Cut.aboveAll();
    }

    @Override
    public int hashCode() {
      return ~endpoint.hashCode();
    }

    @Override
    public String toString() {
      return "/" + endpoint + "\\";
    }

    private static final long serialVersionUID = 0;
  }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy