Simplify Evoral::RangeList::subtract(), and make it pass amended tests

The various conditionals in Evoral::RangeList::subtract() appear to have
been there to work around
 (a) coverage() not always returning the correct value, &
 (b) the test suite assuming that the ->to point lies outside the range

Now that these are both fixed, the implementation of subtract() becomes
quite a bit clearer. I replaced the if()s with assert()s for now, but these
shouldn't trip if coverage() is working as I expect.

Also (attempt to) clarify the comments in subtract.
This commit is contained in:
Colin Fletcher 2014-11-23 19:16:42 +00:00
parent 30a9c2d05b
commit dd5fc9432f

View file

@ -196,7 +196,7 @@ template<typename T>
struct /*LIBEVORAL_API*/ Range { struct /*LIBEVORAL_API*/ Range {
Range (T f, T t) : from (f), to (t) {} Range (T f, T t) : from (f), to (t) {}
T from; ///< start of the range T from; ///< start of the range
T to; ///< end of the range T to; ///< end of the range (inclusive: to lies inside the range)
}; };
template<typename T> template<typename T>
@ -297,28 +297,33 @@ RangeList<T> subtract (Range<T> range, RangeList<T> sub)
switch (coverage (j->from, j->to, i->from, i->to)) { switch (coverage (j->from, j->to, i->from, i->to)) {
case OverlapNone: case OverlapNone:
/* The thing we're subtracting does not overlap this bit of the result, /* The thing we're subtracting (*i) does not overlap this bit of the result (*j),
so pass it through. so pass it through.
*/ */
new_result.add (*j); new_result.add (*j);
break; break;
case OverlapInternal: case OverlapInternal:
/* Internal overlap of the thing we're subtracting from this bit of the result, /* Internal overlap of the thing we're subtracting (*i) from this bit of the result,
so we might end up with two bits left over. so we should end up with two bits of (*j) left over, from the start of (*j) to
the start of (*i), and from the end of (*i) to the end of (*j).
*/ */
if (j->from < (i->from - 1)) { assert (j->from < i->from);
new_result.add (Range<T> (j->from, i->from - 1)); assert (j->to > i->to);
} new_result.add (Range<T> (j->from, i->from - 1));
if (j->to != i->to) { new_result.add (Range<T> (i->to + 1, j->to));
new_result.add (Range<T> (i->to, j->to));
}
break; break;
case OverlapStart: case OverlapStart:
/* The bit we're subtracting overlaps the start of the bit of the result */ /* The bit we're subtracting (*i) overlaps the start of the bit of the result (*j),
new_result.add (Range<T> (i->to, j->to - 1)); * so we keep only the part of of (*j) from after the end of (*i)
*/
assert (i->to < j->to);
new_result.add (Range<T> (i->to + 1, j->to));
break; break;
case OverlapEnd: case OverlapEnd:
/* The bit we're subtracting overlaps the end of the bit of the result */ /* The bit we're subtracting (*i) overlaps the end of the bit of the result (*j),
* so we keep only the part of of (*j) from before the start of (*i)
*/
assert (j->from < i->from);
new_result.add (Range<T> (j->from, i->from - 1)); new_result.add (Range<T> (j->from, i->from - 1));
break; break;
case OverlapExternal: case OverlapExternal: