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)); }
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)); }