From c3431c0bedb23feac279efa43b51740353dcab8d Mon Sep 17 00:00:00 2001 From: Nathan James Date: Fri, 12 Jul 2024 23:04:42 +0100 Subject: [PATCH] Allow specifying pipe syntax for use-ranges checks Add `UseReversePipe` option to (boost|modernize)-use-ranges checks. This controls whether to create a reverse view using function syntax (`reverse(Range)`) or pipe syntax (`Range | reverse`) --- .../clang-tidy/boost/UseRangesCheck.cpp | 15 ++- .../clang-tidy/boost/UseRangesCheck.h | 1 + .../clang-tidy/modernize/UseRangesCheck.cpp | 13 +- .../clang-tidy/modernize/UseRangesCheck.h | 7 +- .../clang-tidy/utils/UseRangesCheck.cpp | 18 +-- .../clang-tidy/utils/UseRangesCheck.h | 1 + .../clang-tidy/checks/boost/use-ranges.rst | 19 ++- .../checks/modernize/use-ranges.rst | 18 ++- .../boost/Inputs/use-ranges/fake_boost.h | 29 +++++ .../boost/Inputs/use-ranges/fake_std.h | 99 +++++++++++++++ .../checkers/boost/use-ranges-pipe.cpp | 18 +++ .../clang-tidy/checkers/boost/use-ranges.cpp | 111 +---------------- .../modernize/Inputs/use-ranges/fake_std.h | 111 +++++++++++++++++ .../checkers/modernize/use-ranges-pipe.cpp | 18 +++ .../checkers/modernize/use-ranges.cpp | 117 +----------------- 15 files changed, 358 insertions(+), 237 deletions(-) create mode 100644 clang-tools-extra/test/clang-tidy/checkers/boost/Inputs/use-ranges/fake_boost.h create mode 100644 clang-tools-extra/test/clang-tidy/checkers/boost/Inputs/use-ranges/fake_std.h create mode 100644 clang-tools-extra/test/clang-tidy/checkers/boost/use-ranges-pipe.cpp create mode 100644 clang-tools-extra/test/clang-tidy/checkers/modernize/Inputs/use-ranges/fake_std.h create mode 100644 clang-tools-extra/test/clang-tidy/checkers/modernize/use-ranges-pipe.cpp diff --git a/clang-tools-extra/clang-tidy/boost/UseRangesCheck.cpp b/clang-tools-extra/clang-tidy/boost/UseRangesCheck.cpp index 9351a1c90ae54..4022ea0cdaf5e 100644 --- a/clang-tools-extra/clang-tidy/boost/UseRangesCheck.cpp +++ b/clang-tools-extra/clang-tidy/boost/UseRangesCheck.cpp @@ -331,12 +331,15 @@ utils::UseRangesCheck::ReplacerMap UseRangesCheck::getReplacerMap() const { UseRangesCheck::UseRangesCheck(StringRef Name, ClangTidyContext *Context) : utils::UseRangesCheck(Name, Context), - IncludeBoostSystem(Options.get("IncludeBoostSystem", true)) {} + IncludeBoostSystem(Options.get("IncludeBoostSystem", true)), + UseReversePipe(Options.get("UseReversePipe", false)) {} void UseRangesCheck::storeOptions(ClangTidyOptions::OptionMap &Opts) { utils::UseRangesCheck::storeOptions(Opts); Options.store(Opts, "IncludeBoostSystem", IncludeBoostSystem); + Options.store(Opts, "UseReversePipe", UseReversePipe); } + DiagnosticBuilder UseRangesCheck::createDiag(const CallExpr &Call) { DiagnosticBuilder D = diag(Call.getBeginLoc(), "use a %0 version of this algorithm"); @@ -362,10 +365,10 @@ UseRangesCheck::getReverseDescriptor() const { {"::boost::rbegin", "::boost::rend"}, {"::boost::const_rbegin", "::boost::const_rend"}, }; - return ReverseIteratorDescriptor{"boost::adaptors::reverse", - IncludeBoostSystem - ? "" - : "boost/range/adaptor/reversed.hpp", - Refs}; + return ReverseIteratorDescriptor{ + UseReversePipe ? "boost::adaptors::reversed" : "boost::adaptors::reverse", + IncludeBoostSystem ? "" + : "boost/range/adaptor/reversed.hpp", + Refs, UseReversePipe}; } } // namespace clang::tidy::boost diff --git a/clang-tools-extra/clang-tidy/boost/UseRangesCheck.h b/clang-tools-extra/clang-tidy/boost/UseRangesCheck.h index a59ced12a6c43..b081c4c479b92 100644 --- a/clang-tools-extra/clang-tidy/boost/UseRangesCheck.h +++ b/clang-tools-extra/clang-tidy/boost/UseRangesCheck.h @@ -36,6 +36,7 @@ class UseRangesCheck : public utils::UseRangesCheck { private: bool IncludeBoostSystem; + bool UseReversePipe; }; } // namespace clang::tidy::boost diff --git a/clang-tools-extra/clang-tidy/modernize/UseRangesCheck.cpp b/clang-tools-extra/clang-tidy/modernize/UseRangesCheck.cpp index 5c7b315f43173..b0a31ad53be3f 100644 --- a/clang-tools-extra/clang-tidy/modernize/UseRangesCheck.cpp +++ b/clang-tools-extra/clang-tidy/modernize/UseRangesCheck.cpp @@ -166,6 +166,15 @@ utils::UseRangesCheck::ReplacerMap UseRangesCheck::getReplacerMap() const { return Result; } +UseRangesCheck::UseRangesCheck(StringRef Name, ClangTidyContext *Context) + : utils::UseRangesCheck(Name, Context), + UseReversePipe(Options.get("UseReversePipe", false)) {} + +void UseRangesCheck::storeOptions(ClangTidyOptions::OptionMap &Opts) { + utils::UseRangesCheck::storeOptions(Opts); + Options.store(Opts, "UseReversePipe", UseReversePipe); +} + bool UseRangesCheck::isLanguageVersionSupported( const LangOptions &LangOpts) const { return LangOpts.CPlusPlus20; @@ -180,6 +189,8 @@ std::optional UseRangesCheck::getReverseDescriptor() const { static const std::pair Refs[] = { {"::std::rbegin", "::std::rend"}, {"::std::crbegin", "::std::crend"}}; - return ReverseIteratorDescriptor{"std::views::reverse", "", Refs}; + return ReverseIteratorDescriptor{UseReversePipe ? "std::views::reverse" + : "std::ranges::reverse_view", + "", Refs, UseReversePipe}; } } // namespace clang::tidy::modernize diff --git a/clang-tools-extra/clang-tidy/modernize/UseRangesCheck.h b/clang-tools-extra/clang-tidy/modernize/UseRangesCheck.h index 2f7613dd1cd24..2f4cace653cf1 100644 --- a/clang-tools-extra/clang-tidy/modernize/UseRangesCheck.h +++ b/clang-tools-extra/clang-tidy/modernize/UseRangesCheck.h @@ -20,7 +20,9 @@ namespace clang::tidy::modernize { /// http://clang.llvm.org/extra/clang-tidy/checks/modernize/use-ranges.html class UseRangesCheck : public utils::UseRangesCheck { public: - using utils::UseRangesCheck::UseRangesCheck; + UseRangesCheck(StringRef CheckName, ClangTidyContext *Context); + + void storeOptions(ClangTidyOptions::OptionMap &Options) override; ReplacerMap getReplacerMap() const override; @@ -31,6 +33,9 @@ class UseRangesCheck : public utils::UseRangesCheck { getReverseDescriptor() const override; bool isLanguageVersionSupported(const LangOptions &LangOpts) const override; + +private: + bool UseReversePipe; }; } // namespace clang::tidy::modernize diff --git a/clang-tools-extra/clang-tidy/utils/UseRangesCheck.cpp b/clang-tools-extra/clang-tidy/utils/UseRangesCheck.cpp index 9c59e4651953a..e2daa5010e2ae 100644 --- a/clang-tools-extra/clang-tidy/utils/UseRangesCheck.cpp +++ b/clang-tools-extra/clang-tidy/utils/UseRangesCheck.cpp @@ -242,16 +242,20 @@ void UseRangesCheck::check(const MatchFinder::MatchResult &Result) { Diag << Inserter.createIncludeInsertion( Result.SourceManager->getFileID(Call->getBeginLoc()), *ReverseDescriptor->ReverseHeader); + StringRef ArgText = Lexer::getSourceText( + CharSourceRange::getTokenRange(ArgExpr->getSourceRange()), + Result.Context->getSourceManager(), Result.Context->getLangOpts()); + SmallString<128> ReplaceText; + if (ReverseDescriptor->IsPipeSyntax) + ReplaceText.assign( + {ArgText, " | ", ReverseDescriptor->ReverseAdaptorName}); + else + ReplaceText.assign( + {ReverseDescriptor->ReverseAdaptorName, "(", ArgText, ")"}); Diag << FixItHint::CreateReplacement( Call->getArg(Replace == Indexes::Second ? Second : First) ->getSourceRange(), - SmallString<128>{ - ReverseDescriptor->ReverseAdaptorName, "(", - Lexer::getSourceText( - CharSourceRange::getTokenRange(ArgExpr->getSourceRange()), - Result.Context->getSourceManager(), - Result.Context->getLangOpts()), - ")"}); + ReplaceText); } ToRemove.push_back(Replace == Indexes::Second ? First : Second); } diff --git a/clang-tools-extra/clang-tidy/utils/UseRangesCheck.h b/clang-tools-extra/clang-tidy/utils/UseRangesCheck.h index 8227d8f7bbbdd..927e9694b0ec7 100644 --- a/clang-tools-extra/clang-tidy/utils/UseRangesCheck.h +++ b/clang-tools-extra/clang-tidy/utils/UseRangesCheck.h @@ -38,6 +38,7 @@ class UseRangesCheck : public ClangTidyCheck { StringRef ReverseAdaptorName; std::optional ReverseHeader; ArrayRef> FreeReverseNames; + bool IsPipeSyntax = false; }; class Replacer : public llvm::RefCountedBase { diff --git a/clang-tools-extra/docs/clang-tidy/checks/boost/use-ranges.rst b/clang-tools-extra/docs/clang-tidy/checks/boost/use-ranges.rst index 39be52fdcf7b9..4c032ad32f4fd 100644 --- a/clang-tools-extra/docs/clang-tidy/checks/boost/use-ranges.rst +++ b/clang-tools-extra/docs/clang-tidy/checks/boost/use-ranges.rst @@ -154,8 +154,8 @@ Transforms to: .. code-block:: c++ - auto AreSame = std::equal(boost::adaptors::reverse(Items1), - boost::adaptors::reverse(Items2)); + auto AreSame = boost::range::equal(boost::adaptors::reverse(Items1), + boost::adaptors::reverse(Items2)); Options ------- @@ -170,3 +170,18 @@ Options If `true` (default value) the boost headers are included as system headers with angle brackets (`#include `), otherwise quotes are used (`#include "boost.hpp"`). + +.. option:: UseReversePipe + + When `true` (default `false`), fixes which involve reverse ranges will use the + pipe adaptor syntax instead of the function syntax. + + .. code-block:: c++ + + std::find(Items.rbegin(), Items.rend(), 0); + + Transforms to: + + .. code-block:: c++ + + boost::range::find(Items | boost::adaptors::reversed, 0); 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 86af6b0eeb8e0..5c0b8058e4535 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 @@ -116,8 +116,8 @@ Transforms to: .. code-block:: c++ - auto AreSame = std::equal(std::views::reverse(Items1), - std::views::reverse(Items2)); + auto AreSame = std::ranges::equal(std::ranges::reverse_view(Items1), + std::ranges::reverse_view(Items2)); Options ------- @@ -127,3 +127,17 @@ Options A string specifying which include-style is used, `llvm` or `google`. Default is `llvm`. +.. option:: UseReversePipe + + When `true` (default `false`), fixes which involve reverse ranges will use the + pipe adaptor syntax instead of the function syntax. + + .. code-block:: c++ + + std::find(Items.rbegin(), Items.rend(), 0); + + Transforms to: + + .. code-block:: c++ + + std::ranges::find(Items | std::views::reverse, 0); diff --git a/clang-tools-extra/test/clang-tidy/checkers/boost/Inputs/use-ranges/fake_boost.h b/clang-tools-extra/test/clang-tidy/checkers/boost/Inputs/use-ranges/fake_boost.h new file mode 100644 index 0000000000000..3664367a60110 --- /dev/null +++ b/clang-tools-extra/test/clang-tidy/checkers/boost/Inputs/use-ranges/fake_boost.h @@ -0,0 +1,29 @@ +#ifndef USE_RANGES_FAKE_BOOST_H +#define USE_RANGES_FAKE_BOOST_H + +namespace boost { +namespace range_adl_barrier { + +template void *begin(T &); +template void *end(T &); +template void *const_begin(const T &); +template void *const_end(const T &); +} // namespace range_adl_barrier + +using namespace range_adl_barrier; + +template void *rbegin(T &); +template void *rend(T &); + +template void *const_rbegin(T &); +template void *const_rend(T &); +namespace algorithm { + +template +T reduce(InputIterator first, InputIterator last, T init, BinaryOperation bOp) { + return init; +} +} // namespace algorithm +} // namespace boost + +#endif // USE_RANGES_FAKE_BOOST_H diff --git a/clang-tools-extra/test/clang-tidy/checkers/boost/Inputs/use-ranges/fake_std.h b/clang-tools-extra/test/clang-tidy/checkers/boost/Inputs/use-ranges/fake_std.h new file mode 100644 index 0000000000000..7c3e39d6000d2 --- /dev/null +++ b/clang-tools-extra/test/clang-tidy/checkers/boost/Inputs/use-ranges/fake_std.h @@ -0,0 +1,99 @@ +#ifndef USE_RANGES_FAKE_STD_H +#define USE_RANGES_FAKE_STD_H +namespace std { + +template class vector { +public: + using iterator = T *; + using const_iterator = const T *; + using reverse_iterator = T*; + using reverse_const_iterator = const T*; + + constexpr const_iterator begin() const; + constexpr const_iterator end() const; + constexpr const_iterator cbegin() const; + constexpr const_iterator cend() const; + constexpr iterator begin(); + constexpr iterator end(); + constexpr reverse_const_iterator rbegin() const; + constexpr reverse_const_iterator rend() const; + constexpr reverse_const_iterator crbegin() const; + constexpr reverse_const_iterator crend() const; + constexpr reverse_iterator rbegin(); + constexpr reverse_iterator rend(); +}; + +template constexpr auto begin(const Container &Cont) { + return Cont.begin(); +} + +template constexpr auto begin(Container &Cont) { + return Cont.begin(); +} + +template constexpr auto end(const Container &Cont) { + return Cont.end(); +} + +template constexpr auto end(Container &Cont) { + return Cont.end(); +} + +template constexpr auto cbegin(const Container &Cont) { + return Cont.cbegin(); +} + +template constexpr auto cend(const Container &Cont) { + return Cont.cend(); +} +// Find +template< class InputIt, class T > +InputIt find(InputIt first, InputIt last, const T& value); + +template void reverse(Iter begin, Iter end); + +template +bool includes(InputIt1 first1, InputIt1 last1, InputIt2 first2, InputIt2 last2); + +template +bool is_permutation(ForwardIt1 first1, ForwardIt1 last1, ForwardIt2 first2, + ForwardIt2 last2); + +template +bool next_permutation(BidirIt first, BidirIt last); + +inline namespace inline_test{ + +template +bool equal(ForwardIt1 first1, ForwardIt1 last1, + ForwardIt2 first2, ForwardIt2 last2); + +template +void push_heap(RandomIt first, RandomIt last); + +template +OutputIt copy_if(InputIt first, InputIt last, OutputIt d_first, UnaryPred pred); + +template +ForwardIt is_sorted_until(ForwardIt first, ForwardIt last); + +template +void reduce(InputIt first, InputIt last); + +template +T reduce(InputIt first, InputIt last, T init); + +template +T reduce(InputIt first, InputIt last, T init, BinaryOp op) { + // Need a definition to suppress undefined_internal_type when invoked with lambda + return init; +} + +template +T accumulate(InputIt first, InputIt last, T init); + +} // namespace inline_test + +} // namespace std + +#endif // USE_RANGES_FAKE_STD_H diff --git a/clang-tools-extra/test/clang-tidy/checkers/boost/use-ranges-pipe.cpp b/clang-tools-extra/test/clang-tidy/checkers/boost/use-ranges-pipe.cpp new file mode 100644 index 0000000000000..c0ce374840098 --- /dev/null +++ b/clang-tools-extra/test/clang-tidy/checkers/boost/use-ranges-pipe.cpp @@ -0,0 +1,18 @@ +// RUN: %check_clang_tidy -std=c++14 %s boost-use-ranges %t -check-suffixes=,PIPE \ +// RUN: -config="{CheckOptions: { \ +// RUN: boost-use-ranges.UseReversePipe: true }}" -- -I %S/Inputs/use-ranges/ +// RUN: %check_clang_tidy -std=c++14 %s boost-use-ranges %t -check-suffixes=,NOPIPE -- -I %S/Inputs/use-ranges/ + +// CHECK-FIXES: #include +// CHECK-FIXES: #include + +#include "fake_std.h" + +void stdLib() { + std::vector I; + std::is_sorted_until(I.rbegin(), I.rend()); + // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use a boost version of this algorithm + // CHECK-FIXES-NOPIPE: boost::algorithm::is_sorted_until(boost::adaptors::reverse(I)); + // CHECK-FIXES-PIPE: boost::algorithm::is_sorted_until(I | boost::adaptors::reversed); + +} diff --git a/clang-tools-extra/test/clang-tidy/checkers/boost/use-ranges.cpp b/clang-tools-extra/test/clang-tidy/checkers/boost/use-ranges.cpp index 3f3d6f1abec9f..06e70267da83a 100644 --- a/clang-tools-extra/test/clang-tidy/checkers/boost/use-ranges.cpp +++ b/clang-tools-extra/test/clang-tidy/checkers/boost/use-ranges.cpp @@ -1,5 +1,5 @@ -// RUN: %check_clang_tidy -std=c++14 %s boost-use-ranges %t -// RUN: %check_clang_tidy -std=c++17 %s boost-use-ranges %t -check-suffixes=,CPP17 +// RUN: %check_clang_tidy -std=c++14 %s boost-use-ranges %t -- -- -I %S/Inputs/use-ranges/ +// RUN: %check_clang_tidy -std=c++17 %s boost-use-ranges %t -check-suffixes=,CPP17 -- -I %S/Inputs/use-ranges/ // CHECK-FIXES: #include // CHECK-FIXES: #include @@ -13,111 +13,8 @@ // CHECK-FIXES: #include // CHECK-FIXES: #include -namespace std { - -template class vector { -public: - using iterator = T *; - using const_iterator = const T *; - constexpr const_iterator begin() const; - constexpr const_iterator end() const; - constexpr const_iterator cbegin() const; - constexpr const_iterator cend() const; - constexpr iterator begin(); - constexpr iterator end(); -}; - -template constexpr auto begin(const Container &Cont) { - return Cont.begin(); -} - -template constexpr auto begin(Container &Cont) { - return Cont.begin(); -} - -template constexpr auto end(const Container &Cont) { - return Cont.end(); -} - -template constexpr auto end(Container &Cont) { - return Cont.end(); -} - -template constexpr auto cbegin(const Container &Cont) { - return Cont.cbegin(); -} - -template constexpr auto cend(const Container &Cont) { - return Cont.cend(); -} -// Find -template< class InputIt, class T > -InputIt find(InputIt first, InputIt last, const T& value); - -template void reverse(Iter begin, Iter end); - -template -bool includes(InputIt1 first1, InputIt1 last1, InputIt2 first2, InputIt2 last2); - -template -bool is_permutation(ForwardIt1 first1, ForwardIt1 last1, ForwardIt2 first2, - ForwardIt2 last2); - -template -bool next_permutation(BidirIt first, BidirIt last); - -template -bool equal(ForwardIt1 first1, ForwardIt1 last1, - ForwardIt2 first2, ForwardIt2 last2); - -template -void push_heap(RandomIt first, RandomIt last); - -template -OutputIt copy_if(InputIt first, InputIt last, OutputIt d_first, UnaryPred pred); - -template -ForwardIt is_sorted_until(ForwardIt first, ForwardIt last); - -template -void reduce(InputIt first, InputIt last); - -template -T reduce(InputIt first, InputIt last, T init); - -template -T reduce(InputIt first, InputIt last, T init, BinaryOp op) { - // Need a definition to suppress undefined_internal_type when invoked with lambda - return init; -} - -template -T accumulate(InputIt first, InputIt last, T init); - -} // namespace std - -namespace boost { -namespace range_adl_barrier { -template void *begin(T &); -template void *end(T &); -template void *const_begin(const T &); -template void *const_end(const T &); -} // namespace range_adl_barrier -using namespace range_adl_barrier; - -template void *rbegin(T &); -template void *rend(T &); - -template void *const_rbegin(T &); -template void *const_rend(T &); -namespace algorithm { - -template -T reduce(InputIterator first, InputIterator last, T init, BinaryOperation bOp) { - return init; -} -} // namespace algorithm -} // namespace boost +#include "fake_boost.h" +#include "fake_std.h" bool returnTrue(int val) { return true; 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 new file mode 100644 index 0000000000000..987ee4e35b3bc --- /dev/null +++ b/clang-tools-extra/test/clang-tidy/checkers/modernize/Inputs/use-ranges/fake_std.h @@ -0,0 +1,111 @@ +#ifndef USE_RANGES_FAKE_STD_H +#define USE_RANGES_FAKE_STD_H + +namespace std { + +template class vector { +public: + using iterator = T *; + using const_iterator = const T *; + using reverse_iterator = T*; + using reverse_const_iterator = const T*; + + constexpr const_iterator begin() const; + constexpr const_iterator end() const; + constexpr const_iterator cbegin() const; + constexpr const_iterator cend() const; + constexpr iterator begin(); + constexpr iterator end(); + constexpr reverse_const_iterator rbegin() const; + constexpr reverse_const_iterator rend() const; + constexpr reverse_const_iterator crbegin() const; + constexpr reverse_const_iterator crend() const; + constexpr reverse_iterator rbegin(); + constexpr reverse_iterator rend(); +}; + +template constexpr auto begin(const Container &Cont) { + return Cont.begin(); +} + +template constexpr auto begin(Container &Cont) { + return Cont.begin(); +} + +template constexpr auto end(const Container &Cont) { + return Cont.end(); +} + +template constexpr auto end(Container &Cont) { + return Cont.end(); +} + +template constexpr auto cbegin(const Container &Cont) { + return Cont.cbegin(); +} + +template constexpr auto cend(const Container &Cont) { + return Cont.cend(); +} + +template constexpr auto rbegin(const Container &Cont) { + return Cont.rbegin(); +} + +template constexpr auto rbegin(Container &Cont) { + return Cont.rbegin(); +} + +template constexpr auto rend(const Container &Cont) { + return Cont.rend(); +} + +template constexpr auto rend(Container &Cont) { + return Cont.rend(); +} + +template constexpr auto crbegin(const Container &Cont) { + return Cont.crbegin(); +} + +template constexpr auto crend(const Container &Cont) { + return Cont.crend(); +} +// Find +template< class InputIt, class T > +InputIt find( InputIt first, InputIt last, const T& value ); + +// Reverse +template void reverse(Iter begin, Iter end); + +// Includes +template +bool includes(InputIt1 first1, InputIt1 last1, InputIt2 first2, InputIt2 last2); + +// IsPermutation +template +bool is_permutation(ForwardIt1 first1, ForwardIt1 last1, ForwardIt2 first2); +template +bool is_permutation(ForwardIt1 first1, ForwardIt1 last1, ForwardIt2 first2, + ForwardIt2 last2); + +// Equal +template +bool equal(InputIt1 first1, InputIt1 last1, InputIt2 first2); + +template +bool equal(InputIt1 first1, InputIt1 last1, InputIt2 first2, InputIt2 last2); + +template +bool equal(InputIt1 first1, InputIt1 last1, + InputIt2 first2, InputIt2 last2, BinaryPred p) { + // Need a definition to suppress undefined_internal_type when invoked with lambda + return true; +} + +template +void iota(ForwardIt first, ForwardIt last, T value); + +} // namespace std + +#endif // USE_RANGES_FAKE_STD_H diff --git a/clang-tools-extra/test/clang-tidy/checkers/modernize/use-ranges-pipe.cpp b/clang-tools-extra/test/clang-tidy/checkers/modernize/use-ranges-pipe.cpp new file mode 100644 index 0000000000000..f53fb70427e2d --- /dev/null +++ b/clang-tools-extra/test/clang-tidy/checkers/modernize/use-ranges-pipe.cpp @@ -0,0 +1,18 @@ +// RUN: %check_clang_tidy -std=c++20 %s modernize-use-ranges %t -check-suffixes=,PIPE \ +// RUN: -config="{CheckOptions: { \ +// RUN: modernize-use-ranges.UseReversePipe: true }}" -- -I %S/Inputs/use-ranges/ +// RUN: %check_clang_tidy -std=c++20 %s modernize-use-ranges %t -check-suffixes=,NOPIPE -- -I %S/Inputs/use-ranges/ + +// CHECK-FIXES: #include +// CHECK-FIXES: #include + +#include "fake_std.h" + +void stdLib() { + std::vector I; + std::find(I.rbegin(), I.rend(), 0); + // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use a ranges version of this algorithm + // CHECK-FIXES-NOPIPE: std::ranges::find(std::ranges::reverse_view(I), 0); + // CHECK-FIXES-PIPE: std::ranges::find(I | std::views::reverse, 0); + +} 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 623af26e3cdc7..e937e1e4e7d3b 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 @@ -1,116 +1,11 @@ -// RUN: %check_clang_tidy -std=c++20 %s modernize-use-ranges %t -// RUN: %check_clang_tidy -std=c++23 %s modernize-use-ranges %t -check-suffixes=,CPP23 +// RUN: %check_clang_tidy -std=c++20 %s modernize-use-ranges %t -- -- -I %S/Inputs/use-ranges/ +// RUN: %check_clang_tidy -std=c++23 %s modernize-use-ranges %t -check-suffixes=,CPP23 -- -I %S/Inputs/use-ranges/ // CHECK-FIXES: #include // CHECK-FIXES-CPP23: #include // CHECK-FIXES: #include -namespace std { - -template class vector { -public: - using iterator = T *; - using const_iterator = const T *; - using reverse_iterator = T*; - using reverse_const_iterator = const T*; - - constexpr const_iterator begin() const; - constexpr const_iterator end() const; - constexpr const_iterator cbegin() const; - constexpr const_iterator cend() const; - constexpr iterator begin(); - constexpr iterator end(); - constexpr reverse_const_iterator rbegin() const; - constexpr reverse_const_iterator rend() const; - constexpr reverse_const_iterator crbegin() const; - constexpr reverse_const_iterator crend() const; - constexpr reverse_iterator rbegin(); - constexpr reverse_iterator rend(); -}; - -template constexpr auto begin(const Container &Cont) { - return Cont.begin(); -} - -template constexpr auto begin(Container &Cont) { - return Cont.begin(); -} - -template constexpr auto end(const Container &Cont) { - return Cont.end(); -} - -template constexpr auto end(Container &Cont) { - return Cont.end(); -} - -template constexpr auto cbegin(const Container &Cont) { - return Cont.cbegin(); -} - -template constexpr auto cend(const Container &Cont) { - return Cont.cend(); -} - -template constexpr auto rbegin(const Container &Cont) { - return Cont.rbegin(); -} - -template constexpr auto rbegin(Container &Cont) { - return Cont.rbegin(); -} - -template constexpr auto rend(const Container &Cont) { - return Cont.rend(); -} - -template constexpr auto rend(Container &Cont) { - return Cont.rend(); -} - -template constexpr auto crbegin(const Container &Cont) { - return Cont.crbegin(); -} - -template constexpr auto crend(const Container &Cont) { - return Cont.crend(); -} -// Find -template< class InputIt, class T > -InputIt find( InputIt first, InputIt last, const T& value ); - -// Reverse -template void reverse(Iter begin, Iter end); - -// Includes -template -bool includes(InputIt1 first1, InputIt1 last1, InputIt2 first2, InputIt2 last2); - -// IsPermutation -template -bool is_permutation(ForwardIt1 first1, ForwardIt1 last1, ForwardIt2 first2); -template -bool is_permutation(ForwardIt1 first1, ForwardIt1 last1, ForwardIt2 first2, - ForwardIt2 last2); - -// Equal -template -bool equal(InputIt1 first1, InputIt1 last1, InputIt2 first2); - -template -bool equal(InputIt1 first1, InputIt1 last1, InputIt2 first2, InputIt2 last2); - -template -bool equal(InputIt1 first1, InputIt1 last1, - InputIt2 first2, InputIt2 last2, BinaryPred p) { - // Need a definition to suppress undefined_internal_type when invoked with lambda - return true; -} - -template -void iota(ForwardIt first, ForwardIt last, T value); - -} // namespace std +#include "fake_std.h" void Positives() { std::vector I, J; @@ -179,15 +74,15 @@ void Reverse(){ std::vector I, J; std::find(I.rbegin(), I.rend(), 0); // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use a ranges version of this algorithm - // CHECK-FIXES: std::ranges::find(std::views::reverse(I), 0); + // CHECK-FIXES: std::ranges::find(std::ranges::reverse_view(I), 0); std::equal(std::rbegin(I), std::rend(I), J.begin(), J.end()); // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use a ranges version of this algorithm - // CHECK-FIXES: std::ranges::equal(std::views::reverse(I), J); + // CHECK-FIXES: std::ranges::equal(std::ranges::reverse_view(I), J); std::equal(I.begin(), I.end(), std::crbegin(J), std::crend(J)); // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use a ranges version of this algorithm - // CHECK-FIXES: std::ranges::equal(I, std::views::reverse(J)); + // CHECK-FIXES: std::ranges::equal(I, std::ranges::reverse_view(J)); } void Negatives() {