/// <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; } }
/// <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); }