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; } }
private static bool BoundariesProduceEmptyInterval(LowerBoundary <T> lowerBoundary, UpperBoundary <T> upperBoundary) { throw null; //return lowerBoundary.Value.IsGreaterThan(upperBoundary.Value) || (lowerBoundary.Value.IsEqualTo(upperBoundary.Value) && (lowerBoundary.IsOpen || upperBoundary.IsOpen)); }
internal LowerBoundary(LowerBoundary <T, DefaultValueComparer <T> > boundary) => _boundary = boundary;
internal Interval(LowerBoundary <T> lowerBoundary, UpperBoundary <T> upperBoundary) : this(new Interval <T, DefaultValueComparer <T> >(lowerBoundary, upperBoundary)) { }
internal Interval(LowerBoundary <T, TComparer> lowerBoundary, UpperBoundary <T, TComparer> upperBoundary) { _lowerBoundary = lowerBoundary; _upperBoundary = upperBoundary; }
public bool Equals(LowerBoundary <T, TComparer> other) => IsValid && other.IsValid ? Value.IsEqualTo <T, TComparer>(other.Value) && Type == other.Type : IsValid == other.IsValid;