/// <summary>Creates instance of <seealso cref="CompositeRange{T}"/>.</summary> /// <param name="ranges">Contained ranges.</param> /// <param name="skipsArgHandling">Stub argument to mark unsafe (no validation) constructor overload.</param> internal CompositeRange([NotNull] IEnumerable <Range <T, TKey> > ranges, UnsafeOverload skipsArgHandling) { Code.NotNull(ranges, nameof(ranges)); #pragma warning disable 618 // ok by design. bool rangesReady = skipsArgHandling == UnsafeOverload.NoEmptyRangesAlreadySortedAndMerged; var tempRanges = rangesReady || skipsArgHandling == UnsafeOverload.NoEmptyRanges ? ranges.ToArray() : ranges.Where(r => r.IsNotEmpty).ToArray(); #pragma warning restore 618 if (tempRanges.Length == 0) { _ranges = _emptyRanges; _hasRangesToMerge = false; _containingRange = _emptyRangeNoKey; return; } if (tempRanges.Length == 1 || rangesReady) { _ranges = tempRanges.AsReadOnly(); _hasRangesToMerge = false; _containingRange = Range.Create(tempRanges[0].From, tempRanges[tempRanges.Length - 1].To); return; } #pragma warning disable 618 // ok by design. if (skipsArgHandling != UnsafeOverload.RangesAlreadySorted) #pragma warning restore 618 { Array.Sort(tempRanges, _rangeComparer); } bool hasRangesToMerge = false; var maxToBoundary = tempRanges[0].To; for (int i = 1; i < tempRanges.Length; i++) { var range = tempRanges[i]; // TODO: check for keyed range. hasRangesToMerge = hasRangesToMerge || IsContinuationFor(maxToBoundary, range); maxToBoundary = Range.Max(maxToBoundary, range.To); } _ranges = tempRanges.AsReadOnly(); _hasRangesToMerge = hasRangesToMerge; _containingRange = Range.Create(tempRanges[0].From, maxToBoundary); }