internal static bool TryParse <T>(BoundDirection lowerDirection , T lowerValue , T upperValue , BoundDirection upperDirection , out Interval <T> result) { Bound <T> lowerBound, upperBound; if (Bound.TryParse(BoundType.Lower, lowerDirection, lowerValue, out lowerBound) && Bound.TryParse(BoundType.Upper, upperDirection, upperValue, out upperBound)) { return(Interval.TryParse(lowerBound, upperBound, out result)); } result = default(Interval <T>); return(false); }
/// <summary> /// Initializes a new instance of the <see cref="Interval<T>"/> class. /// </summary> /// <param name="lowerBound">The lower bound.</param> /// <param name="upperBound">The upper bound.</param> protected internal Interval(Bound <T> lowerBound , Bound <T> upperBound) { if (lowerBound == null || upperBound == null) { throw new ArgumentNullException("lowerBound or upperBound"); } if (lowerBound > upperBound) { throw new ArgumentException("The lower bound must be lower than or equal the upper bound."); } if (object.Equals(lowerBound.Value, upperBound.Value) && !object.Equals(lowerBound.Direction, upperBound.Direction) && !Bound.IsInfinity(lowerBound.Value)) { throw new ArgumentException("Singleton or empty interval must define the same boundary direction."); } LowerBound = lowerBound; UpperBound = upperBound; }
internal static bool TryParse <T>(Bound <T> lowerBound , Bound <T> upperBound , out Interval <T> result) { result = default(Interval <T>); if (lowerBound == null || upperBound == null || lowerBound > upperBound) { return(false); } if (object.Equals(lowerBound.Value, upperBound.Value) && !object.Equals(lowerBound.Direction, upperBound.Direction) && !Bound.IsInfinity(lowerBound.Value)) { return(false); } result = new Interval <T>(lowerBound, upperBound); return(true); }
/// <summary> /// Initializes a new instance of the <see cref="Period"/> class. /// </summary> /// <param name="lowerBound">The lower bound.</param> /// <param name="upperBound">The upper bound.</param> public Period(Bound <DateTimeOffset?> lowerBound, Bound <DateTimeOffset?> upperBound) : base(lowerBound, upperBound) { }
internal int UnionCompareTo(Bound <T> other) { //perform value comparaison var vCompare = ((Type == BoundType.Upper && Bound.IsInfinity(Value)) || (other.Type == BoundType.Upper && Bound.IsInfinity(other.Value))) ? Comparer <T> .Default.Compare(other.Value, Value) : Comparer <T> .Default.Compare(Value, other.Value); return((vCompare != 0) ? vCompare : (object.Equals(Direction, BoundDirection.Closed) || object.Equals(other.Direction, BoundDirection.Closed)) ? 0 : -1); }
/// <summary> /// Compares this instance to a specified <see cref="Bound<T>"/> and returns an indication of their relative values. /// </summary> /// <param name="other">A <see cref="Bound<T>"/> to compare to this instance.</param> /// <returns> /// A signed number indicating the relative values of this instance and the <paramref name="other"/>. /// <list type="table"> /// <listheader> /// <term>Value Type</term> /// <description>Condition</description> /// </listheader> /// <item> /// <term>Less than zero</term> /// <description>This instance is less than the <paramref name="other"/>.</description> /// </item> /// <item> /// <term>Zero</term> /// <description>This instance is equal to the <paramref name="other"/>.</description> /// </item> /// <item> /// <term>Greater than zero</term> /// <description>This instance is greater than the <paramref name="other"/>.</description> /// </item> ///</list> /// </returns> /// <exception cref="ArgumentNullException"><paramref name="other"/> is null.</exception> public int CompareTo(Bound <T> other) { if (other == null) { throw new ArgumentNullException("other"); } //perform value comparaison var vCompare = ((Type == BoundType.Upper && Bound.IsInfinity(Value)) || (other.Type == BoundType.Upper && Bound.IsInfinity(other.Value))) ? Comparer <T> .Default.Compare(other.Value, Value) : Comparer <T> .Default.Compare(Value, other.Value); //consider value comparaison if (vCompare != 0) { return(vCompare); } else { //perform type comparaison var tCompare = Type.CompareTo(other.Type); if (tCompare != 0) { return(tCompare); } else { //perform direction comparaison return((Type == BoundType.Upper) ? Direction.CompareTo(other.Direction) : other.Direction.CompareTo(Direction)); } } }
/// <summary> /// Overrides the default bound values of <see cref="Interval<T>"/>. /// </summary> /// <param name="lowestValue">The lowest value.</param> /// <param name="upmostValue">The upmost value.</param> public static void OverrideBounds(T lowestValue, T upmostValue) { Bound <T> .OverrideBounds(lowestValue, upmostValue); }
private static IntervalCollection <T> HighUnionOf <T>(Interval <T> a, Interval <T> b) { if (Interval.IsNullOrEmpty(a)) { return(new IntervalCollection <T>(b)); } if (Interval.IsNullOrEmpty(b)) { return(new IntervalCollection <T>(a)); } var lowestBound = Bound.Min(a.LowerBound, b.LowerBound); var upmostValue = Bound.Max(a.UpperBound, b.UpperBound); var lowerBound = default(Bound <T>); var upperBound = default(Bound <T>); // a //------------- // b // --------- if (object.Equals(lowestBound, a.LowerBound) && object.Equals(upmostValue, a.UpperBound)) { lowerBound = new Bound <T>(BoundType.Lower , object.Equals(a.LowerBound.Value, b.LowerBound.Value) ? Bound.Max(a.LowerBound.Direction, b.LowerBound.Direction) : a.LowerBound.Direction , a.LowerBound.Value); upperBound = new Bound <T>(BoundType.Upper , object.Equals(a.UpperBound.Value, b.UpperBound.Value) ? Bound.Max(a.UpperBound.Direction, b.UpperBound.Direction) : a.UpperBound.Direction , a.UpperBound.Value); } // a // --------- // b //------------- else if (object.Equals(lowestBound, b.LowerBound) && object.Equals(upmostValue, b.UpperBound)) { lowerBound = new Bound <T>(BoundType.Lower , object.Equals(a.LowerBound.Value, b.LowerBound.Value) ? Bound.Max(a.LowerBound.Direction, b.LowerBound.Direction) : b.LowerBound.Direction , b.LowerBound.Value); upperBound = new Bound <T>(BoundType.Upper , object.Equals(a.UpperBound.Value, b.UpperBound.Value) ? Bound.Max(a.UpperBound.Direction, b.UpperBound.Direction) : b.UpperBound.Direction , b.UpperBound.Value); } // a //--------- // b // ------------- else if (object.Equals(lowestBound, a.LowerBound) && object.Equals(upmostValue, b.UpperBound) && a.UpperBound.UnionCompareTo(b.LowerBound) >= 0) { lowerBound = new Bound <T>(BoundType.Lower , object.Equals(a.LowerBound.Value, b.LowerBound.Value) ? Bound.Max(a.LowerBound.Direction, b.LowerBound.Direction) : a.LowerBound.Direction , a.LowerBound.Value); upperBound = new Bound <T>(BoundType.Upper , object.Equals(a.UpperBound.Value, b.UpperBound.Value) ? Bound.Max(a.UpperBound.Direction, b.UpperBound.Direction) : b.UpperBound.Direction , b.UpperBound.Value); } // a // ------------- // b //--------- else if (object.Equals(lowestBound, b.LowerBound) && object.Equals(upmostValue, a.UpperBound) && b.UpperBound.UnionCompareTo(a.LowerBound) >= 0) { lowerBound = new Bound <T>(BoundType.Lower , object.Equals(a.LowerBound.Value, b.LowerBound.Value) ? Bound.Max(a.LowerBound.Direction, b.LowerBound.Direction) : b.LowerBound.Direction , b.LowerBound.Value); upperBound = new Bound <T>(BoundType.Upper , object.Equals(a.UpperBound.Value, b.UpperBound.Value) ? Bound.Max(a.UpperBound.Direction, b.UpperBound.Direction) : a.UpperBound.Direction , a.UpperBound.Value); } else { return(new IntervalCollection <T>(a, b)); } Interval <T> result; return(TryParse(lowerBound, upperBound, out result) ? new IntervalCollection <T>(result) : new IntervalCollection <T>(a, b)); }
/// <summary> /// Determines the intersection of two intervals. /// </summary> /// <typeparam name="T">The value type of the intervals.</typeparam> /// <param name="a">The first interval.</param> /// <param name="b">The second interval.</param> /// <returns>An <see cref="Interval<T>"/> that contains all elements of <paramref name="a"/> /// that also belong to <paramref name="b"/> (or equivalently, all elements of <paramref name="b"/> /// that also belong to <paramref name="a"/>), but no other elements.</returns> /// <seealso href="http://en.wikipedia.org/wiki/Intersection_(set_theory)">Intersection (set theory)</seealso> private static Interval <T> IntersectionOf <T>(Interval <T> a, Interval <T> b) { if (Interval.IsNullOrEmpty(a)) { return(a); } if (Interval.IsNullOrEmpty(b)) { return(b); } var lowestBound = Bound.Min(a.LowerBound, b.LowerBound); var upmostValue = Bound.Max(a.UpperBound, b.UpperBound); var lowerBound = default(Bound <T>); var upperBound = default(Bound <T>); // a //------------- // b // --------- if (object.Equals(lowestBound, a.LowerBound) && object.Equals(upmostValue, a.UpperBound)) { lowerBound = new Bound <T>(BoundType.Lower , object.Equals(a.LowerBound.Value, b.LowerBound.Value) ? Bound.Min(a.LowerBound.Direction, b.LowerBound.Direction) : b.LowerBound.Direction , b.LowerBound.Value); upperBound = new Bound <T>(BoundType.Upper , object.Equals(a.UpperBound.Value, b.UpperBound.Value) ? Bound.Min(a.UpperBound.Direction, b.UpperBound.Direction) : b.UpperBound.Direction , b.UpperBound.Value); } // a // --------- // b //------------- else if (object.Equals(lowestBound, b.LowerBound) && object.Equals(upmostValue, b.UpperBound)) { lowerBound = new Bound <T>(BoundType.Lower , object.Equals(a.LowerBound.Value, b.LowerBound.Value) ? Bound.Min(a.LowerBound.Direction, b.LowerBound.Direction) : a.LowerBound.Direction , a.LowerBound.Value); upperBound = new Bound <T>(BoundType.Upper , object.Equals(a.UpperBound.Value, b.UpperBound.Value) ? Bound.Min(a.UpperBound.Direction, b.UpperBound.Direction) : a.UpperBound.Direction , a.UpperBound.Value); } // a //--------- // b // ------------- else if (object.Equals(lowestBound, a.LowerBound) && object.Equals(upmostValue, b.UpperBound)) { lowerBound = new Bound <T>(BoundType.Lower , object.Equals(a.LowerBound.Value, b.LowerBound.Value) ? Bound.Min(a.LowerBound.Direction, b.LowerBound.Direction) : b.LowerBound.Direction , b.LowerBound.Value); upperBound = new Bound <T>(BoundType.Upper , object.Equals(a.UpperBound.Value, b.UpperBound.Value) ? Bound.Min(a.UpperBound.Direction, b.UpperBound.Direction) : a.UpperBound.Direction , a.UpperBound.Value); } // a // ------------- // b //--------- else if (object.Equals(lowestBound, b.LowerBound) && object.Equals(upmostValue, a.UpperBound)) { lowerBound = new Bound <T>(BoundType.Lower , object.Equals(a.LowerBound.Value, b.LowerBound.Value) ? Bound.Min(a.LowerBound.Direction, b.LowerBound.Direction) : a.LowerBound.Direction , a.LowerBound.Value); upperBound = new Bound <T>(BoundType.Upper , object.Equals(a.UpperBound.Value, b.UpperBound.Value) ? Bound.Min(a.UpperBound.Direction, b.UpperBound.Direction) : b.UpperBound.Direction , b.UpperBound.Value); } else { return(Interval.Empty <T>()); } Interval <T> result; return(TryParse(lowerBound, upperBound, out result) ? result : Interval.Empty <T>()); }