Example #1
0
        public IEnumerable <Range <TValue> > Exclude(Range <TValue> other)
        {
            var current = this;

            if (current.IsEmpty || other.IsFull)
            {
                yield return(Empty);

                yield break;
            }

            if (other.IsEmpty)
            {
                yield return(this);

                yield break;
            }

            if (current.IsFull)
            {
                foreach (var r in other.Invert())
                {
                    yield return(r);
                }
                yield break;
            }

            var currentStart = current.StartValue;
            var currentEnd   = current.EndValue;

            var otherStart = other.StartValue;
            var otherEnd   = other.EndValue;

            var overlap = currentStart <= otherEnd && otherStart <= currentEnd;

            if (!overlap)
            {
                yield return(current);                // Nothing to exclude
            }
            var compareStart = currentStart.CompareTo(otherStart);

            if (compareStart <= 0)             // currentStart <= otherStart
            {
                // =====---C---------      //
                //      --------O--        //
                //      --------O----      //
                //      --------O--------- //

                if (compareStart == 0)
                {
                    if (!otherStart.Included && currentStart.Included)
                    {
                        var singleValueRange = new Range <TValue>(currentStart, currentStart, true, true);
                        yield return(singleValueRange);
                    }
                }
                else
                {
                    var newRange = new Range <TValue>(currentStart, otherStart, currentStart.Included, !otherStart.Included);
                    yield return(newRange);
                }
            }

            var compareEnd = currentEnd.CompareTo(otherEnd);

            if (compareEnd >= 0)             // currentEnd >= otherEnd
            {
                //    --------C----=====      //
                // --------O-------           //
                // --------O------------      //

                if (compareEnd == 0)
                {
                    if (!otherEnd.Included && currentEnd.Included)
                    {
                        var singleValueRange = new Range <TValue>(currentEnd, currentEnd, true, true);
                        yield return(singleValueRange);
                    }
                }
                else
                {
                    var newRange = new Range <TValue>(otherEnd, currentEnd, !otherEnd.Included, currentEnd.Included);
                    yield return(newRange);
                }
            }
        }