public static ReadOnlyArray <Interval <T, TComparer> > Union <T, TComparer>(ReadOnlyArray <Interval <T, TComparer> > first, ReadOnlyArray <Interval <T, TComparer> > second) where TComparer : struct, IBoundaryValueComparer <T>
        {
            var firstArray      = first.AsArrayUnchecked();
            var secondArray     = second.AsArrayUnchecked();
            var maxFirst        = first.Count - 1;
            var maxSecond       = second.Count - 1;
            var mergedIntervals = new Interval <T, TComparer> [maxFirst + maxSecond + 2];

            int            f = 0;
            int            s = 0;
            int            m = 0;
            OperationState operationState;
            LowerBoundary <T, TComparer> currentLowerBoundary;

            if (maxFirst == -1)
            {
                return(MergeTail(mergedIntervals, secondArray, s, maxSecond, m));
            }
            else if (maxSecond == -1)
            {
                return(MergeTail(mergedIntervals, firstArray, f, maxFirst, m));
            }

LowerFirstLowerSecond:
            operationState = OperationState.Middle;
            if (firstArray[f].LowerBoundary.IsLessThan <T, TComparer>(secondArray[s].LowerBoundary))
            {
                currentLowerBoundary = firstArray[f].LowerBoundary;
                goto UpperFirstLowerSecond;
            }
            else
            {
                currentLowerBoundary = secondArray[s].LowerBoundary;
                goto LowerFirstUpperSecond;
            }

LowerFirstUpperSecond:
            if (firstArray[f].LowerBoundary.IsLessThan <T, TComparer, OverlapClosed>(secondArray[s].UpperBoundary))
            {
                operationState++;
                if (operationState == OperationState.Middle)
                {
                    currentLowerBoundary = firstArray[f].LowerBoundary;
                }

                goto UpperFirstUpperSecond;
            }
            else
            {
                operationState--;
                if (operationState == OperationState.Lowest)
                {
                    mergedIntervals[m] = new Interval <T, TComparer>(currentLowerBoundary, secondArray[s].UpperBoundary);
                    m++;
                }
                if (s == maxSecond)
                {
                    return(MergeTail(mergedIntervals, firstArray, f, maxFirst, m));
                }

                s++;
                goto LowerFirstLowerSecond;
            }

UpperFirstLowerSecond:
            if (firstArray[f].UpperBoundary.IsLessThan <T, TComparer, OverlapClosed>(secondArray[s].LowerBoundary))
            {
                operationState--;
                if (operationState == OperationState.Lowest)
                {
                    mergedIntervals[m] = new Interval <T, TComparer>(currentLowerBoundary, firstArray[f].UpperBoundary);
                    m++;
                }
                if (f == maxFirst)
                {
                    return(MergeTail(mergedIntervals, secondArray, s, maxSecond, m));
                }

                f++;
                goto LowerFirstLowerSecond;
            }
            else
            {
                operationState++;
                if (operationState == OperationState.Middle)
                {
                    currentLowerBoundary = secondArray[s].LowerBoundary;
                }

                goto UpperFirstUpperSecond;
            }

UpperFirstUpperSecond:
            operationState = OperationState.Middle;
            if (firstArray[f].UpperBoundary.IsLessThan(secondArray[s].UpperBoundary))
            {
                if (f == maxFirst)
                {
                    return(MergeTailStartingWithUpperBoundary(mergedIntervals, secondArray, currentLowerBoundary, s, maxSecond, m));
                }
                f++;

                goto LowerFirstUpperSecond;
            }
            else
            {
                if (s == maxSecond)
                {
                    return(MergeTailStartingWithUpperBoundary(mergedIntervals, firstArray, currentLowerBoundary, f, maxFirst, m));
                }
                s++;

                goto UpperFirstLowerSecond;
            }
        }
 internal Enumerator(ReadOnlyArray <T> readOnlyArray)
 {
     _array = readOnlyArray._array;
     _count = readOnlyArray.Count;
     _index = -1;
 }
        public static ReadOnlyArray <Interval <T, TComparer> > Intersect <T, TComparer>(ReadOnlyArray <Interval <T, TComparer> > first, ReadOnlyArray <Interval <T, TComparer> > second) where TComparer : struct, IBoundaryValueComparer <T>
        {
            var firstArray      = first.AsArrayUnchecked();
            var secondArray     = second.AsArrayUnchecked();
            var maxFirst        = first.Count - 1;
            var maxSecond       = second.Count - 1;
            var mergedIntervals = new Interval <T, TComparer> [maxFirst + maxSecond + 2];

            int            f = 0;
            int            s = 0;
            int            m = 0;
            OperationState operationState;
            LowerBoundary <T, TComparer> currentLowerBoundary = default;

            if (maxFirst == -1 || maxSecond == -1)
            {
                return(ReadOnlyArray <Interval <T, TComparer> > .Empty);
            }

LowerFirstLowerSecond:
            operationState = OperationState.Middle;
            if (firstArray[f].LowerBoundary.IsLessThan(secondArray[s].LowerBoundary))
            {
                goto UpperFirstLowerSecond;
            }
            else
            {
                goto LowerFirstUpperSecond;
            }

LowerFirstUpperSecond:
            if (firstArray[f].LowerBoundary.IsLessThan <T, TComparer, OverlapFullyClosed>(secondArray[s].UpperBoundary))
            {
                operationState++;
                if (operationState == OperationState.Highest)
                {
                    currentLowerBoundary = firstArray[f].LowerBoundary;
                }

                goto UpperFirstUpperSecond;
            }
            else
            {
                operationState--;
                if (operationState == OperationState.Middle)
                {
                    mergedIntervals[m] = new Interval <T, TComparer>(currentLowerBoundary, secondArray[s].UpperBoundary);
                    m++;
                }
                if (s == maxSecond)
                {
                    return(new ReadOnlyArray <Interval <T, TComparer> >(mergedIntervals, m));
                }

                s++;
                goto LowerFirstLowerSecond;
            }

UpperFirstLowerSecond:
            if (firstArray[f].UpperBoundary.IsLessThan <T, TComparer, OverlapFullyClosed>(secondArray[s].LowerBoundary))
            {
                operationState--;
                if (operationState == OperationState.Middle)
                {
                    mergedIntervals[m] = new Interval <T, TComparer>(currentLowerBoundary, firstArray[f].UpperBoundary);
                    m++;
                }
                if (f == maxFirst)
                {
                    return(new ReadOnlyArray <Interval <T, TComparer> >(mergedIntervals, m));
                }

                f++;
                goto LowerFirstLowerSecond;
            }
            else
            {
                operationState++;
                if (operationState == OperationState.Highest)
                {
                    currentLowerBoundary = secondArray[s].LowerBoundary;
                }

                goto UpperFirstUpperSecond;
            }

UpperFirstUpperSecond:
            operationState = OperationState.Middle;
            if (firstArray[f].UpperBoundary.IsLessThan(secondArray[s].UpperBoundary))
            {
                mergedIntervals[m] = new Interval <T, TComparer>(currentLowerBoundary, firstArray[f].UpperBoundary);
                m++;
                if (f == maxFirst)
                {
                    return(new ReadOnlyArray <Interval <T, TComparer> >(mergedIntervals, m));
                }
                f++;

                goto LowerFirstUpperSecond;
            }
            else
            {
                mergedIntervals[m] = new Interval <T, TComparer>(currentLowerBoundary, secondArray[s].UpperBoundary);
                m++;
                if (s == maxSecond)
                {
                    return(new ReadOnlyArray <Interval <T, TComparer> >(mergedIntervals, m));
                }
                s++;

                goto UpperFirstLowerSecond;
            }
        }
 public bool Equals(ReadOnlyArray <T> other) => _array == other._array && _count == other._count;