static void coalesce(Value::Ranges* ranges, const Value::Range& range) { // Note that we assume that ranges has already been coalesced. Value::Ranges result; Value::Range temp = range; for (int i = 0; i < ranges->range_size(); i++) { const Value::Range& current = ranges->range(i); // Check if current and range overlap. Note, we only need to // compare with range and not with temp to check for overlap // because we expect ranges to be coalesced to begin with! if (current.begin() <= range.end() && current.end() >= range.begin() ) { // Update temp with new boundaries. temp.set_begin(std::min(range.begin(), current.begin())); temp.set_end(std::max(range.end(), current.end())); } else { // No overlap. result.add_range()->MergeFrom(current); } } result.add_range()->MergeFrom(temp); *ranges = result; }
static void remove(Value::Ranges* ranges, const Value::Range& range) { // Note that we assume that ranges has already been coalesced. Value::Ranges result; for (int i = 0; i < ranges->range_size(); i++) { const Value::Range& current = ranges->range(i); // Note that these if/else if conditionals are in a particular // order. In particular, the last two assume that the "subsumes" // checks have already occured. if (range.begin() <= current.begin() && range.end() >= current.end()) { // Range subsumes current. // current: | | // range: | | // range: | | // range: | | // range: | | } else if (range.begin() >= current.begin() && range.end() <= current.end()) { // Range is subsumed by current. // current: | | // range: | | // range: | | // range: | | ranges::add(&result, current.begin(), range.begin() - 1); ranges::add(&result, range.end() + 1, current.end()); } else if (range.begin() <= current.begin() && range.end() >= current.begin()) { // Range overlaps to the left. // current: | | // range: | | // range: | | ranges::add(&result, range.end() + 1, current.end()); } else if (range.begin() <= current.end() && range.end() >= current.end()) { // Range overlaps to the right. // current: | | // range: | | // range: | | ranges::add(&result, current.begin(), range.begin() - 1); } else { // Range doesn't overlap current. // current: | | // range: | | // range: | | ranges::add(&result, current.begin(), current.end()); } } *ranges = result; }