示例#1
0
        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);
        }
示例#2
0
        /// <summary>
        /// Initializes a new instance of the <see cref="Interval&lt;T&gt;"/> 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;
        }
示例#3
0
        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);
        }
示例#4
0
 /// <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)
 {
 }
示例#5
0
        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);
        }
示例#6
0
        /// <summary>
        /// Compares this instance to a specified <see cref="Bound&lt;T&gt;"/> and returns an indication of their relative values.
        /// </summary>
        /// <param name="other">A <see cref="Bound&lt;T&gt;"/> 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));
                }
            }
        }
示例#7
0
 /// <summary>
 /// Overrides the default bound values of <see cref="Interval&lt;T&gt;"/>.
 /// </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);
 }
示例#8
0
        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));
        }
示例#9
0
        /// <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&lt;T&gt;"/> 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>());
        }