Пример #1
0
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;
}
Пример #2
0
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;
}