/// <summary> Yields all elements that are between the elements in the specified sorted sequence. So basically, this is exclusion of the sequence from the range of the sequence. </summary>
        /// <typeparam name="T"> The type of the elements. </typeparam>
        /// <param name="sequence"> The sequence of the elements that are not yielded. </param>
        /// <param name="increment"> A function specifying the next element given one. </param>
        /// <param name="start"> The start of the range of all elements to yield. </param>
        /// <param name="end"> The end of the range of all elements to yield. </param>
        /// <param name="equalityComparer"> The equality comparer used for determining whether an element in the specified sequence matches that in the range. </param>
        public static IEnumerable <T> RangeExcept <T>(this ISortedEnumerable <T> sequence, Func <T, T> increment, T start, T end, IEqualityComparer <T> equalityComparer = null)
        {
            Contract.Requires(sequence != null);
            Contract.Requires(increment != null);
            Contract.Requires(sequence.IsSorted(sequence.Comparer));
            equalityComparer = equalityComparer ?? EqualityComparer <T> .Default;

            T    previouslyExcludedElement = start;
            bool first = true;

            foreach (var excludedElement in sequence.Concat(end))
            {
                foreach (var elementBelowExcludedElement in Range(previouslyExcludedElement, increment, excludedElement, equalityComparer, first))
                {
                    if (equalityComparer.Equals(end, elementBelowExcludedElement))
                    {
                        yield break;
                    }
                    yield return(elementBelowExcludedElement);
                }
                if (equalityComparer.Equals(end, excludedElement))
                {
                    yield break;
                }
                previouslyExcludedElement = excludedElement;
                first = false;
            }
        }
示例#2
0
        /// <summary> Returns whether the specified intervals are disjoint. </summary>
        /// <param name="intervals"> The intervals to inspect, ordered by interval start. </param>
        /// <returns> an empty specified enumerable is considered disjoint. </returns>
        public static bool AreDisjoint(this ISortedEnumerable <Interval> intervals)
        {
            Contract.Requires(intervals != null);
            Contract.RequiresForAll(intervals, interval => !interval.IsEmpty);
            Contract.Requires(intervals.IsSorted(comparer: Compare));

            Interval previous = default(Interval);
            bool     first    = true;

            foreach (Interval interval in intervals)
            {
                if (first)
                {
                    first = false;
                }
                else
                {
                    if (!previous.DisjointFrom(interval))
                    {
                        return(false);
                    }
                }
                previous = interval;
            }

            return(true);
        }