source: trunk/src/org/expeditee/core/Range.java@ 1441

Last change on this file since 1441 was 1097, checked in by davidb, 6 years ago

Newly structured files from Corey's work on logic/graphics separation

File size: 4.0 KB
Line 
1package org.expeditee.core;
2
3/**
4 * Represents a range of ordered values defined by a start and end value.
5 * Range can be open or closed at each end (i.e. the start and end points
6 * can be considered inside or outside the range). Either/both ends can
7 * also be null representing no lower/upper bound. If the upper bound is
8 * lower than the lower bound, the range is an outside range (where points
9 * outside the two bounds are considered contained by the range).
10 *
11 * @author cts16
12 *
13 * @param <T> The type of values in this range. Must have an order and
14 * therefore must implement Comparable.
15 */
16public class Range<T extends Comparable<T>> {
17
18 /** The lowest value in the range. If null, then the range has no lower bound. */
19 public T lowerBound;
20 /** The highest value in the range. If null, then the range has no upper bound. */
21 public T upperBound;
22 /** Whether the lowest value is open or closed (outside or inside the range respectively). */
23 public boolean lowerBoundClosed;
24 /** Whether the end value is open or closed. */
25 public boolean upperBoundClosed;
26
27 /** Standard constructor considers the lower bound closed and upper bound open. */
28 public Range(T lowerBound, T upperBound)
29 {
30 this(lowerBound, upperBound, true, false);
31 }
32
33 /** Standard constructor. */
34 public Range(T lowerBound, T upperBound, boolean lowerBoundClosed, boolean upperBoundClosed)
35 {
36 this.lowerBound = lowerBound;
37 this.upperBound = upperBound;
38 this.lowerBoundClosed = lowerBoundClosed;
39 this.upperBoundClosed = upperBoundClosed;
40 }
41
42 /** Whether this range contains the given value. */
43 public boolean contains(T t)
44 {
45 // A null value is never inside the bound
46 if (t == null) return false;
47
48 // See how the value compares to the two boundaries
49 int compStart = lowerBound != null ? t.compareTo(lowerBound) : 0;
50 int compEnd = upperBound != null ? t.compareTo(upperBound) : 0;
51
52 // See if this is an outside range
53 boolean outsideRange = lowerBound != null && upperBound != null && upperBound.compareTo(lowerBound) < 0;
54
55 // Make sure it's above the lower bound
56 boolean aboveLowerBound = (lowerBound == null) || // No lower bound, or...
57 (compStart > 0) || // Strictly above the lower bound, or...
58 (compStart == 0 && lowerBoundClosed); // On the lower bound but it's closed
59
60 // Make sure it's below the upper bound
61 boolean belowUpperBound = (upperBound == null) || // No upper bound, or...
62 (compEnd < 0) || // Strictly below the upper bound, or...
63 (compEnd == 0 && upperBoundClosed); // On the upper bound but it's closed
64
65 // In an inside range if we are below the upper bound and above the lower bound,
66 // in an outside range if we are below the upper bound or above the lower bound
67 return (aboveLowerBound && belowUpperBound) ||
68 (outsideRange && (aboveLowerBound || belowUpperBound));
69 }
70
71 /** Creates an inside range when the order of the two ends is unknown. Both ends are considered closed. */
72 public static <T extends Comparable<T>> Range<T> insideRangeFromUncertainEnds(T anEnd, T anotherEnd)
73 {
74 return insideRangeFromUncertainEnds(anEnd, anotherEnd, true, true);
75 }
76
77 /** Creates an inside range when the order of the two ends is unknown. */
78 public static <T extends Comparable<T>> Range<T> insideRangeFromUncertainEnds(T anEnd, T anotherEnd, boolean anEndClosed, boolean anotherEndClosed)
79 {
80 // If both ends are null then ordering doesn't matter
81 if (anEnd == null && anotherEnd == null) return new Range<T>(anEnd, anotherEnd, anEndClosed, anotherEndClosed);
82
83 // Can't determine order of a single end
84 if (anEnd == null || anotherEnd == null) return null;
85
86 // Put the two ends in order (so anEnd is lower than anotherEnd),
87 // keeping the respective closed flags with their ends
88 if (anEnd.compareTo(anotherEnd) > 0) {
89 T temp = anEnd;
90 anEnd = anotherEnd;
91 anotherEnd = temp;
92 boolean bTemp = anEndClosed;
93 anEndClosed = anotherEndClosed;
94 anotherEndClosed = bTemp;
95 }
96
97 // Create a range from the reorder ends
98 return new Range<T>(anEnd, anotherEnd, anEndClosed, anotherEndClosed);
99 }
100}
Note: See TracBrowser for help on using the repository browser.