[clang-tools-extra] Add support for std::rotate(_copy) and inplace_merge to modernize-use-ranges (PR #99057)
Nathan James via cfe-commits
cfe-commits at lists.llvm.org
Tue Jul 16 09:29:04 PDT 2024
https://github.com/njames93 created https://github.com/llvm/llvm-project/pull/99057
These algorithms take 3 iterators for the range and we are only interested in the first and last iterator argument. The ranges versions of these take a range and an iterator(defined to be inside the range) so the transformation is pretty similar `algo(I.begin, other, I.end,...)` -> `ranges::algo(I, other,...)`
>From d1fa3d190685a71f23a91dd214bda26a1b701cd2 Mon Sep 17 00:00:00 2001
From: Nathan James <n.james93 at hotmail.co.uk>
Date: Tue, 16 Jul 2024 17:28:01 +0100
Subject: [PATCH] Add support for std::rotate(_copy) and inplace_merge to
modernize-use-ranges
These algorithms take 3 iterators for the range and we are only
interested in the first and last iterator argument.
The ranges versions of these take a range and an iterator(defined to be
inside the range) so the transformation is pretty similar
`algo(I.begin, other, I.end,...)` -> `ranges::algo(I, other,...)`
---
.../clang-tidy/modernize/UseRangesCheck.cpp | 12 +++++++++++-
.../docs/clang-tidy/checks/modernize/use-ranges.rst | 3 +++
.../checkers/modernize/Inputs/use-ranges/fake_std.h | 3 +++
.../clang-tidy/checkers/modernize/use-ranges.cpp | 11 +++++++++++
4 files changed, 28 insertions(+), 1 deletion(-)
diff --git a/clang-tools-extra/clang-tidy/modernize/UseRangesCheck.cpp b/clang-tools-extra/clang-tidy/modernize/UseRangesCheck.cpp
index b0a31ad53be3f..057ec9327d700 100644
--- a/clang-tools-extra/clang-tidy/modernize/UseRangesCheck.cpp
+++ b/clang-tools-extra/clang-tidy/modernize/UseRangesCheck.cpp
@@ -96,6 +96,10 @@ static constexpr const char *TwoRangeNames[] = {
"is_permutation",
};
+static constexpr const char *SinglePivotRangeNames[] = {
+ "rotate","rotate_copy","inplace_merge"
+};
+
namespace {
class StdReplacer : public utils::UseRangesCheck::Replacer {
public:
@@ -141,13 +145,19 @@ utils::UseRangesCheck::ReplacerMap UseRangesCheck::getReplacerMap() const {
// Func(Iter1 first1, Iter1 last1, Iter2 first2, Iter2 last2,...).
static const Signature TwoRangeArgs = {{0}, {2}};
+ // template<typename Iter> Func(Iter first, Iter pivot, Iter last,...).
+ static const Signature SinglePivotRange = {{0, 2}};
+
static const Signature SingleRangeFunc[] = {SingleRangeArgs};
static const Signature TwoRangeFunc[] = {TwoRangeArgs};
+ static const Signature SinglePivotFunc[] = {SinglePivotRange};
+
static const std::pair<ArrayRef<Signature>, ArrayRef<const char *>>
AlgorithmNames[] = {{SingleRangeFunc, SingleRangeNames},
- {TwoRangeFunc, TwoRangeNames}};
+ {TwoRangeFunc, TwoRangeNames},
+ {SinglePivotFunc, SinglePivotRangeNames}};
SmallString<64> Buff;
for (const auto &[Signatures, Values] : AlgorithmNames) {
auto Replacer = llvm::makeIntrusiveRefCnt<StdAlgorithmReplacer>(
diff --git a/clang-tools-extra/docs/clang-tidy/checks/modernize/use-ranges.rst b/clang-tools-extra/docs/clang-tidy/checks/modernize/use-ranges.rst
index 5c0b8058e4535..1ce866ca1f66a 100644
--- a/clang-tools-extra/docs/clang-tidy/checks/modernize/use-ranges.rst
+++ b/clang-tools-extra/docs/clang-tidy/checks/modernize/use-ranges.rst
@@ -46,6 +46,7 @@ Calls to the following std library algorithms are checked:
``std::for_each``,
``std::generate``,
``std::includes``,
+``std::inplace_merge``,
``std::iota``,
``std::is_heap_until``,
``std::is_heap``,
@@ -79,6 +80,8 @@ Calls to the following std library algorithms are checked:
``std::replace``,
``std::reverse_copy``,
``std::reverse``,
+``std::rotate``,
+``std::rotate_copy``,
``std::sample``,
``std::search``,
``std::set_difference``,
diff --git a/clang-tools-extra/test/clang-tidy/checkers/modernize/Inputs/use-ranges/fake_std.h b/clang-tools-extra/test/clang-tidy/checkers/modernize/Inputs/use-ranges/fake_std.h
index 987ee4e35b3bc..6596511c7a38b 100644
--- a/clang-tools-extra/test/clang-tidy/checkers/modernize/Inputs/use-ranges/fake_std.h
+++ b/clang-tools-extra/test/clang-tidy/checkers/modernize/Inputs/use-ranges/fake_std.h
@@ -106,6 +106,9 @@ bool equal(InputIt1 first1, InputIt1 last1,
template <class ForwardIt, class T>
void iota(ForwardIt first, ForwardIt last, T value);
+template <class ForwardIt>
+ForwardIt rotate(ForwardIt first, ForwardIt middle, ForwardIt last);
+
} // namespace std
#endif // USE_RANGES_FAKE_STD_H
diff --git a/clang-tools-extra/test/clang-tidy/checkers/modernize/use-ranges.cpp b/clang-tools-extra/test/clang-tidy/checkers/modernize/use-ranges.cpp
index e937e1e4e7d3b..b022efebfdf4d 100644
--- a/clang-tools-extra/test/clang-tidy/checkers/modernize/use-ranges.cpp
+++ b/clang-tools-extra/test/clang-tidy/checkers/modernize/use-ranges.cpp
@@ -57,6 +57,10 @@ void Positives() {
// CHECK-MESSAGES-CPP23: :[[@LINE-1]]:3: warning: use a ranges version of this algorithm
// CHECK-FIXES-CPP23: std::ranges::iota(I, 0);
+ std::rotate(I.begin(), I.begin() + 2, I.end());
+ // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use a ranges version of this algorithm
+ // CHECK-FIXES: std::ranges::rotate(I, I.begin() + 2);
+
using std::find;
namespace my_std = std;
@@ -100,4 +104,11 @@ void Negatives() {
std::equal(I.begin(), I.end(), J.end(), J.end());
std::equal(std::rbegin(I), std::rend(I), std::rend(J), std::rbegin(J));
std::equal(I.begin(), J.end(), I.begin(), I.end());
+
+ // std::rotate expects the full range in the 1st and 3rd argument.
+ // Anyone writing this code has probably written a bug, but this isn't the
+ // purpose of this check.
+ std::rotate(I.begin(), I.end(), I.begin() + 2);
+ // Pathological, but probably shouldn't diagnose this
+ std::rotate(I.begin(), I.end(), I.end() + 0);
}
More information about the cfe-commits
mailing list