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;