protected internal virtual void Add(Interval addition)
{
if (@readonly)
{
throw new InvalidOperationException("can't alter readonly IntervalSet");
}
//System.out.println("add "+addition+" to "+intervals.toString());
if (addition.b < addition.a)
{
return;
}
// find position in list
// Use iterators as we modify list in place
for (int i = 0; i < intervals.Count; i++)
{
Interval r = intervals[i];
if (addition.Equals(r))
{
return;
}
if (addition.Adjacent(r) || !addition.Disjoint(r))
{
// next to each other, make a single larger interval
Interval bigger = addition.Union(r);
intervals[i] = bigger;
// make sure we didn't just create an interval that
// should be merged with next interval in list
while (i < intervals.Count - 1)
{
i++;
Interval next = intervals[i];
if (!bigger.Adjacent(next) && bigger.Disjoint(next))
{
break;
}
// if we bump up against or overlap next, merge
intervals.RemoveAt(i);
// remove this one
i--;
// move backwards to what we just set
intervals[i] = bigger.Union(next);
// set to 3 merged ones
}
// first call to next after previous duplicates the result
return;
}
if (addition.StartsBeforeDisjoint(r))
{
// insert before r
intervals.Insert(i, addition);
return;
}
}
// if disjoint and after r, a future iteration will handle it
// ok, must be after last interval (and disjoint from last interval)
// just add it
intervals.Add(addition);
}