* We instead always have 3rdparty/ in the relevant include search paths and rely
on that. Each library still has its own unique base dir within 3rdparty to
clarify where the include is coming from.
When the interval being updated went all the way to the end of the last
interval (UINT64_MAX), `update` would call `mergeLeft` on the `end()` interval.
This would cause `mergeLeft` to dereference an invalid iterator.
Also added a quick return for updating empty intervals, and unit tests to verify
correct handling of empty intervals, which were run both with and without this
optimization.
Also removed some unnecessary asserts that likely called many times. These
asserts could only fail if there was a bug in the `Intervals<T>` implementation,
which should be caught by the unit tests.
When `Intervals<T>::update` was called with `finish=UINT64_MAX`, the loop
condition `i->start() < finish` would remain true for every interval, until `i`
went past the last interval, at which point `i->start()` (and all the other
accesses to `i` within the loop) have undefined behaviuor.