public CompositeRange <T> Intersect <TKey2>(CompositeRange <T, TKey2> other) { if (IsEmpty) { return(this); } if (other.IsEmpty || !ContainingRange.HasIntersection(other.ContainingRange)) { return(Empty); } var intersectionResult = new List <Range <T> >(SubRanges.Count); var rangesToIntersect = new List <Range <T> >(SubRanges); foreach (var otherRange in other.GetMergedRanges()) { for (var i = 0; i < rangesToIntersect.Count; i++) { var intersectionRange = rangesToIntersect[i]; if (intersectionRange.StartsAfter(otherRange)) { break; } intersectionRange = intersectionRange.Intersect(otherRange); if (intersectionRange.IsEmpty) { rangesToIntersect.RemoveAt(i); i--; } else { intersectionResult.Add(intersectionRange); } } if (rangesToIntersect.Count == 0) { break; } } CompositeRange <T> result; if (intersectionResult.Count == 0) { result = Empty; } else { var overload = IsMerged ? UnsafeOverload.NoEmptyRangesAlreadySortedAndMerged : UnsafeOverload.RangesAlreadySorted; result = new CompositeRange <T>(intersectionResult, overload); } return(result); }
/// <summary>Returns ranges that has intersections with passed range.</summary> /// <typeparam name="T">The type of the range values.</typeparam> /// <param name="compositeRange">The source range.</param> /// <param name="value">The value to check.</param> /// <returns>Ranges that has intersections with passed range.</returns> public static Range <T>[] GetIntersection <T>(this CompositeRange <T> compositeRange, T value) { { var ranges = new List <Range <T> >(); if (!compositeRange.ContainingRange.Contains(value)) { return (#if (!FW452) Array.Empty <Range <T> >()); } #else Array <Range <T> > .Empty; #endif foreach (var range in compositeRange.SubRanges) { if (range.StartsAfter(value)) { break; } if (range.Contains(value)) { ranges.Add(range); } } return(ranges.ToArray()); } }
/// <summary>Returns ranges that has intersections with passed range.</summary> /// <typeparam name="T">The type of the range values.</typeparam> /// <typeparam name="TRange">The type of the range.</typeparam> /// <param name="compositeRange">The source range.</param> /// <param name="other">The range to check.</param> /// <returns>Ranges that has intersections with passed range.</returns> private static RangeIntersection <T> GetIntersectionCore <T, TRange>(this CompositeRange <T> compositeRange, TRange other) where TRange : IRange <T> { var ranges = new List <Range <T> >(); if (!compositeRange.ContainingRange.HasIntersection(other)) { return (GetRangeIntersection( other.From, other.To, #if (!FW452) Array.Empty <Range <T> >() #else Array <Range <T> > .Empty #endif )); } foreach (var range in compositeRange.SubRanges) { if (range.From > other.To) { break; } if (range.To >= other.From) { ranges.Add(range); } } return(GetRangeIntersection(other.From, other.To, ranges.ToArray())); }
public static void TestCreate() { var range1 = Range.Create(1, 2); var range2 = Range.Create(2, 3); var keyedRange1 = Range.Create(1, 2, "A"); var keyedRange2 = Range.Create(2, 3, "B"); DoesNotThrow(() => CompositeRange.Create <int>()); DoesNotThrow(() => CompositeRange.Create(range1)); DoesNotThrow(() => CompositeRange.Create(range1, range2)); DoesNotThrow(() => CompositeRange.Create(range1, range1)); DoesNotThrow(() => CompositeRange.Create(range2, range1)); Throws <ArgumentNullException>(() => CompositeRange.Create <int>(null)); DoesNotThrow(() => CompositeRange.Create <int, string>()); DoesNotThrow(() => CompositeRange.Create(keyedRange1)); DoesNotThrow(() => CompositeRange.Create(keyedRange1, keyedRange2)); DoesNotThrow(() => CompositeRange.Create(keyedRange1, keyedRange1)); DoesNotThrow(() => CompositeRange.Create(keyedRange2, keyedRange1)); Throws <ArgumentNullException>(() => CompositeRange.Create <int, string>(null)); AreEqual(new CompositeRange <int>(), CompositeRange <int> .Empty); AreEqual(CompositeRange.Create <int>(), CompositeRange <int> .Empty); AreEqual(CompositeRange.Create(Range <int> .Empty), CompositeRange <int> .Empty); AreEqual(CompositeRange.Create(Range <int> .Empty, Range <int> .Empty), CompositeRange <int> .Empty); AreEqual(CompositeRange.Create(Range <int> .Infinite), CompositeRange <int> .Infinite); }
/// <summary>Creates a new composite range with the key specified.</summary> /// <typeparam name="T">The type of the range values.</typeparam> /// <typeparam name="T2">The type of new range values.</typeparam> /// <param name="compositeRange">The source range.</param> /// <param name="fromValueSelector">Callback to obtain a new value for the From boundary. Used if boundary has a value.</param> /// <param name="toValueSelector">Callback to obtain a new value for the To boundary. Used if boundary has a value.</param> /// <returns>A new composite range with the key specified.</returns> public static CompositeRange <T2> WithValues <T, T2>( this CompositeRange <T> compositeRange, [NotNull, InstantHandle] Func <T, T2> fromValueSelector, [NotNull, InstantHandle] Func <T, T2> toValueSelector) => compositeRange.IsEmpty ? CompositeRange <T2> .Empty : compositeRange.SubRanges.Select(s => s.WithValues(fromValueSelector, toValueSelector)).ToCompositeRange();
/// <summary>Indicates whether the current range is equal to another.</summary> /// <param name="other">A range to compare with this.</param> /// <returns> /// <c>True</c> if the current range is equal to the <paramref name="other"/> parameter; /// otherwise, false. /// </returns> public bool Equals(CompositeRange <T> other) { if (IsEmpty) { return(other.IsEmpty); } if (other.IsEmpty) { return(false); } DebugCode.BugIf(_ranges == null, "_ranges == null"); DebugCode.BugIf(other._ranges == null, "other._ranges == null"); var otherRanges = other._ranges; if (_containingRange != other._containingRange || _ranges.Count != otherRanges.Count) { return(false); } for (var i = 0; i < _ranges.Count; i++) { if (!_ranges[i].Equals(otherRanges[i])) { return(false); } } return(true); }
public bool HasIntersection <TKey2>(CompositeRange <T, TKey2> other) { if (IsEmpty && other.IsEmpty) { return(true); } if (!ContainingRange.HasIntersection(other.ContainingRange)) { return(false); } var result = false; using (var containingRanges = GetMergedRanges().GetEnumerator()) { var hasContainingRange = containingRanges.MoveNext(); foreach (var otherRange in other.GetMergedRanges()) { while (hasContainingRange && containingRanges.Current.EndsBefore(otherRange)) { hasContainingRange = containingRanges.MoveNext(); } if (!hasContainingRange || containingRanges.Current.HasIntersection(otherRange)) { result = hasContainingRange; break; } } } return(result); }
/// <summary>Determines whether the composite range has intersection with another range.</summary> /// <typeparam name="T">The type of the range values.</typeparam> /// <typeparam name="TCompositeRange">The type of another range.</typeparam> /// <param name="compositeRange">The source range.</param> /// <param name="other">The range to check.</param> /// <returns><c>true</c>, if the composite range has intersection with another range.</returns> public static bool HasIntersection <T, TCompositeRange>( this CompositeRange <T> compositeRange, TCompositeRange other) where TCompositeRange : ICompositeRange <T> { if (compositeRange.IsEmpty && other.IsEmpty) { return(true); } if (!compositeRange.ContainingRange.HasIntersection(other.ContainingRange)) { return(false); } bool result = false; using (var containingRanges = compositeRange.GetMergedRanges().GetEnumerator()) { bool hasContainingRange = containingRanges.MoveNext(); foreach (var otherRange in other.GetMergedRanges()) { while (hasContainingRange && containingRanges.Current.EndsBefore(otherRange)) { hasContainingRange = containingRanges.MoveNext(); } if (!hasContainingRange || containingRanges.Current.HasIntersection(otherRange)) { result = hasContainingRange; break; } } } return(result); }
/// <summary>Indicates whether the current range is equal to another.</summary> /// <param name="other">A range to compare with this.</param> /// <returns> /// <c>True</c> if the current range is equal to the <paramref name="other"/> parameter; /// otherwise, false. /// </returns> public bool Equals(CompositeRange <T, TKey> other) { // TODO: BADCODE, rewrite if (IsEmpty) { return(other.IsEmpty); } if (other.IsEmpty) { return(false); } DebugCode.BugIf(_ranges == null, "_ranges == null"); DebugCode.BugIf(other._ranges == null, "other._ranges == null"); var otherRanges = other._ranges; if (_containingRange != other._containingRange || _ranges.Count != otherRanges.Count) { return(false); } var previousRange = Range <T> .Empty; IDictionary <(TKey, int), int> keys = new Dictionary <(TKey, int), int>(); var nullKeysCount = 0; for (var i = 0; i < _ranges.Count; i++) { var currentWithoutKey = _ranges[i].WithoutKey(); // TODO: helper method to compare without key. if (!currentWithoutKey.Equals(otherRanges[i].WithoutKey())) { return(false); } if (currentWithoutKey != previousRange) { var sameKeys = nullKeysCount == 0 && keys.Values.All(a => a == 0); if (!sameKeys) { return(false); } keys.Clear(); nullKeysCount = 0; } var key = _ranges[i].Key; if (key == null) { nullKeysCount++; } else { keys[(key, 0)] = keys.GetValueOrDefault((key, 0)) + 1;
public static CompositeRange <T, TKey> Intersect <T, TKey>( this CompositeRange <T, TKey> compositeRange, #region T4-dont-replace Range <T> other #endregion ) => Intersect(compositeRange, other.ToCompositeRange());
public CompositeRange <T> Except <TKey2>(CompositeRange <T, TKey2> other) { if (IsEmpty || other.IsEmpty || !ContainingRange.HasIntersection(other.ContainingRange)) { return(this); } return(Intersect(other.GetComplementation())); }
/// <summary>Returns ranges that has intersections with passed range.</summary> /// <typeparam name="T">The type of the range values.</typeparam> /// <param name="compositeRange">The source range.</param> /// <param name="other">The range to check.</param> /// <returns>Ranges that has intersections with passed range.</returns> public static RangeIntersection <T> GetIntersection <T>( this CompositeRange <T> compositeRange, #region T4-dont-replace Range <T> other #endregion ) => GetIntersectionCore(compositeRange, other);
/// <summary>Returns source range with other range excluded.</summary> /// <typeparam name="T">The type of the range values.</typeparam> /// <param name="compositeRange">The source range.</param> /// <param name="other">The range to intersect with.</param> /// <returns>Source range with other range excluded.</returns> public static CompositeRange <T> Except <T>( this CompositeRange <T> compositeRange, #region T4-dont-replace Range <T> other #endregion ) => Except(compositeRange, other.ToCompositeRange());
public static IEnumerable <RangeIntersection <T> > GetIntersections <T>(this CompositeRange <T> compositeRange) { if (compositeRange.IsEmpty) { yield break; } var toBoundaries = new List <RangeBoundaryTo <T> >(); // Sorted by descending. var rangesToYield = new List <Range <T> >(); var fromBoundary = RangeBoundaryFrom <T> .NegativeInfinity; foreach (var range in compositeRange.SubRanges) { // return all ranges that has no intersection with current range. while (toBoundaries.Count > 0 && toBoundaries.Last() < range.From) { var toBoundary = toBoundaries.Last(); yield return(GetRangeIntersection(fromBoundary, toBoundary, rangesToYield)); rangesToYield.RemoveAll(r => r.To == toBoundary); toBoundaries.RemoveAt(toBoundaries.Count - 1); fromBoundary = toBoundary.GetComplementation(); } // return rangesToYield as they starts before current range. if (fromBoundary < range.From) { var to = range.From.GetComplementation(); yield return(GetRangeIntersection(fromBoundary, to, rangesToYield)); } // updating the state rangesToYield.Add(range); InsertInSortedList( toBoundaries, range.To, RangeBoundaryToDescendingComparer <T> .Instance, // ReSharper disable once ArgumentsStyleLiteral skipDuplicates: true); fromBoundary = range.From; } // flush all ranges. while (toBoundaries.Count > 0 && toBoundaries.Last() < RangeBoundaryTo <T> .PositiveInfinity) { var toBoundary = toBoundaries.Last(); yield return(GetRangeIntersection(fromBoundary, toBoundary, rangesToYield)); rangesToYield.RemoveAll(r => r.To == toBoundary); toBoundaries.RemoveAt(toBoundaries.Count - 1); fromBoundary = toBoundary.GetComplementation(); } yield return(GetRangeIntersection(fromBoundary, RangeBoundaryTo <T> .PositiveInfinity, rangesToYield)); }
/// <summary>Determines whether the composite range contains another range.</summary> /// <typeparam name="T">The type of the range values.</typeparam> /// <param name="compositeRange">The source range.</param> /// <param name="other">The range to check.</param> /// <returns><c>true</c>, if the composite range contains another range.</returns> public static bool Contains <T>( this CompositeRange <T> compositeRange, #region T4-dont-replace Range <T> other #endregion ) => compositeRange.ContainingRange.Contains(other) && compositeRange.GetMergedRanges().Any(r => r.Contains(other));
/// <summary>Determines whether the composite range has intersection with another range.</summary> /// <typeparam name="T">The type of the range values.</typeparam> /// <param name="compositeRange">The source range.</param> /// <param name="other">The range to check.</param> /// <returns><c>true</c>, if the composite range has intersection with another range.</returns> public static bool HasIntersection <T>( this CompositeRange <T> compositeRange, #region T4-dont-replace Range <T> other #endregion ) => compositeRange.ContainingRange.HasIntersection(other) && compositeRange.SubRanges.Any(r => r.HasIntersection(other));
public IntervalTreeTests() { _sameStartRanges = Enumerable.Range(0, Count) .ToCompositeRange(i => 0, i => 2 * i, i => i.ToString()); _sameEndRanges = Enumerable.Range(0, Count) .ToCompositeRange(i => 0, i => 2 * i, i => i.ToString()); _nonOverlappingRanges = Enumerable.Range(0, Count) .ToCompositeRange(i => 4 * i - 2, i => 4 * i + 2, i => i.ToString()); _overlappingRanges = Enumerable.Range(0, Count) .ToCompositeRange(i => 4 * i - 2 * (i % 4), i => 4 * i + 2 * (i % 4), i => i.ToString()); }
static IntervalTreeTests() { _sameStartRanges = Enumerable.Range(0, _count) .ToCompositeRange(i => 0, i => 2 * i, i => i.ToString(CultureInfo.InvariantCulture)); _sameEndRanges = Enumerable.Range(0, _count) .ToCompositeRange(i => 0, i => 2 * i, i => i.ToString(CultureInfo.InvariantCulture)); _nonOverlappingRanges = Enumerable.Range(0, _count) .ToCompositeRange(i => 4 * i - 2, i => 4 * i + 2, i => i.ToString(CultureInfo.InvariantCulture)); _overlappingRanges = Enumerable.Range(0, _count) .ToCompositeRange(i => 4 * i - 2 * (i % 4), i => 4 * i + 2 * (i % 4), i => i.ToString(CultureInfo.InvariantCulture)); }
/// <summary>Returns source range with other range excluded.</summary> /// <typeparam name="T">The type of the range values.</typeparam> /// <typeparam name="TCompositeRange">The type of another range.</typeparam> /// <param name="compositeRange">The source range.</param> /// <param name="other">The range to intersect with.</param> /// <returns>Source range with other range excluded.</returns> public static CompositeRange <T> Except <T, TCompositeRange>( this CompositeRange <T> compositeRange, TCompositeRange other) where TCompositeRange : ICompositeRange <T> { if (compositeRange.IsEmpty || other.IsEmpty || !compositeRange.ContainingRange.HasIntersection(other.ContainingRange)) { return(compositeRange); } return(Intersect(compositeRange, GetComplementationCore <T, TCompositeRange>(other))); }
/// <summary> /// Replaces exclusive boundaries with inclusive ones with the values from the selector callbacks /// </summary> /// <typeparam name="T">The type of the range values.</typeparam> /// <param name="compositeRange">The source range.</param> /// <param name="fromValueSelector">Callback to obtain a new value for the From boundary. Used if the boundary is exclusive.</param> /// <param name="toValueSelector">Callback to obtain a new value for the To boundary. Used if the boundary is exclusive.</param> /// <returns>A range with inclusive boundaries.</returns> public static CompositeRange <T> MakeInclusive <T>( this CompositeRange <T> compositeRange, [NotNull, InstantHandle] Func <T, T> fromValueSelector, [NotNull, InstantHandle] Func <T, T> toValueSelector) { if (compositeRange.IsEmpty) { return(compositeRange); } return(compositeRange.SubRanges .Select(r => r.MakeInclusive(fromValueSelector, toValueSelector)) .ToCompositeRange()); }
public IntervalTreePerfTest() { _ranges = Enumerable.Range(0, _count) .ToCompositeRange(i => 4 * i - 2 * (i % 4), i => 1 + 4 * i + 2 * (i % 4), i => i.ToString()); _intersection = _ranges.SubRanges[1000].WithoutKey(); _intersectionCostin = new Interval <int>(_intersection.FromValue, _intersection.ToValue); _tree = new IntervalTree <int, string>(_ranges); _treeCostin = new IntervalTreeCostin <int, string>( _ranges.SubRanges.Select(r => new KeyValuePair <IInterval <int>, string>( new Interval <int>(r.FromValue, r.ToValue), r.Key)) ); }
public CompositeRange <T> Except( #region T4-dont-replace CompositeRange <T> other #endregion ) { if (IsEmpty || other.IsEmpty || !ContainingRange.HasIntersection(other.ContainingRange)) { return(this); } return(Intersect(other.GetComplementation())); }
public static void TestRangesCore(CompositeRange <int, string> ranges) { var tree = new IntervalTree <int, string>(ranges); for (var i = ranges.ContainingRange.FromValue; i <= ranges.ContainingRange.ToValue; i++) { var overlapRange = Range.Create(i, i); AssertSameOverlap(ranges, tree, overlapRange); overlapRange = Range.Create(i - 1, i + 1); AssertSameOverlap(ranges, tree, overlapRange); overlapRange = Range.Create(i - 2, i + 2); AssertSameOverlap(ranges, tree, overlapRange); overlapRange = Range.Create(i - 10, i); AssertSameOverlap(ranges, tree, overlapRange); } }
/// <summary>Returns a union range containing all subranges.</summary> /// <typeparam name="T">The type of the range values.</typeparam> /// <param name="compositeRange">The source range.</param> /// <param name="other">The range to union with.</param> /// <returns>A union range containing all subranges.</returns> public static CompositeRange <T> Union <T>( this CompositeRange <T> compositeRange, CompositeRange <T> other) { if (other.IsEmpty) { return(compositeRange); } if (compositeRange.IsEmpty) { return(other); } var ranges1 = compositeRange.SubRanges; var ranges2 = other.SubRanges; var resultRanges = new Range <T> [ranges1.Count + ranges2.Count]; var overload = compositeRange.IsMerged && other.IsMerged ? UnsafeOverload.NoEmptyRangesAlreadySortedAndMerged : UnsafeOverload.RangesAlreadySorted; if (other.ContainingRange.EndsBefore(compositeRange.ContainingRange)) { ranges2.CopyTo(resultRanges, 0); ranges1.CopyTo(resultRanges, ranges2.Count); } else { ranges1.CopyTo(resultRanges, 0); ranges2.CopyTo(resultRanges, ranges1.Count); if (!compositeRange.ContainingRange.EndsBefore(other.ContainingRange)) { overload = UnsafeOverload.NoEmptyRanges; } } var result = new CompositeRange <T>(resultRanges, overload); if (overload != UnsafeOverload.NoEmptyRangesAlreadySortedAndMerged) { result = result.Merge(); } return(result); }
/// <summary>Extends the range from the right.</summary> /// <typeparam name="T">The type of the range values.</typeparam> /// <param name="compositeRange">The source range.</param> /// <param name="to">A new boundary To.</param> /// <returns> /// A range with a new To boundary or the source fange if the new boundary is less than original. /// </returns> public static CompositeRange <T> ExtendTo <T>(this CompositeRange <T> compositeRange, RangeBoundaryTo <T> to) { if (compositeRange.IsEmpty || to.IsEmpty || to <= compositeRange.ContainingRange.To) { return(compositeRange); } var ranges = compositeRange.SubRanges.ToArray(); for (int i = ranges.Length - 1; i >= 0; i--) { if (ranges[i].To != compositeRange.ContainingRange.To) { break; } ranges[i] = ranges[i].ExtendTo(to); } return(new CompositeRange <T>(ranges, UnsafeOverload.RangesAlreadySorted)); }
/// <summary>Extends the range from the left.</summary> /// <typeparam name="T">The type of the range values.</typeparam> /// <param name="compositeRange">The source range.</param> /// <param name="from">A new boundary From.</param> /// <returns> /// A range with a new From boundary or the source fange if the new boundary is greater than original. /// </returns> public static CompositeRange <T> ExtendFrom <T>(this CompositeRange <T> compositeRange, RangeBoundaryFrom <T> from) { if (compositeRange.IsEmpty || from.IsEmpty || from >= compositeRange.ContainingRange.From) { return(compositeRange); } var ranges = compositeRange.SubRanges.ToArray(); for (int i = 0; i < ranges.Length; i++) { if (ranges[i].From != compositeRange.ContainingRange.From) { break; } ranges[i] = ranges[i].ExtendFrom(from); } return(new CompositeRange <T>(ranges, UnsafeOverload.RangesAlreadySorted)); }
private static List <Range <int, string> > IntersectNaive(CompositeRange <int, string> rangeA, Range <int> overlap) { var result = new List <Range <int, string> >(); if (!rangeA.ContainingRange.HasIntersection(overlap)) { return(result); } foreach (var range in rangeA.SubRanges) { if (range.From > overlap.To) { break; } if (range.To >= overlap.From) { result.Add(range); } } return(result); }
public bool Contains( #region T4-dont-replace CompositeRange <T> other #endregion ) { if (IsEmpty && other.IsEmpty) { return(true); } if (!ContainingRange.Contains(other.ContainingRange)) { return(false); } var result = true; using (var containingRanges = GetMergedRanges().GetEnumerator()) { var hasContainingRange = containingRanges.MoveNext(); foreach (var otherRange in other.GetMergedRanges()) { while (hasContainingRange && containingRanges.Current.EndsBefore(otherRange)) { hasContainingRange = containingRanges.MoveNext(); } if (!hasContainingRange || !containingRanges.Current.Contains(otherRange)) { result = false; break; } } } return(result); }
public static void TestCompositeRangeWithKeyProperties() { var range1A = Range.Create(1, 2, "A"); var range1B = Range.Create(1, 2, "B"); var range2C = Range.CreateExclusiveFrom(2, 3, "C"); var range3A = Range.Create(3, 4).WithKey("A"); var empty = Range <int> .Empty.WithKey((string)null); var infinite = Range <int> .Infinite.WithKey((string)null); var a = new CompositeRange <int, string>(); AreEqual(a, CompositeRange.Create(empty, empty)); AreEqual(a, new CompositeRange <int, string>()); AreEqual(a.SubRanges.Count, 0); AreEqual(a.ContainingRange, Range <int> .Empty); IsTrue(a.IsEmpty); IsFalse(a.IsNotEmpty); IsTrue(a.IsMerged); a = new CompositeRange <int, string>(infinite); AreNotEqual(a, new CompositeRange <int, string>()); AreEqual(a, CompositeRange.Create(infinite)); AreNotEqual(a, CompositeRange.Create(infinite, infinite)); AreEqual(a.SubRanges.Count, 1); AreEqual(a.ContainingRange, infinite.WithoutKey()); AreEqual(a.SubRanges[0], infinite); IsFalse(a.IsEmpty); IsTrue(a.IsNotEmpty); IsTrue(a.IsMerged); a = CompositeRange.Create(range1A); AreNotEqual(a, new CompositeRange <int, string>()); AreNotEqual(a, new CompositeRange <int, string>(infinite)); AreNotEqual(a, CompositeRange.Create(range1A, range1A)); AreNotEqual(a, CompositeRange.Create(range1B)); AreEqual(a.SubRanges.Count, 1); AreEqual(a.ContainingRange, range1A.WithoutKey()); AreEqual(a.SubRanges[0], range1A); AreNotEqual(a.SubRanges[0], range1B); IsFalse(a.IsEmpty); IsTrue(a.IsNotEmpty); IsTrue(a.IsMerged); a = CompositeRange.Create(range1A, range1B); AreNotEqual(a, CompositeRange <int> .Empty); AreNotEqual(a, CompositeRange <int> .Infinite); AreEqual(a, CompositeRange.Create(range1B, range1A)); AreEqual(a.SubRanges.Count, 2); AreEqual(a.ContainingRange, range1A.WithoutKey()); AreEqual(a.SubRanges[0], range1A); AreEqual(a.SubRanges[1], range1B); IsFalse(a.IsEmpty); IsTrue(a.IsNotEmpty); IsFalse(a.IsMerged); a = CompositeRange.Create(range1A, range2C); AreNotEqual(a, CompositeRange <int> .Empty); AreNotEqual(a, CompositeRange <int> .Infinite); AreEqual(a, CompositeRange.Create(range2C, range1A)); AreEqual(a.SubRanges.Count, 2); AreEqual(a.ContainingRange, Range.Create(1, 3)); AreEqual(a.SubRanges[0], range1A); AreEqual(a.SubRanges[1], range2C); IsFalse(a.IsEmpty); IsTrue(a.IsNotEmpty); IsFalse(a.IsMerged); IsFalse(a.SubRanges[0].HasIntersection(a.SubRanges[1])); IsTrue(a.SubRanges[0].To.GetComplementation() == a.SubRanges[1].From); a = CompositeRange.Create(range1A, range3A); AreNotEqual(a, CompositeRange <int> .Empty); AreNotEqual(a, CompositeRange <int> .Infinite); AreEqual(a, CompositeRange.Create(range3A, range1A)); AreEqual(a.SubRanges.Count, 2); AreEqual(a.ContainingRange, Range.Create(1, 4)); AreEqual(a.SubRanges[0], range1A); AreEqual(a.SubRanges[1], range3A); IsFalse(a.IsEmpty); IsTrue(a.IsNotEmpty); IsTrue(a.IsMerged); }
public static void TestCompositeRangeRangeProperties() { var range1 = Range.Create(1, 2); var range2 = Range.CreateExclusiveFrom(2, 3); var range3 = Range.Create(3, 4); var empty = Range <int> .Empty; var infinite = Range <int> .Infinite; // ReSharper disable once ObjectCreationAsStatement // ReSharper disable once AssignNullToNotNullAttribute Throws <ArgumentNullException>(() => new CompositeRange <int>(null)); var a = new CompositeRange <int>(); AreEqual(a, CompositeRange <int> .Empty); AreEqual(a, CompositeRange.Create(empty, empty)); AreNotEqual(a, CompositeRange <int> .Infinite); AreEqual(a, new CompositeRange <int>()); AreEqual(a.SubRanges.Count, 0); AreEqual(a.ContainingRange, empty); IsTrue(a.IsEmpty); IsFalse(a.IsNotEmpty); IsTrue(a.IsMerged); a = new CompositeRange <int>(infinite); AreNotEqual(a, CompositeRange <int> .Empty); AreEqual(a, CompositeRange <int> .Infinite); AreNotEqual(a, CompositeRange.Create(infinite, infinite)); AreEqual(a.SubRanges.Count, 1); AreEqual(a.ContainingRange, infinite); AreEqual(a.SubRanges[0], infinite); IsFalse(a.IsEmpty); IsTrue(a.IsNotEmpty); IsTrue(a.IsMerged); a = CompositeRange.Create(range1); AreNotEqual(a, CompositeRange <int> .Empty); AreNotEqual(a, CompositeRange <int> .Infinite); AreNotEqual(a, CompositeRange.Create(range1, range1)); AreEqual(a.SubRanges.Count, 1); AreEqual(a.ContainingRange, range1); AreEqual(a.SubRanges[0], range1); IsFalse(a.IsEmpty); IsTrue(a.IsNotEmpty); IsTrue(a.IsMerged); a = CompositeRange.Create(range1, range1); AreNotEqual(a, CompositeRange <int> .Empty); AreNotEqual(a, CompositeRange <int> .Infinite); AreEqual(a, CompositeRange.Create(range1, range1)); AreEqual(a.SubRanges.Count, 2); AreEqual(a.ContainingRange, range1); AreEqual(a.SubRanges[0], range1); AreEqual(a.SubRanges[1], range1); IsFalse(a.IsEmpty); IsTrue(a.IsNotEmpty); IsFalse(a.IsMerged); a = CompositeRange.Create(range1, range2); AreNotEqual(a, CompositeRange <int> .Empty); AreNotEqual(a, CompositeRange <int> .Infinite); AreEqual(a, CompositeRange.Create(range2, range1)); AreEqual(a.SubRanges.Count, 2); AreEqual(a.ContainingRange, Range.Create(1, 3)); AreEqual(a.SubRanges[0], range1); AreEqual(a.SubRanges[1], range2); IsFalse(a.IsEmpty); IsTrue(a.IsNotEmpty); IsFalse(a.IsMerged); IsFalse(a.SubRanges[0].HasIntersection(a.SubRanges[1])); IsTrue(a.SubRanges[0].To.GetComplementation() == a.SubRanges[1].From); a = CompositeRange.Create(range1, range3); AreNotEqual(a, CompositeRange <int> .Empty); AreNotEqual(a, CompositeRange <int> .Infinite); AreEqual(a, CompositeRange.Create(range3, range1)); AreEqual(a.SubRanges.Count, 2); AreEqual(a.ContainingRange, Range.Create(1, 4)); AreEqual(a.SubRanges[0], range1); AreEqual(a.SubRanges[1], range3); IsFalse(a.IsEmpty); IsTrue(a.IsNotEmpty); IsTrue(a.IsMerged); }