mirror of
https://github.com/Eaglercraft-Archive/Eaglercraftx-1.8.8-src.git
synced 2025-06-28 02:48:14 -05:00
Update #0 - First Release
This commit is contained in:
275
sources/main/java/com/google/common/collect/GeneralRange.java
Normal file
275
sources/main/java/com/google/common/collect/GeneralRange.java
Normal file
@ -0,0 +1,275 @@
|
||||
/*
|
||||
* Copyright (C) 2011 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.checkArgument;
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
import static com.google.common.collect.BoundType.CLOSED;
|
||||
import static com.google.common.collect.BoundType.OPEN;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.Comparator;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
import com.google.common.annotations.GwtCompatible;
|
||||
import com.google.common.base.Objects;
|
||||
|
||||
/**
|
||||
* A generalized interval on any ordering, for internal use. Supports
|
||||
* {@code null}. Unlike {@link Range}, this allows the use of an arbitrary
|
||||
* comparator. This is designed for use in the implementation of subcollections
|
||||
* of sorted collection types.
|
||||
*
|
||||
* <p>
|
||||
* Whenever possible, use {@code Range} instead, which is better supported.
|
||||
*
|
||||
* @author Louis Wasserman
|
||||
*/
|
||||
@GwtCompatible(serializable = true)
|
||||
final class GeneralRange<T> implements Serializable {
|
||||
/**
|
||||
* Converts a Range to a GeneralRange.
|
||||
*/
|
||||
static <T extends Comparable> GeneralRange<T> from(Range<T> range) {
|
||||
@Nullable
|
||||
T lowerEndpoint = range.hasLowerBound() ? range.lowerEndpoint() : null;
|
||||
BoundType lowerBoundType = range.hasLowerBound() ? range.lowerBoundType() : OPEN;
|
||||
|
||||
@Nullable
|
||||
T upperEndpoint = range.hasUpperBound() ? range.upperEndpoint() : null;
|
||||
BoundType upperBoundType = range.hasUpperBound() ? range.upperBoundType() : OPEN;
|
||||
return new GeneralRange<T>(Ordering.natural(), range.hasLowerBound(), lowerEndpoint, lowerBoundType,
|
||||
range.hasUpperBound(), upperEndpoint, upperBoundType);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the whole range relative to the specified comparator.
|
||||
*/
|
||||
static <T> GeneralRange<T> all(Comparator<? super T> comparator) {
|
||||
return new GeneralRange<T>(comparator, false, null, OPEN, false, null, OPEN);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns everything above the endpoint relative to the specified comparator,
|
||||
* with the specified endpoint behavior.
|
||||
*/
|
||||
static <T> GeneralRange<T> downTo(Comparator<? super T> comparator, @Nullable T endpoint, BoundType boundType) {
|
||||
return new GeneralRange<T>(comparator, true, endpoint, boundType, false, null, OPEN);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns everything below the endpoint relative to the specified comparator,
|
||||
* with the specified endpoint behavior.
|
||||
*/
|
||||
static <T> GeneralRange<T> upTo(Comparator<? super T> comparator, @Nullable T endpoint, BoundType boundType) {
|
||||
return new GeneralRange<T>(comparator, false, null, OPEN, true, endpoint, boundType);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns everything between the endpoints relative to the specified
|
||||
* comparator, with the specified endpoint behavior.
|
||||
*/
|
||||
static <T> GeneralRange<T> range(Comparator<? super T> comparator, @Nullable T lower, BoundType lowerType,
|
||||
@Nullable T upper, BoundType upperType) {
|
||||
return new GeneralRange<T>(comparator, true, lower, lowerType, true, upper, upperType);
|
||||
}
|
||||
|
||||
private final Comparator<? super T> comparator;
|
||||
private final boolean hasLowerBound;
|
||||
@Nullable
|
||||
private final T lowerEndpoint;
|
||||
private final BoundType lowerBoundType;
|
||||
private final boolean hasUpperBound;
|
||||
@Nullable
|
||||
private final T upperEndpoint;
|
||||
private final BoundType upperBoundType;
|
||||
|
||||
private GeneralRange(Comparator<? super T> comparator, boolean hasLowerBound, @Nullable T lowerEndpoint,
|
||||
BoundType lowerBoundType, boolean hasUpperBound, @Nullable T upperEndpoint, BoundType upperBoundType) {
|
||||
this.comparator = checkNotNull(comparator);
|
||||
this.hasLowerBound = hasLowerBound;
|
||||
this.hasUpperBound = hasUpperBound;
|
||||
this.lowerEndpoint = lowerEndpoint;
|
||||
this.lowerBoundType = checkNotNull(lowerBoundType);
|
||||
this.upperEndpoint = upperEndpoint;
|
||||
this.upperBoundType = checkNotNull(upperBoundType);
|
||||
|
||||
if (hasLowerBound) {
|
||||
comparator.compare(lowerEndpoint, lowerEndpoint);
|
||||
}
|
||||
if (hasUpperBound) {
|
||||
comparator.compare(upperEndpoint, upperEndpoint);
|
||||
}
|
||||
if (hasLowerBound && hasUpperBound) {
|
||||
int cmp = comparator.compare(lowerEndpoint, upperEndpoint);
|
||||
// be consistent with Range
|
||||
checkArgument(cmp <= 0, "lowerEndpoint (%s) > upperEndpoint (%s)", lowerEndpoint, upperEndpoint);
|
||||
if (cmp == 0) {
|
||||
checkArgument(lowerBoundType != OPEN | upperBoundType != OPEN);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Comparator<? super T> comparator() {
|
||||
return comparator;
|
||||
}
|
||||
|
||||
boolean hasLowerBound() {
|
||||
return hasLowerBound;
|
||||
}
|
||||
|
||||
boolean hasUpperBound() {
|
||||
return hasUpperBound;
|
||||
}
|
||||
|
||||
boolean isEmpty() {
|
||||
return (hasUpperBound() && tooLow(getUpperEndpoint())) || (hasLowerBound() && tooHigh(getLowerEndpoint()));
|
||||
}
|
||||
|
||||
boolean tooLow(@Nullable T t) {
|
||||
if (!hasLowerBound()) {
|
||||
return false;
|
||||
}
|
||||
T lbound = getLowerEndpoint();
|
||||
int cmp = comparator.compare(t, lbound);
|
||||
return cmp < 0 | (cmp == 0 & getLowerBoundType() == OPEN);
|
||||
}
|
||||
|
||||
boolean tooHigh(@Nullable T t) {
|
||||
if (!hasUpperBound()) {
|
||||
return false;
|
||||
}
|
||||
T ubound = getUpperEndpoint();
|
||||
int cmp = comparator.compare(t, ubound);
|
||||
return cmp > 0 | (cmp == 0 & getUpperBoundType() == OPEN);
|
||||
}
|
||||
|
||||
boolean contains(@Nullable T t) {
|
||||
return !tooLow(t) && !tooHigh(t);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the intersection of the two ranges, or an empty range if their
|
||||
* intersection is empty.
|
||||
*/
|
||||
GeneralRange<T> intersect(GeneralRange<T> other) {
|
||||
checkNotNull(other);
|
||||
checkArgument(comparator.equals(other.comparator));
|
||||
|
||||
boolean hasLowBound = this.hasLowerBound;
|
||||
@Nullable
|
||||
T lowEnd = getLowerEndpoint();
|
||||
BoundType lowType = getLowerBoundType();
|
||||
if (!hasLowerBound()) {
|
||||
hasLowBound = other.hasLowerBound;
|
||||
lowEnd = other.getLowerEndpoint();
|
||||
lowType = other.getLowerBoundType();
|
||||
} else if (other.hasLowerBound()) {
|
||||
int cmp = comparator.compare(getLowerEndpoint(), other.getLowerEndpoint());
|
||||
if (cmp < 0 || (cmp == 0 && other.getLowerBoundType() == OPEN)) {
|
||||
lowEnd = other.getLowerEndpoint();
|
||||
lowType = other.getLowerBoundType();
|
||||
}
|
||||
}
|
||||
|
||||
boolean hasUpBound = this.hasUpperBound;
|
||||
@Nullable
|
||||
T upEnd = getUpperEndpoint();
|
||||
BoundType upType = getUpperBoundType();
|
||||
if (!hasUpperBound()) {
|
||||
hasUpBound = other.hasUpperBound;
|
||||
upEnd = other.getUpperEndpoint();
|
||||
upType = other.getUpperBoundType();
|
||||
} else if (other.hasUpperBound()) {
|
||||
int cmp = comparator.compare(getUpperEndpoint(), other.getUpperEndpoint());
|
||||
if (cmp > 0 || (cmp == 0 && other.getUpperBoundType() == OPEN)) {
|
||||
upEnd = other.getUpperEndpoint();
|
||||
upType = other.getUpperBoundType();
|
||||
}
|
||||
}
|
||||
|
||||
if (hasLowBound && hasUpBound) {
|
||||
int cmp = comparator.compare(lowEnd, upEnd);
|
||||
if (cmp > 0 || (cmp == 0 && lowType == OPEN && upType == OPEN)) {
|
||||
// force allowed empty range
|
||||
lowEnd = upEnd;
|
||||
lowType = OPEN;
|
||||
upType = CLOSED;
|
||||
}
|
||||
}
|
||||
|
||||
return new GeneralRange<T>(comparator, hasLowBound, lowEnd, lowType, hasUpBound, upEnd, upType);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(@Nullable Object obj) {
|
||||
if (obj instanceof GeneralRange) {
|
||||
GeneralRange<?> r = (GeneralRange<?>) obj;
|
||||
return comparator.equals(r.comparator) && hasLowerBound == r.hasLowerBound
|
||||
&& hasUpperBound == r.hasUpperBound && getLowerBoundType().equals(r.getLowerBoundType())
|
||||
&& getUpperBoundType().equals(r.getUpperBoundType())
|
||||
&& Objects.equal(getLowerEndpoint(), r.getLowerEndpoint())
|
||||
&& Objects.equal(getUpperEndpoint(), r.getUpperEndpoint());
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hashCode(comparator, getLowerEndpoint(), getLowerBoundType(), getUpperEndpoint(),
|
||||
getUpperBoundType());
|
||||
}
|
||||
|
||||
private transient GeneralRange<T> reverse;
|
||||
|
||||
/**
|
||||
* Returns the same range relative to the reversed comparator.
|
||||
*/
|
||||
GeneralRange<T> reverse() {
|
||||
GeneralRange<T> result = reverse;
|
||||
if (result == null) {
|
||||
result = new GeneralRange<T>(Ordering.from(comparator).reverse(), hasUpperBound, getUpperEndpoint(),
|
||||
getUpperBoundType(), hasLowerBound, getLowerEndpoint(), getLowerBoundType());
|
||||
result.reverse = this;
|
||||
return this.reverse = result;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return new StringBuilder().append(comparator).append(":").append(lowerBoundType == CLOSED ? '[' : '(')
|
||||
.append(hasLowerBound ? lowerEndpoint : "-\u221e").append(',')
|
||||
.append(hasUpperBound ? upperEndpoint : "\u221e").append(upperBoundType == CLOSED ? ']' : ')')
|
||||
.toString();
|
||||
}
|
||||
|
||||
T getLowerEndpoint() {
|
||||
return lowerEndpoint;
|
||||
}
|
||||
|
||||
BoundType getLowerBoundType() {
|
||||
return lowerBoundType;
|
||||
}
|
||||
|
||||
T getUpperEndpoint() {
|
||||
return upperEndpoint;
|
||||
}
|
||||
|
||||
BoundType getUpperBoundType() {
|
||||
return upperBoundType;
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user