// RUN: %check_clang_tidy %s performance-inefficient-algorithm %t namespace std { template struct less { bool operator()(const T &lhs, const T &rhs) { return lhs < rhs; } }; template struct greater { bool operator()(const T &lhs, const T &rhs) { return lhs > rhs; } }; struct iterator_type {}; template > struct set { typedef iterator_type iterator; iterator find(const K &k); unsigned count(const K &k); iterator begin(); iterator end(); iterator begin() const; iterator end() const; }; struct other_iterator_type {}; template > struct map { typedef other_iterator_type iterator; iterator find(const K &k); unsigned count(const K &k); iterator begin(); iterator end(); iterator begin() const; iterator end() const; }; template struct multimap : map {}; template struct unordered_set : set {}; template struct unordered_map : map {}; template struct unordered_multiset : set {}; template struct unordered_multimap : map {}; template > struct multiset : set {}; template FwIt find(FwIt, FwIt end, const K &) { return end; } template FwIt find(FwIt, FwIt end, const K &, Cmp) { return end; } template FwIt find_if(FwIt, FwIt end, Pred) { return end; } template unsigned count(FwIt, FwIt, const K &) { return 0; } template FwIt lower_bound(FwIt, FwIt end, const K &) { return end; } template FwIt lower_bound(FwIt, FwIt end, const K &, Ord) { return end; } } #define FIND_IN_SET(x) find(x.begin(), x.end(), 10) // CHECK-FIXES: #define FIND_IN_SET(x) find(x.begin(), x.end(), 10) template void f(const T &t) { std::set s; find(s.begin(), s.end(), 46); // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: this STL algorithm call should be // CHECK-FIXES: {{^ }}s.find(46);{{$}} find(t.begin(), t.end(), 46); // CHECK-FIXES: {{^ }}find(t.begin(), t.end(), 46);{{$}} } int main() { std::set s; auto it = std::find(s.begin(), s.end(), 43); // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: this STL algorithm call should be replaced with a container method [performance-inefficient-algorithm] // CHECK-FIXES: {{^ }}auto it = s.find(43);{{$}} auto c = count(s.begin(), s.end(), 43); // CHECK-MESSAGES: :[[@LINE-1]]:12: warning: this STL algorithm call should be // CHECK-FIXES: {{^ }}auto c = s.count(43);{{$}} #define SECOND(x, y, z) y SECOND(q,std::count(s.begin(), s.end(), 22),w); // CHECK-MESSAGES: :[[@LINE-1]]:12: warning: this STL algorithm call should be // CHECK-FIXES: {{^ }}SECOND(q,s.count(22),w);{{$}} it = find_if(s.begin(), s.end(), [](int) { return false; }); std::multiset ms; find(ms.begin(), ms.end(), 46); // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: this STL algorithm call should be // CHECK-FIXES: {{^ }}ms.find(46);{{$}} const std::multiset &msref = ms; find(msref.begin(), msref.end(), 46); // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: this STL algorithm call should be // CHECK-FIXES: {{^ }}msref.find(46);{{$}} std::multiset *msptr = &ms; find(msptr->begin(), msptr->end(), 46); // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: this STL algorithm call should be // CHECK-FIXES: {{^ }}msptr->find(46);{{$}} it = std::find(s.begin(), s.end(), 43, std::greater()); // CHECK-MESSAGES: :[[@LINE-1]]:42: warning: different comparers used in the algorithm and the container [performance-inefficient-algorithm] FIND_IN_SET(s); // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: this STL algorithm call should be // CHECK-FIXES: {{^ }}FIND_IN_SET(s);{{$}} f(s); std::unordered_set us; lower_bound(us.begin(), us.end(), 10); // CHECK-FIXES: {{^ }}lower_bound(us.begin(), us.end(), 10);{{$}} find(us.begin(), us.end(), 10); // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: this STL algorithm call should be // CHECK-FIXES: {{^ }}us.find(10);{{$}} std::unordered_multiset ums; find(ums.begin(), ums.end(), 10); // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: this STL algorithm call should be // CHECK-FIXES: {{^ }}ums.find(10);{{$}} std::map intmap; find(intmap.begin(), intmap.end(), 46); // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: this STL algorithm call should be // CHECK-FIXES: {{^ }}find(intmap.begin(), intmap.end(), 46);{{$}} std::multimap intmmap; find(intmmap.begin(), intmmap.end(), 46); // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: this STL algorithm call should be // CHECK-FIXES: {{^ }}find(intmmap.begin(), intmmap.end(), 46);{{$}} std::unordered_map umap; find(umap.begin(), umap.end(), 46); // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: this STL algorithm call should be // CHECK-FIXES: {{^ }}find(umap.begin(), umap.end(), 46);{{$}} std::unordered_multimap ummap; find(ummap.begin(), ummap.end(), 46); // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: this STL algorithm call should be // CHECK-FIXES: {{^ }}find(ummap.begin(), ummap.end(), 46);{{$}} } struct Value { int value; }; struct Ordering { bool operator()(const Value &lhs, const Value &rhs) const { return lhs.value < rhs.value; } bool operator()(int lhs, const Value &rhs) const { return lhs < rhs.value; } }; void g(std::set container, int value) { lower_bound(container.begin(), container.end(), value, Ordering()); // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: this STL algorithm call should be // CHECK-FIXES: {{^ }}lower_bound(container.begin(), container.end(), value, Ordering());{{$}} }