1 18 19 package org.sablecc.sablecc.alphabet; 20 21 import org.sablecc.sablecc.exception.InternalException; 22 23 30 public final class Interval<T extends Comparable <? super T>> 31 implements Comparable <Interval<T>> { 32 33 34 private final T lowerBound; 35 36 37 private final T upperBound; 38 39 40 private final AdjacencyRealm<T> adjacencyRealm; 41 42 43 private Integer hashCode; 44 45 49 private String toString; 50 51 66 Interval( 67 T lowerBound, 68 T upperBound, 69 AdjacencyRealm<T> adjacencyRealm) { 70 71 if (lowerBound == null) { 72 throw new InternalException("lower bound may not be null"); 73 } 74 75 if (upperBound == null) { 76 throw new InternalException("upper bound may not be null"); 77 } 78 79 if (adjacencyRealm == null) { 80 throw new InternalException("adjacency realm may not be null"); 81 } 82 83 if (lowerBound.compareTo(upperBound) > 0) { 84 throw new InternalException( 85 "lower bound must be smaller or equal to upper bound"); 86 } 87 88 this.lowerBound = lowerBound; 89 this.upperBound = upperBound; 90 this.adjacencyRealm = adjacencyRealm; 91 } 92 93 102 Interval( 103 T bound, 104 AdjacencyRealm<T> adjacencyRealm) { 105 106 this(bound, bound, adjacencyRealm); 107 } 108 109 114 public T getLowerBound() { 115 116 return this.lowerBound; 117 } 118 119 124 public T getUpperBound() { 125 126 return this.upperBound; 127 } 128 129 134 public AdjacencyRealm<T> getAdjacencyRealm() { 135 136 return this.adjacencyRealm; 137 } 138 139 149 @Override 150 public boolean equals( 151 Object obj) { 152 153 if (this == obj) { 154 return true; 155 } 156 157 if (obj == null) { 158 return false; 159 } 160 161 if (getClass() != obj.getClass()) { 162 return false; 163 } 164 165 Interval interval = (Interval) obj; 166 167 return this.lowerBound.equals(interval.lowerBound) 168 && this.upperBound.equals(interval.upperBound) 169 && this.adjacencyRealm == interval.adjacencyRealm; 170 } 171 172 177 @Override 178 public int hashCode() { 179 180 if (this.hashCode == null) { 181 this.hashCode = this.lowerBound.hashCode() * 121 182 + this.upperBound.hashCode() * 11 183 + this.adjacencyRealm.hashCode(); 184 } 185 186 return this.hashCode; 187 } 188 189 194 @Override 195 public String toString() { 196 197 if (this.toString == null) { 198 this.toString = "[" + this.lowerBound + ".." + this.upperBound 199 + "]"; 200 } 201 202 return this.toString; 203 } 204 205 219 public int compareTo( 220 Interval<T> interval) { 221 222 if (this.adjacencyRealm != interval.adjacencyRealm) { 223 throw new InternalException( 224 "cannot compare intervals from distinct realms"); 225 } 226 227 int result = this.lowerBound.compareTo(interval.lowerBound); 228 229 if (result == 0) { 230 result = this.upperBound.compareTo(interval.upperBound); 231 } 232 233 return result; 234 } 235 236 249 public boolean isAdjacentTo( 250 Interval<T> interval) { 251 252 if (interval == null) { 253 throw new InternalException("interval may not be null"); 254 } 255 256 if (this.adjacencyRealm != interval.adjacencyRealm) { 257 throw new InternalException( 258 "cannot test adjacency of intervals from distinct realms"); 259 } 260 261 return this.adjacencyRealm.isAdjacent(this.upperBound, 262 interval.lowerBound); 263 } 264 265 277 public boolean intersects( 278 Interval<T> interval) { 279 280 if (interval == null) { 281 throw new InternalException("interval may not be null"); 282 } 283 284 if (this.adjacencyRealm != interval.adjacencyRealm) { 285 throw new InternalException( 286 "cannot intersect intervals from distinct realms"); 287 } 288 289 return this.lowerBound.compareTo(interval.upperBound) <= 0 290 && this.upperBound.compareTo(interval.lowerBound) >= 0; 291 } 292 293 306 public Interval<T> intersection( 307 Interval<T> interval) { 308 309 if (interval == null) { 310 throw new InternalException("interval may not be null"); 311 } 312 313 if (this.adjacencyRealm != interval.adjacencyRealm) { 314 throw new InternalException( 315 "cannot intersect intervals from distinct realms"); 316 } 317 318 T lowerBound = AdjacencyRealm.max(this.lowerBound, interval.lowerBound); 319 320 T upperBound = AdjacencyRealm.min(this.upperBound, interval.upperBound); 321 322 if (lowerBound.compareTo(upperBound) <= 0) { 323 return new Interval<T>(lowerBound, upperBound, this.adjacencyRealm); 324 } 325 326 return null; 327 } 328 329 343 public Interval<T> mergeWith( 344 Interval<T> interval) { 345 346 if (interval == null) { 347 throw new InternalException("interval may not be null"); 348 } 349 350 if (this.adjacencyRealm != interval.adjacencyRealm) { 351 throw new InternalException( 352 "cannot merge intervals from distinct realms"); 353 } 354 355 if (!isAdjacentTo(interval)) { 356 throw new InternalException("cannot merge non-adjacent intervals"); 357 } 358 359 return new Interval<T>(this.lowerBound, interval.upperBound, 360 this.adjacencyRealm); 361 } 362 363 375 public static <T extends Comparable <? super T>> Interval<T> min( 376 Interval<T> interval1, 377 Interval<T> interval2) { 378 379 if (interval1 == null) { 380 throw new InternalException("interval1 may not be null"); 381 } 382 383 if (interval2 == null) { 384 throw new InternalException("interval2 may not be null"); 385 } 386 387 if (interval1.compareTo(interval2) <= 0) { 388 return interval1; 389 } 390 391 return interval2; 392 } 393 394 406 public static <T extends Comparable <? super T>> Interval<T> max( 407 Interval<T> interval1, 408 Interval<T> interval2) { 409 410 if (interval1 == null) { 411 throw new InternalException("interval1 may not be null"); 412 } 413 414 if (interval2 == null) { 415 throw new InternalException("interval2 may not be null"); 416 } 417 418 if (interval1.compareTo(interval2) >= 0) { 419 return interval1; 420 } 421 422 return interval2; 423 } 424 } 425 | Popular Tags |