llvm / llvm/llvm-project

[clang-tidy] Add check to replace erase-remove idiom with `std::erase` / `std::erase_if`

Open
#189,493 2 comments 0 reactions 1 assignee Claimed by @moar55 View on GitHub
check-request clang-tidy
Dominant language
LLVM
Stars
40.5k
Forks
18.7k
PR merge metrics
PR metrics pending

Description

`clang-tidy` should have a check that recognises the erase-remove idiom and suggests the C++20 replacement: `std::erase` or `std::erase_if`.

Today code like this is still very common:

```cpp
v.erase(std::remove(v.begin(), v.end(), value), v.end());
v.erase(std::remove_if(v.begin(), v.end(), pred), v.end());
```

but in C++20 the better spelling is:

```cpp
std::erase(v, value);
std::erase_if(v, pred);
```

The check should also catch the ranges form:

```cpp
v.erase(std::ranges::remove(v, value).begin(), v.end());
v.erase(std::ranges::remove_if(v, pred).begin(), v.end());
```

and suggest the same replacement.

It would also be useful if the check recognized the canonical manual erase loop for associative containers:

```cpp
for (auto it = m.begin(); it != m.end(); ) {
if (pred(*it))
it = m.erase(it);
else
++it;
}
```

and suggested `std::erase_if(m, pred)` when the loop is purely removing elements and does nothing else.

The main thing is to be conservative. The check should not trigger when the algorithm is applied to only part of the container, when the iterators do not clearly belong to the same container, when a ranges projection is involved, or when a manual loop has extra side effects beyond erasing.

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.