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 }