示例#1
0
void deduplicate(std::vector<Replacement> &Replaces,
                 std::vector<Range> &Conflicts) {
    if (Replaces.empty())
        return;

    auto LessNoPath = [](const Replacement &LHS, const Replacement &RHS) {
        if (LHS.getOffset() != RHS.getOffset())
            return LHS.getOffset() < RHS.getOffset();
        if (LHS.getLength() != RHS.getLength())
            return LHS.getLength() < RHS.getLength();
        return LHS.getReplacementText() < RHS.getReplacementText();
    };

    auto EqualNoPath = [](const Replacement &LHS, const Replacement &RHS) {
        return LHS.getOffset() == RHS.getOffset() &&
               LHS.getLength() == RHS.getLength() &&
               LHS.getReplacementText() == RHS.getReplacementText();
    };

    // Deduplicate. We don't want to deduplicate based on the path as we assume
    // that all replacements refer to the same file (or are symlinks).
    std::sort(Replaces.begin(), Replaces.end(), LessNoPath);
    Replaces.erase(std::unique(Replaces.begin(), Replaces.end(), EqualNoPath),
                   Replaces.end());

    // Detect conflicts
    Range ConflictRange(Replaces.front().getOffset(),
                        Replaces.front().getLength());
    unsigned ConflictStart = 0;
    unsigned ConflictLength = 1;
    for (unsigned i = 1; i < Replaces.size(); ++i) {
        Range Current(Replaces[i].getOffset(), Replaces[i].getLength());
        if (ConflictRange.overlapsWith(Current)) {
            // Extend conflicted range
            ConflictRange = Range(ConflictRange.getOffset(),
                                  std::max(ConflictRange.getLength(),
                                           Current.getOffset() + Current.getLength() -
                                           ConflictRange.getOffset()));
            ++ConflictLength;
        } else {
            if (ConflictLength > 1)
                Conflicts.push_back(Range(ConflictStart, ConflictLength));
            ConflictRange = Current;
            ConflictStart = i;
            ConflictLength = 1;
        }
    }

    if (ConflictLength > 1)
        Conflicts.push_back(Range(ConflictStart, ConflictLength));
}
示例#2
0
void deduplicate(std::vector<Replacement> &Replaces,
                 std::vector<Range> &Conflicts) {
  if (Replaces.empty())
    return;

  // Deduplicate
  std::sort(Replaces.begin(), Replaces.end());
  std::vector<Replacement>::iterator End =
      std::unique(Replaces.begin(), Replaces.end());
  Replaces.erase(End, Replaces.end());

  // Detect conflicts
  Range ConflictRange(Replaces.front().getOffset(),
                      Replaces.front().getLength());
  unsigned ConflictStart = 0;
  unsigned ConflictLength = 1;
  for (unsigned i = 1; i < Replaces.size(); ++i) {
    Range Current(Replaces[i].getOffset(), Replaces[i].getLength());
    if (ConflictRange.overlapsWith(Current)) {
      // Extend conflicted range
      ConflictRange = Range(ConflictRange.getOffset(),
                            std::max(ConflictRange.getLength(),
                                     Current.getOffset() + Current.getLength() -
                                         ConflictRange.getOffset()));
      ++ConflictLength;
    } else {
      if (ConflictLength > 1)
        Conflicts.push_back(Range(ConflictStart, ConflictLength));
      ConflictRange = Current;
      ConflictStart = i;
      ConflictLength = 1;
    }
  }

  if (ConflictLength > 1)
    Conflicts.push_back(Range(ConflictStart, ConflictLength));
}