• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2008 The Guava Authors
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package com.google.common.collect;
18 
19 import static com.google.common.base.Preconditions.checkNotNull;
20 
21 import com.google.common.annotations.GwtCompatible;
22 import com.google.common.base.Equivalence;
23 import com.google.common.base.Function;
24 import com.google.common.base.Predicate;
25 
26 import java.io.Serializable;
27 import java.util.Comparator;
28 import java.util.Iterator;
29 import java.util.NoSuchElementException;
30 import java.util.SortedSet;
31 
32 import javax.annotation.Nullable;
33 
34 /**
35  * A range (or "interval") defines the <i>boundaries</i> around a contiguous span of values of some
36  * {@code Comparable} type; for example, "integers from 1 to 100 inclusive." Note that it is not
37  * possible to <i>iterate</i> over these contained values. To do so, pass this range instance and
38  * an appropriate {@link DiscreteDomain} to {@link ContiguousSet#create}.
39  *
40  * <h3>Types of ranges</h3>
41  *
42  * <p>Each end of the range may be bounded or unbounded. If bounded, there is an associated
43  * <i>endpoint</i> value, and the range is considered to be either <i>open</i> (does not include the
44  * endpoint) or <i>closed</i> (includes the endpoint) on that side. With three possibilities on each
45  * side, this yields nine basic types of ranges, enumerated below. (Notation: a square bracket
46  * ({@code [ ]}) indicates that the range is closed on that side; a parenthesis ({@code ( )}) means
47  * it is either open or unbounded. The construct {@code {x | statement}} is read "the set of all
48  * <i>x</i> such that <i>statement</i>.")
49  *
50  * <blockquote><table>
51  * <tr><td><b>Notation</b> <td><b>Definition</b>        <td><b>Factory method</b>
52  * <tr><td>{@code (a..b)}  <td>{@code {x | a < x < b}}  <td>{@link Range#open open}
53  * <tr><td>{@code [a..b]}  <td>{@code {x | a <= x <= b}}<td>{@link Range#closed closed}
54  * <tr><td>{@code (a..b]}  <td>{@code {x | a < x <= b}} <td>{@link Range#openClosed openClosed}
55  * <tr><td>{@code [a..b)}  <td>{@code {x | a <= x < b}} <td>{@link Range#closedOpen closedOpen}
56  * <tr><td>{@code (a..+∞)} <td>{@code {x | x > a}}      <td>{@link Range#greaterThan greaterThan}
57  * <tr><td>{@code [a..+∞)} <td>{@code {x | x >= a}}     <td>{@link Range#atLeast atLeast}
58  * <tr><td>{@code (-∞..b)} <td>{@code {x | x < b}}      <td>{@link Range#lessThan lessThan}
59  * <tr><td>{@code (-∞..b]} <td>{@code {x | x <= b}}     <td>{@link Range#atMost atMost}
60  * <tr><td>{@code (-∞..+∞)}<td>{@code {x}}              <td>{@link Range#all all}
61  * </table></blockquote>
62  *
63  * <p>When both endpoints exist, the upper endpoint may not be less than the lower. The endpoints
64  * may be equal only if at least one of the bounds is closed:
65  *
66  * <ul>
67  * <li>{@code [a..a]} : a singleton range
68  * <li>{@code [a..a); (a..a]} : {@linkplain #isEmpty empty} ranges; also valid
69  * <li>{@code (a..a)} : <b>invalid</b>; an exception will be thrown
70  * </ul>
71  *
72  * <h3>Warnings</h3>
73  *
74  * <ul>
75  * <li>Use immutable value types only, if at all possible. If you must use a mutable type, <b>do
76  *     not</b> allow the endpoint instances to mutate after the range is created!
77  * <li>Your value type's comparison method should be {@linkplain Comparable consistent with equals}
78  *     if at all possible. Otherwise, be aware that concepts used throughout this documentation such
79  *     as "equal", "same", "unique" and so on actually refer to whether {@link Comparable#compareTo
80  *     compareTo} returns zero, not whether {@link Object#equals equals} returns {@code true}.
81  * <li>A class which implements {@code Comparable<UnrelatedType>} is very broken, and will cause
82  *     undefined horrible things to happen in {@code Range}. For now, the Range API does not prevent
83  *     its use, because this would also rule out all ungenerified (pre-JDK1.5) data types. <b>This
84  *     may change in the future.</b>
85  * </ul>
86  *
87  * <h3>Other notes</h3>
88  *
89  * <ul>
90  * <li>Instances of this type are obtained using the static factory methods in this class.
91  * <li>Ranges are <i>convex</i>: whenever two values are contained, all values in between them must
92  *     also be contained. More formally, for any {@code c1 <= c2 <= c3} of type {@code C}, {@code
93  *     r.contains(c1) && r.contains(c3)} implies {@code r.contains(c2)}). This means that a {@code
94  *     Range<Integer>} can never be used to represent, say, "all <i>prime</i> numbers from 1 to
95  *     100."
96  * <li>When evaluated as a {@link Predicate}, a range yields the same result as invoking {@link
97  *     #contains}.
98  * <li>Terminology note: a range {@code a} is said to be the <i>maximal</i> range having property
99  *     <i>P</i> if, for all ranges {@code b} also having property <i>P</i>, {@code a.encloses(b)}.
100  *     Likewise, {@code a} is <i>minimal</i> when {@code b.encloses(a)} for all {@code b} having
101  *     property <i>P</i>. See, for example, the definition of {@link #intersection intersection}.
102  * </ul>
103  *
104  * <h3>Further reading</h3>
105  *
106  * <p>See the Guava User Guide article on
107  * <a href="http://code.google.com/p/guava-libraries/wiki/RangesExplained">{@code Range}</a>.
108  *
109  * @author Kevin Bourrillion
110  * @author Gregory Kick
111  * @since 10.0
112  */
113 @GwtCompatible
114 @SuppressWarnings("rawtypes")
115 public final class Range<C extends Comparable> implements Predicate<C>, Serializable {
116 
117   private static final Function<Range, Cut> LOWER_BOUND_FN = new Function<Range, Cut>() {
118     @Override
119     public Cut apply(Range range) {
120       return range.lowerBound;
121     }
122   };
123 
124   @SuppressWarnings("unchecked")
lowerBoundFn()125   static <C extends Comparable<?>> Function<Range<C>, Cut<C>> lowerBoundFn() {
126     return (Function) LOWER_BOUND_FN;
127   }
128 
129   private static final Function<Range, Cut> UPPER_BOUND_FN = new Function<Range, Cut>() {
130     @Override
131     public Cut apply(Range range) {
132       return range.upperBound;
133     }
134   };
135 
136   @SuppressWarnings("unchecked")
upperBoundFn()137   static <C extends Comparable<?>> Function<Range<C>, Cut<C>> upperBoundFn() {
138     return (Function) UPPER_BOUND_FN;
139   }
140 
141   static final Ordering<Range<?>> RANGE_LEX_ORDERING = new Ordering<Range<?>>() {
142     @Override
143     public int compare(Range<?> left, Range<?> right) {
144       return ComparisonChain.start()
145           .compare(left.lowerBound, right.lowerBound)
146           .compare(left.upperBound, right.upperBound)
147           .result();
148     }
149   };
150 
create( Cut<C> lowerBound, Cut<C> upperBound)151   static <C extends Comparable<?>> Range<C> create(
152       Cut<C> lowerBound, Cut<C> upperBound) {
153     return new Range<C>(lowerBound, upperBound);
154   }
155 
156   /**
157    * Returns a range that contains all values strictly greater than {@code
158    * lower} and strictly less than {@code upper}.
159    *
160    * @throws IllegalArgumentException if {@code lower} is greater than <i>or
161    *     equal to</i> {@code upper}
162    * @since 14.0
163    */
open(C lower, C upper)164   public static <C extends Comparable<?>> Range<C> open(C lower, C upper) {
165     return create(Cut.aboveValue(lower), Cut.belowValue(upper));
166   }
167 
168   /**
169    * Returns a range that contains all values greater than or equal to
170    * {@code lower} and less than or equal to {@code upper}.
171    *
172    * @throws IllegalArgumentException if {@code lower} is greater than {@code
173    *     upper}
174    * @since 14.0
175    */
closed(C lower, C upper)176   public static <C extends Comparable<?>> Range<C> closed(C lower, C upper) {
177     return create(Cut.belowValue(lower), Cut.aboveValue(upper));
178   }
179 
180   /**
181    * Returns a range that contains all values greater than or equal to
182    * {@code lower} and strictly less than {@code upper}.
183    *
184    * @throws IllegalArgumentException if {@code lower} is greater than {@code
185    *     upper}
186    * @since 14.0
187    */
closedOpen( C lower, C upper)188   public static <C extends Comparable<?>> Range<C> closedOpen(
189       C lower, C upper) {
190     return create(Cut.belowValue(lower), Cut.belowValue(upper));
191   }
192 
193   /**
194    * Returns a range that contains all values strictly greater than {@code
195    * lower} and less than or equal to {@code upper}.
196    *
197    * @throws IllegalArgumentException if {@code lower} is greater than {@code
198    *     upper}
199    * @since 14.0
200    */
openClosed( C lower, C upper)201   public static <C extends Comparable<?>> Range<C> openClosed(
202       C lower, C upper) {
203     return create(Cut.aboveValue(lower), Cut.aboveValue(upper));
204   }
205 
206   /**
207    * Returns a range that contains any value from {@code lower} to {@code
208    * upper}, where each endpoint may be either inclusive (closed) or exclusive
209    * (open).
210    *
211    * @throws IllegalArgumentException if {@code lower} is greater than {@code
212    *     upper}
213    * @since 14.0
214    */
range( C lower, BoundType lowerType, C upper, BoundType upperType)215   public static <C extends Comparable<?>> Range<C> range(
216       C lower, BoundType lowerType, C upper, BoundType upperType) {
217     checkNotNull(lowerType);
218     checkNotNull(upperType);
219 
220     Cut<C> lowerBound = (lowerType == BoundType.OPEN)
221         ? Cut.aboveValue(lower)
222         : Cut.belowValue(lower);
223     Cut<C> upperBound = (upperType == BoundType.OPEN)
224         ? Cut.belowValue(upper)
225         : Cut.aboveValue(upper);
226     return create(lowerBound, upperBound);
227   }
228 
229   /**
230    * Returns a range that contains all values strictly less than {@code
231    * endpoint}.
232    *
233    * @since 14.0
234    */
lessThan(C endpoint)235   public static <C extends Comparable<?>> Range<C> lessThan(C endpoint) {
236     return create(Cut.<C>belowAll(), Cut.belowValue(endpoint));
237   }
238 
239   /**
240    * Returns a range that contains all values less than or equal to
241    * {@code endpoint}.
242    *
243    * @since 14.0
244    */
atMost(C endpoint)245   public static <C extends Comparable<?>> Range<C> atMost(C endpoint) {
246     return create(Cut.<C>belowAll(), Cut.aboveValue(endpoint));
247   }
248 
249   /**
250    * Returns a range with no lower bound up to the given endpoint, which may be
251    * either inclusive (closed) or exclusive (open).
252    *
253    * @since 14.0
254    */
upTo( C endpoint, BoundType boundType)255   public static <C extends Comparable<?>> Range<C> upTo(
256       C endpoint, BoundType boundType) {
257     switch (boundType) {
258       case OPEN:
259         return lessThan(endpoint);
260       case CLOSED:
261         return atMost(endpoint);
262       default:
263         throw new AssertionError();
264     }
265   }
266 
267   /**
268    * Returns a range that contains all values strictly greater than {@code
269    * endpoint}.
270    *
271    * @since 14.0
272    */
greaterThan(C endpoint)273   public static <C extends Comparable<?>> Range<C> greaterThan(C endpoint) {
274     return create(Cut.aboveValue(endpoint), Cut.<C>aboveAll());
275   }
276 
277   /**
278    * Returns a range that contains all values greater than or equal to
279    * {@code endpoint}.
280    *
281    * @since 14.0
282    */
atLeast(C endpoint)283   public static <C extends Comparable<?>> Range<C> atLeast(C endpoint) {
284     return create(Cut.belowValue(endpoint), Cut.<C>aboveAll());
285   }
286 
287   /**
288    * Returns a range from the given endpoint, which may be either inclusive
289    * (closed) or exclusive (open), with no upper bound.
290    *
291    * @since 14.0
292    */
downTo( C endpoint, BoundType boundType)293   public static <C extends Comparable<?>> Range<C> downTo(
294       C endpoint, BoundType boundType) {
295     switch (boundType) {
296       case OPEN:
297         return greaterThan(endpoint);
298       case CLOSED:
299         return atLeast(endpoint);
300       default:
301         throw new AssertionError();
302     }
303   }
304 
305   private static final Range<Comparable> ALL =
306       new Range<Comparable>(Cut.belowAll(), Cut.aboveAll());
307 
308   /**
309    * Returns a range that contains every value of type {@code C}.
310    *
311    * @since 14.0
312    */
313   @SuppressWarnings("unchecked")
all()314   public static <C extends Comparable<?>> Range<C> all() {
315     return (Range) ALL;
316   }
317 
318   /**
319    * Returns a range that {@linkplain Range#contains(Comparable) contains} only
320    * the given value. The returned range is {@linkplain BoundType#CLOSED closed}
321    * on both ends.
322    *
323    * @since 14.0
324    */
singleton(C value)325   public static <C extends Comparable<?>> Range<C> singleton(C value) {
326     return closed(value, value);
327   }
328 
329    /**
330    * Returns the minimal range that
331    * {@linkplain Range#contains(Comparable) contains} all of the given values.
332    * The returned range is {@linkplain BoundType#CLOSED closed} on both ends.
333    *
334    * @throws ClassCastException if the parameters are not <i>mutually
335    *     comparable</i>
336    * @throws NoSuchElementException if {@code values} is empty
337    * @throws NullPointerException if any of {@code values} is null
338    * @since 14.0
339    */
encloseAll( Iterable<C> values)340   public static <C extends Comparable<?>> Range<C> encloseAll(
341       Iterable<C> values) {
342     checkNotNull(values);
343     if (values instanceof ContiguousSet) {
344       return ((ContiguousSet<C>) values).range();
345     }
346     Iterator<C> valueIterator = values.iterator();
347     C min = checkNotNull(valueIterator.next());
348     C max = min;
349     while (valueIterator.hasNext()) {
350       C value = checkNotNull(valueIterator.next());
351       min = Ordering.natural().min(min, value);
352       max = Ordering.natural().max(max, value);
353     }
354     return closed(min, max);
355   }
356 
357   final Cut<C> lowerBound;
358   final Cut<C> upperBound;
359 
Range(Cut<C> lowerBound, Cut<C> upperBound)360   private Range(Cut<C> lowerBound, Cut<C> upperBound) {
361     if (lowerBound.compareTo(upperBound) > 0 || lowerBound == Cut.<C>aboveAll()
362         || upperBound == Cut.<C>belowAll()) {
363       throw new IllegalArgumentException("Invalid range: " + toString(lowerBound, upperBound));
364     }
365     this.lowerBound = checkNotNull(lowerBound);
366     this.upperBound = checkNotNull(upperBound);
367   }
368 
369   /**
370    * Returns {@code true} if this range has a lower endpoint.
371    */
hasLowerBound()372   public boolean hasLowerBound() {
373     return lowerBound != Cut.belowAll();
374   }
375 
376   /**
377    * Returns the lower endpoint of this range.
378    *
379    * @throws IllegalStateException if this range is unbounded below (that is, {@link
380    *     #hasLowerBound()} returns {@code false})
381    */
lowerEndpoint()382   public C lowerEndpoint() {
383     return lowerBound.endpoint();
384   }
385 
386   /**
387    * Returns the type of this range's lower bound: {@link BoundType#CLOSED} if the range includes
388    * its lower endpoint, {@link BoundType#OPEN} if it does not.
389    *
390    * @throws IllegalStateException if this range is unbounded below (that is, {@link
391    *     #hasLowerBound()} returns {@code false})
392    */
lowerBoundType()393   public BoundType lowerBoundType() {
394     return lowerBound.typeAsLowerBound();
395   }
396 
397   /**
398    * Returns {@code true} if this range has an upper endpoint.
399    */
hasUpperBound()400   public boolean hasUpperBound() {
401     return upperBound != Cut.aboveAll();
402   }
403 
404   /**
405    * Returns the upper endpoint of this range.
406    *
407    * @throws IllegalStateException if this range is unbounded above (that is, {@link
408    *     #hasUpperBound()} returns {@code false})
409    */
upperEndpoint()410   public C upperEndpoint() {
411     return upperBound.endpoint();
412   }
413 
414   /**
415    * Returns the type of this range's upper bound: {@link BoundType#CLOSED} if the range includes
416    * its upper endpoint, {@link BoundType#OPEN} if it does not.
417    *
418    * @throws IllegalStateException if this range is unbounded above (that is, {@link
419    *     #hasUpperBound()} returns {@code false})
420    */
upperBoundType()421   public BoundType upperBoundType() {
422     return upperBound.typeAsUpperBound();
423   }
424 
425   /**
426    * Returns {@code true} if this range is of the form {@code [v..v)} or {@code (v..v]}. (This does
427    * not encompass ranges of the form {@code (v..v)}, because such ranges are <i>invalid</i> and
428    * can't be constructed at all.)
429    *
430    * <p>Note that certain discrete ranges such as the integer range {@code (3..4)} are <b>not</b>
431    * considered empty, even though they contain no actual values.  In these cases, it may be
432    * helpful to preprocess ranges with {@link #canonical(DiscreteDomain)}.
433    */
isEmpty()434   public boolean isEmpty() {
435     return lowerBound.equals(upperBound);
436   }
437 
438   /**
439    * Returns {@code true} if {@code value} is within the bounds of this range. For example, on the
440    * range {@code [0..2)}, {@code contains(1)} returns {@code true}, while {@code contains(2)}
441    * returns {@code false}.
442    */
contains(C value)443   public boolean contains(C value) {
444     checkNotNull(value);
445     // let this throw CCE if there is some trickery going on
446     return lowerBound.isLessThan(value) && !upperBound.isLessThan(value);
447   }
448 
449   /**
450    * @deprecated Provided only to satisfy the {@link Predicate} interface; use {@link #contains}
451    *     instead.
452    */
453   @Deprecated
454   @Override
apply(C input)455   public boolean apply(C input) {
456     return contains(input);
457   }
458 
459   /**
460    * Returns {@code true} if every element in {@code values} is {@linkplain #contains contained} in
461    * this range.
462    */
containsAll(Iterable<? extends C> values)463   public boolean containsAll(Iterable<? extends C> values) {
464     if (Iterables.isEmpty(values)) {
465       return true;
466     }
467 
468     // this optimizes testing equality of two range-backed sets
469     if (values instanceof SortedSet) {
470       SortedSet<? extends C> set = cast(values);
471       Comparator<?> comparator = set.comparator();
472       if (Ordering.natural().equals(comparator) || comparator == null) {
473         return contains(set.first()) && contains(set.last());
474       }
475     }
476 
477     for (C value : values) {
478       if (!contains(value)) {
479         return false;
480       }
481     }
482     return true;
483   }
484 
485   /**
486    * Returns {@code true} if the bounds of {@code other} do not extend outside the bounds of this
487    * range. Examples:
488    *
489    * <ul>
490    * <li>{@code [3..6]} encloses {@code [4..5]}
491    * <li>{@code (3..6)} encloses {@code (3..6)}
492    * <li>{@code [3..6]} encloses {@code [4..4)} (even though the latter is empty)
493    * <li>{@code (3..6]} does not enclose {@code [3..6]}
494    * <li>{@code [4..5]} does not enclose {@code (3..6)} (even though it contains every value
495    *     contained by the latter range)
496    * <li>{@code [3..6]} does not enclose {@code (1..1]} (even though it contains every value
497    *     contained by the latter range)
498    * </ul>
499    *
500    * <p>Note that if {@code a.encloses(b)}, then {@code b.contains(v)} implies
501    * {@code a.contains(v)}, but as the last two examples illustrate, the converse is not always
502    * true.
503    *
504    * <p>Being reflexive, antisymmetric and transitive, the {@code encloses} relation defines a
505    * <i>partial order</i> over ranges. There exists a unique {@linkplain Range#all maximal} range
506    * according to this relation, and also numerous {@linkplain #isEmpty minimal} ranges. Enclosure
507    * also implies {@linkplain #isConnected connectedness}.
508    */
encloses(Range<C> other)509   public boolean encloses(Range<C> other) {
510     return lowerBound.compareTo(other.lowerBound) <= 0
511         && upperBound.compareTo(other.upperBound) >= 0;
512   }
513 
514   /**
515    * Returns {@code true} if there exists a (possibly empty) range which is {@linkplain #encloses
516    * enclosed} by both this range and {@code other}.
517    *
518    * <p>For example,
519    * <ul>
520    * <li>{@code [2, 4)} and {@code [5, 7)} are not connected
521    * <li>{@code [2, 4)} and {@code [3, 5)} are connected, because both enclose {@code [3, 4)}
522    * <li>{@code [2, 4)} and {@code [4, 6)} are connected, because both enclose the empty range
523    *     {@code [4, 4)}
524    * </ul>
525    *
526    * <p>Note that this range and {@code other} have a well-defined {@linkplain #span union} and
527    * {@linkplain #intersection intersection} (as a single, possibly-empty range) if and only if this
528    * method returns {@code true}.
529    *
530    * <p>The connectedness relation is both reflexive and symmetric, but does not form an {@linkplain
531    * Equivalence equivalence relation} as it is not transitive.
532    *
533    * <p>Note that certain discrete ranges are not considered connected, even though there are no
534    * elements "between them."  For example, {@code [3, 5]} is not considered connected to {@code
535    * [6, 10]}.  In these cases, it may be desirable for both input ranges to be preprocessed with
536    * {@link #canonical(DiscreteDomain)} before testing for connectedness.
537    */
isConnected(Range<C> other)538   public boolean isConnected(Range<C> other) {
539     return lowerBound.compareTo(other.upperBound) <= 0
540         && other.lowerBound.compareTo(upperBound) <= 0;
541   }
542 
543   /**
544    * Returns the maximal range {@linkplain #encloses enclosed} by both this range and {@code
545    * connectedRange}, if such a range exists.
546    *
547    * <p>For example, the intersection of {@code [1..5]} and {@code (3..7)} is {@code (3..5]}. The
548    * resulting range may be empty; for example, {@code [1..5)} intersected with {@code [5..7)}
549    * yields the empty range {@code [5..5)}.
550    *
551    * <p>The intersection exists if and only if the two ranges are {@linkplain #isConnected
552    * connected}.
553    *
554    * <p>The intersection operation is commutative, associative and idempotent, and its identity
555    * element is {@link Range#all}).
556    *
557    * @throws IllegalArgumentException if {@code isConnected(connectedRange)} is {@code false}
558    */
intersection(Range<C> connectedRange)559   public Range<C> intersection(Range<C> connectedRange) {
560     int lowerCmp = lowerBound.compareTo(connectedRange.lowerBound);
561     int upperCmp = upperBound.compareTo(connectedRange.upperBound);
562     if (lowerCmp >= 0 && upperCmp <= 0) {
563       return this;
564     } else if (lowerCmp <= 0 && upperCmp >= 0) {
565       return connectedRange;
566     } else {
567       Cut<C> newLower = (lowerCmp >= 0) ? lowerBound : connectedRange.lowerBound;
568       Cut<C> newUpper = (upperCmp <= 0) ? upperBound : connectedRange.upperBound;
569       return create(newLower, newUpper);
570     }
571   }
572 
573   /**
574    * Returns the minimal range that {@linkplain #encloses encloses} both this range and {@code
575    * other}. For example, the span of {@code [1..3]} and {@code (5..7)} is {@code [1..7)}.
576    *
577    * <p><i>If</i> the input ranges are {@linkplain #isConnected connected}, the returned range can
578    * also be called their <i>union</i>. If they are not, note that the span might contain values
579    * that are not contained in either input range.
580    *
581    * <p>Like {@link #intersection(Range) intersection}, this operation is commutative, associative
582    * and idempotent. Unlike it, it is always well-defined for any two input ranges.
583    */
span(Range<C> other)584   public Range<C> span(Range<C> other) {
585     int lowerCmp = lowerBound.compareTo(other.lowerBound);
586     int upperCmp = upperBound.compareTo(other.upperBound);
587     if (lowerCmp <= 0 && upperCmp >= 0) {
588       return this;
589     } else if (lowerCmp >= 0 && upperCmp <= 0) {
590       return other;
591     } else {
592       Cut<C> newLower = (lowerCmp <= 0) ? lowerBound : other.lowerBound;
593       Cut<C> newUpper = (upperCmp >= 0) ? upperBound : other.upperBound;
594       return create(newLower, newUpper);
595     }
596   }
597 
598   /**
599    * Returns the canonical form of this range in the given domain. The canonical form has the
600    * following properties:
601    *
602    * <ul>
603    * <li>equivalence: {@code a.canonical().contains(v) == a.contains(v)} for all {@code v} (in other
604    *     words, {@code ContiguousSet.create(a.canonical(domain), domain).equals(
605    *     ContiguousSet.create(a, domain))}
606    * <li>uniqueness: unless {@code a.isEmpty()},
607    *     {@code ContiguousSet.create(a, domain).equals(ContiguousSet.create(b, domain))} implies
608    *     {@code a.canonical(domain).equals(b.canonical(domain))}
609    * <li>idempotence: {@code a.canonical(domain).canonical(domain).equals(a.canonical(domain))}
610    * </ul>
611    *
612    * <p>Furthermore, this method guarantees that the range returned will be one of the following
613    * canonical forms:
614    *
615    * <ul>
616    * <li>[start..end)
617    * <li>[start..+∞)
618    * <li>(-∞..end) (only if type {@code C} is unbounded below)
619    * <li>(-∞..+∞) (only if type {@code C} is unbounded below)
620    * </ul>
621    */
canonical(DiscreteDomain<C> domain)622   public Range<C> canonical(DiscreteDomain<C> domain) {
623     checkNotNull(domain);
624     Cut<C> lower = lowerBound.canonical(domain);
625     Cut<C> upper = upperBound.canonical(domain);
626     return (lower == lowerBound && upper == upperBound) ? this : create(lower, upper);
627   }
628 
629   /**
630    * Returns {@code true} if {@code object} is a range having the same endpoints and bound types as
631    * this range. Note that discrete ranges such as {@code (1..4)} and {@code [2..3]} are <b>not</b>
632    * equal to one another, despite the fact that they each contain precisely the same set of values.
633    * Similarly, empty ranges are not equal unless they have exactly the same representation, so
634    * {@code [3..3)}, {@code (3..3]}, {@code (4..4]} are all unequal.
635    */
equals(@ullable Object object)636   @Override public boolean equals(@Nullable Object object) {
637     if (object instanceof Range) {
638       Range<?> other = (Range<?>) object;
639       return lowerBound.equals(other.lowerBound)
640           && upperBound.equals(other.upperBound);
641     }
642     return false;
643   }
644 
645   /** Returns a hash code for this range. */
hashCode()646   @Override public int hashCode() {
647     return lowerBound.hashCode() * 31 + upperBound.hashCode();
648   }
649 
650   /**
651    * Returns a string representation of this range, such as {@code "[3..5)"} (other examples are
652    * listed in the class documentation).
653    */
toString()654   @Override public String toString() {
655     return toString(lowerBound, upperBound);
656   }
657 
toString(Cut<?> lowerBound, Cut<?> upperBound)658   private static String toString(Cut<?> lowerBound, Cut<?> upperBound) {
659     StringBuilder sb = new StringBuilder(16);
660     lowerBound.describeAsLowerBound(sb);
661     sb.append('\u2025');
662     upperBound.describeAsUpperBound(sb);
663     return sb.toString();
664   }
665 
666   /**
667    * Used to avoid http://bugs.sun.com/view_bug.do?bug_id=6558557
668    */
cast(Iterable<T> iterable)669   private static <T> SortedSet<T> cast(Iterable<T> iterable) {
670     return (SortedSet<T>) iterable;
671   }
672 
readResolve()673   Object readResolve() {
674     if (this.equals(ALL)) {
675       return all();
676     } else {
677       return this;
678     }
679   }
680 
681   @SuppressWarnings("unchecked") // this method may throw CCE
compareOrThrow(Comparable left, Comparable right)682   static int compareOrThrow(Comparable left, Comparable right) {
683     return left.compareTo(right);
684   }
685 
686   private static final long serialVersionUID = 0;
687 }
688