Coverage Summary for Class: Cut (com.google.common.collect)

Class Method, % Line, %
Cut 77.8% (7/9) 78.3% (18/23)
Cut$1 0% (0/1) 0% (0/1)
Cut$AboveAll 35.3% (6/17) 42.1% (8/19)
Cut$AboveValue 23.1% (3/13) 20% (5/25)
Cut$BelowAll 33.3% (6/18) 36.4% (8/22)
Cut$BelowValue 25% (3/12) 21.7% (5/23)
Total 35.7% (25/70) 38.9% (44/113)


1 /* 2  * Copyright (C) 2009 The Guava Authors 3  * 4  * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except 5  * in compliance with the License. You may obtain a copy of the License at 6  * 7  * http://www.apache.org/licenses/LICENSE-2.0 8  * 9  * Unless required by applicable law or agreed to in writing, software distributed under the License 10  * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express 11  * or implied. See the License for the specific language governing permissions and limitations under 12  * the License. 13  */ 14  15 package com.google.common.collect; 16  17 import static com.google.common.base.Preconditions.checkNotNull; 18  19 import com.google.common.annotations.GwtCompatible; 20 import com.google.common.primitives.Booleans; 21 import java.io.Serializable; 22 import java.util.NoSuchElementException; 23 import org.checkerframework.checker.nullness.qual.Nullable; 24  25 /** 26  * Implementation detail for the internal structure of {@link Range} instances. Represents a unique 27  * way of "cutting" a "number line" (actually of instances of type {@code C}, not necessarily 28  * "numbers") into two sections; this can be done below a certain value, above a certain value, 29  * below all values or above all values. With this object defined in this way, an interval can 30  * always be represented by a pair of {@code Cut} instances. 31  * 32  * @author Kevin Bourrillion 33  */ 34 @GwtCompatible 35 abstract class Cut<C extends Comparable> implements Comparable<Cut<C>>, Serializable { 36  final @Nullable C endpoint; 37  38  Cut(@Nullable C endpoint) { 39  this.endpoint = endpoint; 40  } 41  42  abstract boolean isLessThan(C value); 43  44  abstract BoundType typeAsLowerBound(); 45  46  abstract BoundType typeAsUpperBound(); 47  48  abstract Cut<C> withLowerBoundType(BoundType boundType, DiscreteDomain<C> domain); 49  50  abstract Cut<C> withUpperBoundType(BoundType boundType, DiscreteDomain<C> domain); 51  52  abstract void describeAsLowerBound(StringBuilder sb); 53  54  abstract void describeAsUpperBound(StringBuilder sb); 55  56  abstract C leastValueAbove(DiscreteDomain<C> domain); 57  58  abstract C greatestValueBelow(DiscreteDomain<C> domain); 59  60  /* 61  * The canonical form is a BelowValue cut whenever possible, otherwise ABOVE_ALL, or 62  * (only in the case of types that are unbounded below) BELOW_ALL. 63  */ 64  Cut<C> canonical(DiscreteDomain<C> domain) { 65  return this; 66  } 67  68  // note: overridden by {BELOW,ABOVE}_ALL 69  @Override 70  public int compareTo(Cut<C> that) { 71  if (that == belowAll()) { 72  return 1; 73  } 74  if (that == aboveAll()) { 75  return -1; 76  } 77  int result = Range.compareOrThrow(endpoint, that.endpoint); 78  if (result != 0) { 79  return result; 80  } 81  // same value. below comes before above 82  return Booleans.compare(this instanceof AboveValue, that instanceof AboveValue); 83  } 84  85  C endpoint() { 86  return endpoint; 87  } 88  89  @SuppressWarnings("unchecked") // catching CCE 90  @Override 91  public boolean equals(Object obj) { 92  if (obj instanceof Cut) { 93  // It might not really be a Cut<C>, but we'll catch a CCE if it's not 94  Cut<C> that = (Cut<C>) obj; 95  try { 96  int compareResult = compareTo(that); 97  return compareResult == 0; 98  } catch (ClassCastException ignored) { 99  } 100  } 101  return false; 102  } 103  104  // Prevent "missing hashCode" warning by explicitly forcing subclasses implement it 105  @Override 106  public abstract int hashCode(); 107  108  /* 109  * The implementation neither produces nor consumes any non-null instance of type C, so 110  * casting the type parameter is safe. 111  */ 112  @SuppressWarnings("unchecked") 113  static <C extends Comparable> Cut<C> belowAll() { 114  return (Cut<C>) BelowAll.INSTANCE; 115  } 116  117  private static final long serialVersionUID = 0; 118  119  private static final class BelowAll extends Cut<Comparable<?>> { 120  private static final BelowAll INSTANCE = new BelowAll(); 121  122  private BelowAll() { 123  super(null); 124  } 125  126  @Override 127  Comparable<?> endpoint() { 128  throw new IllegalStateException("range unbounded on this side"); 129  } 130  131  @Override 132  boolean isLessThan(Comparable<?> value) { 133  return true; 134  } 135  136  @Override 137  BoundType typeAsLowerBound() { 138  throw new IllegalStateException(); 139  } 140  141  @Override 142  BoundType typeAsUpperBound() { 143  throw new AssertionError("this statement should be unreachable"); 144  } 145  146  @Override 147  Cut<Comparable<?>> withLowerBoundType( 148  BoundType boundType, DiscreteDomain<Comparable<?>> domain) { 149  throw new IllegalStateException(); 150  } 151  152  @Override 153  Cut<Comparable<?>> withUpperBoundType( 154  BoundType boundType, DiscreteDomain<Comparable<?>> domain) { 155  throw new AssertionError("this statement should be unreachable"); 156  } 157  158  @Override 159  void describeAsLowerBound(StringBuilder sb) { 160  sb.append("(-\u221e"); 161  } 162  163  @Override 164  void describeAsUpperBound(StringBuilder sb) { 165  throw new AssertionError(); 166  } 167  168  @Override 169  Comparable<?> leastValueAbove(DiscreteDomain<Comparable<?>> domain) { 170  return domain.minValue(); 171  } 172  173  @Override 174  Comparable<?> greatestValueBelow(DiscreteDomain<Comparable<?>> domain) { 175  throw new AssertionError(); 176  } 177  178  @Override 179  Cut<Comparable<?>> canonical(DiscreteDomain<Comparable<?>> domain) { 180  try { 181  return Cut.<Comparable<?>>belowValue(domain.minValue()); 182  } catch (NoSuchElementException e) { 183  return this; 184  } 185  } 186  187  @Override 188  public int compareTo(Cut<Comparable<?>> o) { 189  return (o == this) ? 0 : -1; 190  } 191  192  @Override 193  public int hashCode() { 194  return System.identityHashCode(this); 195  } 196  197  @Override 198  public String toString() { 199  return "-\u221e"; 200  } 201  202  private Object readResolve() { 203  return INSTANCE; 204  } 205  206  private static final long serialVersionUID = 0; 207  } 208  209  /* 210  * The implementation neither produces nor consumes any non-null instance of 211  * type C, so casting the type parameter is safe. 212  */ 213  @SuppressWarnings("unchecked") 214  static <C extends Comparable> Cut<C> aboveAll() { 215  return (Cut<C>) AboveAll.INSTANCE; 216  } 217  218  private static final class AboveAll extends Cut<Comparable<?>> { 219  private static final AboveAll INSTANCE = new AboveAll(); 220  221  private AboveAll() { 222  super(null); 223  } 224  225  @Override 226  Comparable<?> endpoint() { 227  throw new IllegalStateException("range unbounded on this side"); 228  } 229  230  @Override 231  boolean isLessThan(Comparable<?> value) { 232  return false; 233  } 234  235  @Override 236  BoundType typeAsLowerBound() { 237  throw new AssertionError("this statement should be unreachable"); 238  } 239  240  @Override 241  BoundType typeAsUpperBound() { 242  throw new IllegalStateException(); 243  } 244  245  @Override 246  Cut<Comparable<?>> withLowerBoundType( 247  BoundType boundType, DiscreteDomain<Comparable<?>> domain) { 248  throw new AssertionError("this statement should be unreachable"); 249  } 250  251  @Override 252  Cut<Comparable<?>> withUpperBoundType( 253  BoundType boundType, DiscreteDomain<Comparable<?>> domain) { 254  throw new IllegalStateException(); 255  } 256  257  @Override 258  void describeAsLowerBound(StringBuilder sb) { 259  throw new AssertionError(); 260  } 261  262  @Override 263  void describeAsUpperBound(StringBuilder sb) { 264  sb.append("+\u221e)"); 265  } 266  267  @Override 268  Comparable<?> leastValueAbove(DiscreteDomain<Comparable<?>> domain) { 269  throw new AssertionError(); 270  } 271  272  @Override 273  Comparable<?> greatestValueBelow(DiscreteDomain<Comparable<?>> domain) { 274  return domain.maxValue(); 275  } 276  277  @Override 278  public int compareTo(Cut<Comparable<?>> o) { 279  return (o == this) ? 0 : 1; 280  } 281  282  @Override 283  public int hashCode() { 284  return System.identityHashCode(this); 285  } 286  287  @Override 288  public String toString() { 289  return "+\u221e"; 290  } 291  292  private Object readResolve() { 293  return INSTANCE; 294  } 295  296  private static final long serialVersionUID = 0; 297  } 298  299  static <C extends Comparable> Cut<C> belowValue(C endpoint) { 300  return new BelowValue<C>(endpoint); 301  } 302  303  private static final class BelowValue<C extends Comparable> extends Cut<C> { 304  BelowValue(C endpoint) { 305  super(checkNotNull(endpoint)); 306  } 307  308  @Override 309  boolean isLessThan(C value) { 310  return Range.compareOrThrow(endpoint, value) <= 0; 311  } 312  313  @Override 314  BoundType typeAsLowerBound() { 315  return BoundType.CLOSED; 316  } 317  318  @Override 319  BoundType typeAsUpperBound() { 320  return BoundType.OPEN; 321  } 322  323  @Override 324  Cut<C> withLowerBoundType(BoundType boundType, DiscreteDomain<C> domain) { 325  switch (boundType) { 326  case CLOSED: 327  return this; 328  case OPEN: 329  @Nullable C previous = domain.previous(endpoint); 330  return (previous == null) ? Cut.<C>belowAll() : new AboveValue<C>(previous); 331  default: 332  throw new AssertionError(); 333  } 334  } 335  336  @Override 337  Cut<C> withUpperBoundType(BoundType boundType, DiscreteDomain<C> domain) { 338  switch (boundType) { 339  case CLOSED: 340  @Nullable C previous = domain.previous(endpoint); 341  return (previous == null) ? Cut.<C>aboveAll() : new AboveValue<C>(previous); 342  case OPEN: 343  return this; 344  default: 345  throw new AssertionError(); 346  } 347  } 348  349  @Override 350  void describeAsLowerBound(StringBuilder sb) { 351  sb.append('[').append(endpoint); 352  } 353  354  @Override 355  void describeAsUpperBound(StringBuilder sb) { 356  sb.append(endpoint).append(')'); 357  } 358  359  @Override 360  C leastValueAbove(DiscreteDomain<C> domain) { 361  return endpoint; 362  } 363  364  @Override 365  C greatestValueBelow(DiscreteDomain<C> domain) { 366  return domain.previous(endpoint); 367  } 368  369  @Override 370  public int hashCode() { 371  return endpoint.hashCode(); 372  } 373  374  @Override 375  public String toString() { 376  return "\\" + endpoint + "/"; 377  } 378  379  private static final long serialVersionUID = 0; 380  } 381  382  static <C extends Comparable> Cut<C> aboveValue(C endpoint) { 383  return new AboveValue<C>(endpoint); 384  } 385  386  private static final class AboveValue<C extends Comparable> extends Cut<C> { 387  AboveValue(C endpoint) { 388  super(checkNotNull(endpoint)); 389  } 390  391  @Override 392  boolean isLessThan(C value) { 393  return Range.compareOrThrow(endpoint, value) < 0; 394  } 395  396  @Override 397  BoundType typeAsLowerBound() { 398  return BoundType.OPEN; 399  } 400  401  @Override 402  BoundType typeAsUpperBound() { 403  return BoundType.CLOSED; 404  } 405  406  @Override 407  Cut<C> withLowerBoundType(BoundType boundType, DiscreteDomain<C> domain) { 408  switch (boundType) { 409  case OPEN: 410  return this; 411  case CLOSED: 412  @Nullable C next = domain.next(endpoint); 413  return (next == null) ? Cut.<C>belowAll() : belowValue(next); 414  default: 415  throw new AssertionError(); 416  } 417  } 418  419  @Override 420  Cut<C> withUpperBoundType(BoundType boundType, DiscreteDomain<C> domain) { 421  switch (boundType) { 422  case OPEN: 423  @Nullable C next = domain.next(endpoint); 424  return (next == null) ? Cut.<C>aboveAll() : belowValue(next); 425  case CLOSED: 426  return this; 427  default: 428  throw new AssertionError(); 429  } 430  } 431  432  @Override 433  void describeAsLowerBound(StringBuilder sb) { 434  sb.append('(').append(endpoint); 435  } 436  437  @Override 438  void describeAsUpperBound(StringBuilder sb) { 439  sb.append(endpoint).append(']'); 440  } 441  442  @Override 443  C leastValueAbove(DiscreteDomain<C> domain) { 444  return domain.next(endpoint); 445  } 446  447  @Override 448  C greatestValueBelow(DiscreteDomain<C> domain) { 449  return endpoint; 450  } 451  452  @Override 453  Cut<C> canonical(DiscreteDomain<C> domain) { 454  C next = leastValueAbove(domain); 455  return (next != null) ? belowValue(next) : Cut.<C>aboveAll(); 456  } 457  458  @Override 459  public int hashCode() { 460  return ~endpoint.hashCode(); 461  } 462  463  @Override 464  public String toString() { 465  return "/" + endpoint + "\\"; 466  } 467  468  private static final long serialVersionUID = 0; 469  } 470 }