/// <summary> /// Creates a new LongSet where val is added to each element of this LongSet. /// </summary> public LongSet AddOffset(long val) { if (val == 0) { return(this); } var newIntervals = new List <LongInterval>(Intervals.Length + 1); foreach (var element in Intervals) { long newStart = unchecked (element.Start + val); long newInclusiveEnd = unchecked (element.InclusiveEnd + val); if (newStart <= newInclusiveEnd) { newIntervals.Add(LongInterval.Inclusive(newStart, newInclusiveEnd)); } else { // interval got split by integer overflow newIntervals.Add(LongInterval.Inclusive(newStart, long.MaxValue)); newIntervals.Add(LongInterval.Inclusive(long.MinValue, newInclusiveEnd)); } } newIntervals.Sort((a, b) => a.Start.CompareTo(b.Start)); return(new LongSet(MergeOverlapping(newIntervals).ToImmutableArray())); }
IEnumerable <LongInterval> DoIntersectWith(LongSet other) { var enumA = this.Intervals.GetEnumerator(); var enumB = other.Intervals.GetEnumerator(); bool moreA = enumA.MoveNext(); bool moreB = enumB.MoveNext(); while (moreA && moreB) { LongInterval a = enumA.Current; LongInterval b = enumB.Current; LongInterval intersection = a.Intersect(b); if (!intersection.IsEmpty) { yield return(intersection); } if (a.InclusiveEnd < b.InclusiveEnd) { moreA = enumA.MoveNext(); } else { moreB = enumB.MoveNext(); } } }
internal int upper_bound(long val) { int min = 0, max = Intervals.Length - 1; while (max >= min) { int m = min + (max - min) / 2; LongInterval i = Intervals[m]; if (val < i.Start) { max = m - 1; continue; } if (val > i.End) { min = m + 1; continue; } return(m + 1); } return(min); }
/// <summary> /// Create a new LongSet that contains the values from the interval. /// </summary> public LongSet(LongInterval interval) : this(interval.IsEmpty ? Empty.Intervals : ImmutableArray.Create(interval)) { }
/// <summary> /// Create a new LongSet that contains a single value. /// </summary> public LongSet(long value) : this(ImmutableArray.Create(LongInterval.Inclusive(value, value))) { }