189a1d03eSRichard // RUN: %check_clang_tidy -std=c++14-or-later %s modernize-avoid-bind %t
289a1d03eSRichard
389a1d03eSRichard namespace std {
489a1d03eSRichard inline namespace impl {
589a1d03eSRichard template <class Fp, class... Arguments>
689a1d03eSRichard class bind_rt {};
789a1d03eSRichard
889a1d03eSRichard template <class Fp, class... Arguments>
989a1d03eSRichard bind_rt<Fp, Arguments...> bind(Fp &&, Arguments &&...);
1089a1d03eSRichard } // namespace impl
1189a1d03eSRichard
1289a1d03eSRichard template <typename T>
1389a1d03eSRichard T ref(T &t);
1489a1d03eSRichard } // namespace std
1589a1d03eSRichard
1689a1d03eSRichard namespace boost {
1789a1d03eSRichard template <class Fp, class... Arguments>
1889a1d03eSRichard class bind_rt {};
1989a1d03eSRichard
2089a1d03eSRichard template <class Fp, class... Arguments>
2189a1d03eSRichard bind_rt<Fp, Arguments...> bind(const Fp &, Arguments...);
2289a1d03eSRichard
2389a1d03eSRichard template <class T>
2489a1d03eSRichard struct reference_wrapper {
reference_wrapperboost::reference_wrapper2589a1d03eSRichard explicit reference_wrapper(T &t) {}
2689a1d03eSRichard };
2789a1d03eSRichard
2889a1d03eSRichard template <class T>
ref(T & t)2989a1d03eSRichard reference_wrapper<T> const ref(T &t) {
3089a1d03eSRichard return reference_wrapper<T>(t);
3189a1d03eSRichard }
3289a1d03eSRichard
3389a1d03eSRichard } // namespace boost
3489a1d03eSRichard
3589a1d03eSRichard namespace C {
add(int x,int y)3689a1d03eSRichard int add(int x, int y) { return x + y; }
3789a1d03eSRichard } // namespace C
3889a1d03eSRichard
3989a1d03eSRichard struct Foo {
addFoo4089a1d03eSRichard static int add(int x, int y) { return x + y; }
4189a1d03eSRichard };
4289a1d03eSRichard
4389a1d03eSRichard struct D {
4489a1d03eSRichard D() = default;
operator ()D4589a1d03eSRichard void operator()(int x, int y) const {}
operator boolD46*d867f668SJoachim Priesner operator bool() const { return true; }
4789a1d03eSRichard
MemberFunctionD4889a1d03eSRichard void MemberFunction(int x) {}
MemberFunctionWithReturnD4993990945S5chmidti int MemberFunctionWithReturn(int x) {}
5089a1d03eSRichard
5189a1d03eSRichard static D *create();
5289a1d03eSRichard };
5389a1d03eSRichard
5489a1d03eSRichard struct F {
FF5589a1d03eSRichard F(int x) {}
~FF5689a1d03eSRichard ~F() {}
5789a1d03eSRichard
getF5889a1d03eSRichard int get() { return 42; }
5989a1d03eSRichard };
6089a1d03eSRichard
6189a1d03eSRichard void UseF(F);
6289a1d03eSRichard
6389a1d03eSRichard struct G {
GG6489a1d03eSRichard G() : _member(0) {}
GG6589a1d03eSRichard G(int m) : _member(m) {}
6689a1d03eSRichard
6789a1d03eSRichard template <typename T>
operator ()G6889a1d03eSRichard void operator()(T) const {}
6989a1d03eSRichard
7089a1d03eSRichard int _member;
7189a1d03eSRichard };
7289a1d03eSRichard
7389a1d03eSRichard template <typename T>
7489a1d03eSRichard struct H {
operator ()H7589a1d03eSRichard void operator()(T) const {};
7689a1d03eSRichard };
7789a1d03eSRichard
7889a1d03eSRichard struct placeholder {};
7989a1d03eSRichard placeholder _1;
8089a1d03eSRichard placeholder _2;
8189a1d03eSRichard
8289a1d03eSRichard namespace placeholders {
8389a1d03eSRichard using ::_1;
8489a1d03eSRichard using ::_2;
8589a1d03eSRichard } // namespace placeholders
8689a1d03eSRichard
add(int x,int y)8789a1d03eSRichard int add(int x, int y) { return x + y; }
addThree(int x,int y,int z)8889a1d03eSRichard int addThree(int x, int y, int z) { return x + y + z; }
sub(int & x,int y)8989a1d03eSRichard void sub(int &x, int y) { x += y; }
9089a1d03eSRichard
9189a1d03eSRichard // Let's fake a minimal std::function-like facility.
9289a1d03eSRichard namespace std {
9389a1d03eSRichard template <typename _Tp>
9489a1d03eSRichard _Tp declval();
9589a1d03eSRichard
9689a1d03eSRichard template <typename _Functor, typename... _ArgTypes>
9789a1d03eSRichard struct __res {
9889a1d03eSRichard template <typename... _Args>
9989a1d03eSRichard static decltype(declval<_Functor>()(_Args()...)) _S_test(int);
10089a1d03eSRichard
10189a1d03eSRichard template <typename...>
10289a1d03eSRichard static void _S_test(...);
10389a1d03eSRichard
10489a1d03eSRichard using type = decltype(_S_test<_ArgTypes...>(0));
10589a1d03eSRichard };
10689a1d03eSRichard
10789a1d03eSRichard template <typename>
10889a1d03eSRichard struct function;
10989a1d03eSRichard
11089a1d03eSRichard template <typename... _ArgTypes>
11189a1d03eSRichard struct function<void(_ArgTypes...)> {
11289a1d03eSRichard template <typename _Functor,
11389a1d03eSRichard typename = typename __res<_Functor, _ArgTypes...>::type>
functionstd::function11489a1d03eSRichard function(_Functor) {}
11589a1d03eSRichard };
11689a1d03eSRichard } // namespace std
11789a1d03eSRichard
11889a1d03eSRichard struct Thing {};
11989a1d03eSRichard void UseThing(Thing *);
12089a1d03eSRichard
12189a1d03eSRichard struct Callback {
12289a1d03eSRichard Callback();
12389a1d03eSRichard Callback(std::function<void()>);
12489a1d03eSRichard void Reset(std::function<void()>);
12589a1d03eSRichard };
12689a1d03eSRichard
12789a1d03eSRichard int GlobalVariable = 42;
12889a1d03eSRichard
12989a1d03eSRichard struct TestCaptureByValueStruct {
13089a1d03eSRichard int MemberVariable;
13189a1d03eSRichard static int StaticMemberVariable;
13289a1d03eSRichard F MemberStruct;
13389a1d03eSRichard G MemberStructWithData;
13489a1d03eSRichard
testCaptureByValueTestCaptureByValueStruct13589a1d03eSRichard void testCaptureByValue(int Param, F f) {
13689a1d03eSRichard int x = 3;
13789a1d03eSRichard int y = 4;
13889a1d03eSRichard auto AAA = std::bind(add, x, y);
13989a1d03eSRichard // CHECK-MESSAGES: :[[@LINE-1]]:16: warning: prefer a lambda to std::bind [modernize-avoid-bind]
14089a1d03eSRichard // CHECK-FIXES: auto AAA = [x, y] { return add(x, y); };
14189a1d03eSRichard
14289a1d03eSRichard // When the captured variable is repeated, it should only appear in the capture list once.
14389a1d03eSRichard auto BBB = std::bind(add, x, x);
14489a1d03eSRichard // CHECK-MESSAGES: :[[@LINE-1]]:16: warning: prefer a lambda to std::bind [modernize-avoid-bind]
14589a1d03eSRichard // CHECK-FIXES: auto BBB = [x] { return add(x, x); };
14689a1d03eSRichard
14789a1d03eSRichard int LocalVariable;
14889a1d03eSRichard // Global variables shouldn't be captured at all, and members should be captured through this.
14989a1d03eSRichard auto CCC = std::bind(add, MemberVariable, GlobalVariable);
15089a1d03eSRichard // CHECK-MESSAGES: :[[@LINE-1]]:16: warning: prefer a lambda to std::bind [modernize-avoid-bind]
15189a1d03eSRichard // CHECK-FIXES: auto CCC = [this] { return add(MemberVariable, GlobalVariable); };
15289a1d03eSRichard
15389a1d03eSRichard // Static member variables shouldn't be captured, but locals should
15489a1d03eSRichard auto DDD = std::bind(add, TestCaptureByValueStruct::StaticMemberVariable, LocalVariable);
15589a1d03eSRichard // CHECK-MESSAGES: :[[@LINE-1]]:16: warning: prefer a lambda to std::bind [modernize-avoid-bind]
15689a1d03eSRichard // CHECK-FIXES: auto DDD = [LocalVariable] { return add(TestCaptureByValueStruct::StaticMemberVariable, LocalVariable); };
15789a1d03eSRichard
15889a1d03eSRichard auto EEE = std::bind(add, Param, Param);
15989a1d03eSRichard // CHECK-MESSAGES: :[[@LINE-1]]:16: warning: prefer a lambda to std::bind [modernize-avoid-bind]
16089a1d03eSRichard // CHECK-FIXES: auto EEE = [Param] { return add(Param, Param); };
16189a1d03eSRichard
16289a1d03eSRichard // The signature of boost::bind() is different, and causes
16389a1d03eSRichard // CXXBindTemporaryExprs to be created in certain cases. So let's test
16489a1d03eSRichard // those here.
16589a1d03eSRichard auto FFF = boost::bind(UseF, f);
16689a1d03eSRichard // CHECK-MESSAGES: :[[@LINE-1]]:16: warning: prefer a lambda to boost::bind [modernize-avoid-bind]
16793990945S5chmidti // CHECK-FIXES: auto FFF = [f] { UseF(f); };
16889a1d03eSRichard
16989a1d03eSRichard auto GGG = boost::bind(UseF, MemberStruct);
17089a1d03eSRichard // CHECK-MESSAGES: :[[@LINE-1]]:16: warning: prefer a lambda to boost::bind [modernize-avoid-bind]
17193990945S5chmidti // CHECK-FIXES: auto GGG = [this] { UseF(MemberStruct); };
17289a1d03eSRichard
17389a1d03eSRichard auto HHH = std::bind(add, MemberStructWithData._member, 1);
17489a1d03eSRichard // CHECK-MESSAGES: :[[@LINE-1]]:16: warning: prefer a lambda to std::bind
17589a1d03eSRichard // Correctly distinguish data members of other classes
17689a1d03eSRichard // CHECK-FIXES: auto HHH = [capture0 = MemberStructWithData._member] { return add(capture0, 1); };
17789a1d03eSRichard }
17889a1d03eSRichard };
17989a1d03eSRichard
testLiteralParameters()18089a1d03eSRichard void testLiteralParameters() {
18189a1d03eSRichard auto AAA = std::bind(add, 2, 2);
18289a1d03eSRichard // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: prefer a lambda to std::bind [modernize-avoid-bind]
18389a1d03eSRichard // CHECK-FIXES: auto AAA = [] { return add(2, 2); };
18489a1d03eSRichard
18589a1d03eSRichard auto BBB = std::bind(addThree, 2, 3, 4);
18689a1d03eSRichard // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: prefer a lambda to std::bind [modernize-avoid-bind]
18789a1d03eSRichard // CHECK-FIXES: auto BBB = [] { return addThree(2, 3, 4); };
18889a1d03eSRichard }
18989a1d03eSRichard
testCaptureByReference()19089a1d03eSRichard void testCaptureByReference() {
19189a1d03eSRichard int x = 2;
19289a1d03eSRichard int y = 2;
19389a1d03eSRichard auto AAA = std::bind(add, std::ref(x), std::ref(y));
19489a1d03eSRichard // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: prefer a lambda to std::bind
19589a1d03eSRichard // CHECK-FIXES: auto AAA = [&x, &y] { return add(x, y); };
19689a1d03eSRichard
19789a1d03eSRichard auto BBB = std::bind(add, std::ref(x), y);
19889a1d03eSRichard // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: prefer a lambda to std::bind
19989a1d03eSRichard // CHECK-FIXES: auto BBB = [&x, y] { return add(x, y); };
20089a1d03eSRichard
20189a1d03eSRichard auto CCC = std::bind(add, y, std::ref(x));
20289a1d03eSRichard // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: prefer a lambda to std::bind
20389a1d03eSRichard // CHECK-FIXES: auto CCC = [y, &x] { return add(y, x); };
20489a1d03eSRichard
20589a1d03eSRichard // Make sure it works with boost::ref() too which has slightly different
20689a1d03eSRichard // semantics.
20789a1d03eSRichard auto DDD = boost::bind(add, boost::ref(x), boost::ref(y));
20889a1d03eSRichard // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: prefer a lambda to boost::bind
20989a1d03eSRichard // CHECK-FIXES: auto DDD = [&x, &y] { return add(x, y); };
21089a1d03eSRichard
21189a1d03eSRichard auto EEE = boost::bind(add, boost::ref(x), y);
21289a1d03eSRichard // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: prefer a lambda to boost::bind
21389a1d03eSRichard // CHECK-FIXES: auto EEE = [&x, y] { return add(x, y); };
21489a1d03eSRichard
21589a1d03eSRichard auto FFF = boost::bind(add, y, boost::ref(x));
21689a1d03eSRichard // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: prefer a lambda to boost::bind
21789a1d03eSRichard // CHECK-FIXES: auto FFF = [y, &x] { return add(y, x); };
21889a1d03eSRichard }
21989a1d03eSRichard
testCaptureByInitExpression()22089a1d03eSRichard void testCaptureByInitExpression() {
22189a1d03eSRichard int x = 42;
22289a1d03eSRichard auto AAA = std::bind(add, x, F(x).get());
22389a1d03eSRichard // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: prefer a lambda to std::bind
22489a1d03eSRichard // CHECK-FIXES: auto AAA = [x, capture0 = F(x).get()] { return add(x, capture0); };
22589a1d03eSRichard }
22689a1d03eSRichard
testFunctionObjects()22789a1d03eSRichard void testFunctionObjects() {
22889a1d03eSRichard D d;
22989a1d03eSRichard D *e = nullptr;
23089a1d03eSRichard auto AAA = std::bind(d, 1, 2);
23189a1d03eSRichard // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: prefer a lambda to std::bind
23293990945S5chmidti // CHECK-FIXES: auto AAA = [d] { d(1, 2); }
23389a1d03eSRichard
23489a1d03eSRichard auto BBB = std::bind(*e, 1, 2);
23589a1d03eSRichard // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: prefer a lambda to std::bind
23693990945S5chmidti // CHECK-FIXES: auto BBB = [e] { (*e)(1, 2); }
23789a1d03eSRichard
23889a1d03eSRichard auto CCC = std::bind(D{}, 1, 2);
23989a1d03eSRichard // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: prefer a lambda to std::bind
24093990945S5chmidti // CHECK-FIXES: auto CCC = [] { D{}(1, 2); }
24189a1d03eSRichard
24289a1d03eSRichard auto DDD = std::bind(D(), 1, 2);
24389a1d03eSRichard // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: prefer a lambda to std::bind
24493990945S5chmidti // CHECK-FIXES: auto DDD = [] { D()(1, 2); }
24589a1d03eSRichard
24689a1d03eSRichard auto EEE = std::bind(*D::create(), 1, 2);
24789a1d03eSRichard // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: prefer a lambda to std::bind
24893990945S5chmidti // CHECK-FIXES: auto EEE = [Func = *D::create()] { Func(1, 2); };
24989a1d03eSRichard
25089a1d03eSRichard auto FFF = std::bind(G(), 1);
25189a1d03eSRichard // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: prefer a lambda to std::bind
25289a1d03eSRichard // Templated function call operators may be used
25393990945S5chmidti // CHECK-FIXES: auto FFF = [] { G()(1); };
25489a1d03eSRichard
25589a1d03eSRichard int CTorArg = 42;
25689a1d03eSRichard auto GGG = std::bind(G(CTorArg), 1);
25789a1d03eSRichard // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: prefer a lambda to std::bind
25889a1d03eSRichard // Function objects with constructor arguments should be captured
25993990945S5chmidti // CHECK-FIXES: auto GGG = [Func = G(CTorArg)] { Func(1); };
26089a1d03eSRichard }
26189a1d03eSRichard
26289a1d03eSRichard template <typename T>
testMemberFnOfClassTemplate(T)26389a1d03eSRichard void testMemberFnOfClassTemplate(T) {
26489a1d03eSRichard auto HHH = std::bind(H<T>(), 42);
26589a1d03eSRichard // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: prefer a lambda to std::bind
26689a1d03eSRichard // Ensure function class template arguments are preserved
26793990945S5chmidti // CHECK-FIXES: auto HHH = [] { H<T>()(42); };
26889a1d03eSRichard }
26989a1d03eSRichard
27089a1d03eSRichard template void testMemberFnOfClassTemplate(int);
27189a1d03eSRichard
testPlaceholders()27289a1d03eSRichard void testPlaceholders() {
27389a1d03eSRichard int x = 2;
27489a1d03eSRichard auto AAA = std::bind(add, x, _1);
27589a1d03eSRichard // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: prefer a lambda to std::bind
27689a1d03eSRichard // CHECK-FIXES: auto AAA = [x](auto && PH1) { return add(x, std::forward<decltype(PH1)>(PH1)); };
27789a1d03eSRichard
27889a1d03eSRichard auto BBB = std::bind(add, _2, _1);
27989a1d03eSRichard // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: prefer a lambda to std::bind
28089a1d03eSRichard // CHECK-FIXES: auto BBB = [](auto && PH1, auto && PH2) { return add(std::forward<decltype(PH2)>(PH2), std::forward<decltype(PH1)>(PH1)); };
28189a1d03eSRichard
28289a1d03eSRichard // No fix is applied for reused placeholders.
28389a1d03eSRichard auto CCC = std::bind(add, _1, _1);
28489a1d03eSRichard // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: prefer a lambda to std::bind
28589a1d03eSRichard // CHECK-FIXES: auto CCC = std::bind(add, _1, _1);
28689a1d03eSRichard
28789a1d03eSRichard // When a placeholder is skipped, we always add skipped ones to the lambda as
28889a1d03eSRichard // unnamed parameters.
28989a1d03eSRichard auto DDD = std::bind(add, _2, 1);
29089a1d03eSRichard // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: prefer a lambda to std::bind
29189a1d03eSRichard // CHECK-FIXES: auto DDD = [](auto &&, auto && PH2) { return add(std::forward<decltype(PH2)>(PH2), 1); };
29289a1d03eSRichard
29389a1d03eSRichard // Namespace-qualified placeholders are valid too
29489a1d03eSRichard auto EEE = std::bind(add, placeholders::_2, 1);
29589a1d03eSRichard // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: prefer a lambda to std::bind
29689a1d03eSRichard // CHECK-FIXES: auto EEE = [](auto &&, auto && PH2) { return add(std::forward<decltype(PH2)>(PH2), 1); };
29789a1d03eSRichard }
29889a1d03eSRichard
testGlobalFunctions()29989a1d03eSRichard void testGlobalFunctions() {
30089a1d03eSRichard auto AAA = std::bind(C::add, 1, 1);
30189a1d03eSRichard // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: prefer a lambda to std::bind
30289a1d03eSRichard // CHECK-FIXES: auto AAA = [] { return C::add(1, 1); };
30389a1d03eSRichard
30489a1d03eSRichard auto BBB = std::bind(Foo::add, 1, 1);
30589a1d03eSRichard // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: prefer a lambda to std::bind
30689a1d03eSRichard // CHECK-FIXES: auto BBB = [] { return Foo::add(1, 1); };
30789a1d03eSRichard
30889a1d03eSRichard // The & should get removed inside of the lambda body.
30989a1d03eSRichard auto CCC = std::bind(&C::add, 1, 1);
31089a1d03eSRichard // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: prefer a lambda to std::bind
31189a1d03eSRichard // CHECK-FIXES: auto CCC = [] { return C::add(1, 1); };
31289a1d03eSRichard
31389a1d03eSRichard auto DDD = std::bind(&Foo::add, 1, 1);
31489a1d03eSRichard // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: prefer a lambda to std::bind
31589a1d03eSRichard // CHECK-FIXES: auto DDD = [] { return Foo::add(1, 1); };
31689a1d03eSRichard
31789a1d03eSRichard auto EEE = std::bind(&add, 1, 1);
31889a1d03eSRichard // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: prefer a lambda to std::bind
31989a1d03eSRichard // CHECK-FIXES: auto EEE = [] { return add(1, 1); };
32089a1d03eSRichard }
32189a1d03eSRichard
testCapturedSubexpressions()32289a1d03eSRichard void testCapturedSubexpressions() {
32389a1d03eSRichard int x = 3;
32489a1d03eSRichard int y = 3;
32589a1d03eSRichard int *p = &x;
32689a1d03eSRichard
32789a1d03eSRichard auto AAA = std::bind(add, 1, add(2, 5));
32889a1d03eSRichard // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: prefer a lambda to std::bind
32989a1d03eSRichard // Results of nested calls are captured by value.
33089a1d03eSRichard // CHECK-FIXES: auto AAA = [capture0 = add(2, 5)] { return add(1, capture0); };
33189a1d03eSRichard
33289a1d03eSRichard auto BBB = std::bind(add, x, add(y, 5));
33389a1d03eSRichard // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: prefer a lambda to std::bind
33489a1d03eSRichard // Results of nested calls are captured by value.
33589a1d03eSRichard // CHECK-FIXES: auto BBB = [x, capture0 = add(y, 5)] { return add(x, capture0); };
33689a1d03eSRichard
33789a1d03eSRichard auto CCC = std::bind(sub, std::ref(*p), _1);
33889a1d03eSRichard // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: prefer a lambda to std::bind
33989a1d03eSRichard // Expressions returning references are captured
34093990945S5chmidti // CHECK-FIXES: auto CCC = [&capture0 = *p](auto && PH1) { sub(capture0, std::forward<decltype(PH1)>(PH1)); };
34189a1d03eSRichard }
34289a1d03eSRichard
34389a1d03eSRichard struct E {
MemberFunctionE34489a1d03eSRichard void MemberFunction(int x) {}
MemberFunctionWithReturnE34593990945S5chmidti int MemberFunctionWithReturn(int x) {}
operator ()E346*d867f668SJoachim Priesner int operator()(int x, int y) const { return x + y; }
34789a1d03eSRichard
testMemberFunctionsE34889a1d03eSRichard void testMemberFunctions() {
34989a1d03eSRichard D *d;
35089a1d03eSRichard D dd;
35189a1d03eSRichard auto AAA = std::bind(&D::MemberFunction, d, 1);
35289a1d03eSRichard // CHECK-MESSAGES: :[[@LINE-1]]:16: warning: prefer a lambda to std::bind
35389a1d03eSRichard // CHECK-FIXES: auto AAA = [d] { d->MemberFunction(1); };
35489a1d03eSRichard
35589a1d03eSRichard auto BBB = std::bind(&D::MemberFunction, &dd, 1);
35689a1d03eSRichard // CHECK-MESSAGES: :[[@LINE-1]]:16: warning: prefer a lambda to std::bind
35789a1d03eSRichard // CHECK-FIXES: auto BBB = [ObjectPtr = &dd] { ObjectPtr->MemberFunction(1); };
35889a1d03eSRichard
35989a1d03eSRichard auto CCC = std::bind(&E::MemberFunction, this, 1);
36089a1d03eSRichard // CHECK-MESSAGES: :[[@LINE-1]]:16: warning: prefer a lambda to std::bind
36189a1d03eSRichard // CHECK-FIXES: auto CCC = [this] { MemberFunction(1); };
36289a1d03eSRichard
36389a1d03eSRichard // Test what happens when the object pointer is itself a placeholder.
36489a1d03eSRichard auto DDD = std::bind(&D::MemberFunction, _1, 1);
36589a1d03eSRichard // CHECK-MESSAGES: :[[@LINE-1]]:16: warning: prefer a lambda to std::bind
36689a1d03eSRichard // CHECK-FIXES: auto DDD = [](auto && PH1) { PH1->MemberFunction(1); };
36793990945S5chmidti
36893990945S5chmidti auto EEE = std::bind(&D::MemberFunctionWithReturn, d, 1);
36993990945S5chmidti // CHECK-MESSAGES: :[[@LINE-1]]:16: warning: prefer a lambda to std::bind
37093990945S5chmidti // CHECK-FIXES: auto EEE = [d] { return d->MemberFunctionWithReturn(1); };
37193990945S5chmidti
37293990945S5chmidti auto FFF = std::bind(&D::MemberFunctionWithReturn, &dd, 1);
37393990945S5chmidti // CHECK-MESSAGES: :[[@LINE-1]]:16: warning: prefer a lambda to std::bind
37493990945S5chmidti // CHECK-FIXES: auto FFF = [ObjectPtr = &dd] { return ObjectPtr->MemberFunctionWithReturn(1); };
37593990945S5chmidti
37693990945S5chmidti auto GGG = std::bind(&E::MemberFunctionWithReturn, this, 1);
37793990945S5chmidti // CHECK-MESSAGES: :[[@LINE-1]]:16: warning: prefer a lambda to std::bind
37893990945S5chmidti // CHECK-FIXES: auto GGG = [this] { return MemberFunctionWithReturn(1); };
37993990945S5chmidti
38093990945S5chmidti // Test what happens when the object pointer is itself a placeholder.
38193990945S5chmidti auto HHH = std::bind(&D::MemberFunctionWithReturn, _1, 1);
38293990945S5chmidti // CHECK-MESSAGES: :[[@LINE-1]]:16: warning: prefer a lambda to std::bind
38393990945S5chmidti // CHECK-FIXES: auto HHH = [](auto && PH1) { return PH1->MemberFunctionWithReturn(1); };
384*d867f668SJoachim Priesner
385*d867f668SJoachim Priesner auto III = std::bind(&D::operator(), d, 1, 2);
386*d867f668SJoachim Priesner // CHECK-MESSAGES: :[[@LINE-1]]:16: warning: prefer a lambda to std::bind
387*d867f668SJoachim Priesner // CHECK-FIXES: auto III = [d] { (*d)(1, 2); }
388*d867f668SJoachim Priesner
389*d867f668SJoachim Priesner auto JJJ = std::bind(&D::operator(), &dd, 1, 2);
390*d867f668SJoachim Priesner // CHECK-MESSAGES: :[[@LINE-1]]:16: warning: prefer a lambda to std::bind
391*d867f668SJoachim Priesner // CHECK-FIXES: auto JJJ = [ObjectPtr = &dd] { (*ObjectPtr)(1, 2); }
392*d867f668SJoachim Priesner
393*d867f668SJoachim Priesner auto KKK = std::bind(&D::operator(), _1, 1, 2);
394*d867f668SJoachim Priesner // CHECK-MESSAGES: :[[@LINE-1]]:16: warning: prefer a lambda to std::bind
395*d867f668SJoachim Priesner // CHECK-FIXES: auto KKK = [](auto && PH1) { (*PH1)(1, 2); };
396*d867f668SJoachim Priesner
397*d867f668SJoachim Priesner auto LLL = std::bind(&D::operator bool, d);
398*d867f668SJoachim Priesner // CHECK-MESSAGES: :[[@LINE-1]]:16: warning: prefer a lambda to std::bind
399*d867f668SJoachim Priesner // CHECK-FIXES: auto LLL = [d] { return d->operator bool(); }
400*d867f668SJoachim Priesner
401*d867f668SJoachim Priesner auto MMM = std::bind(&E::operator(), this, 1, 2);
402*d867f668SJoachim Priesner // CHECK-MESSAGES: :[[@LINE-1]]:16: warning: prefer a lambda to std::bind
403*d867f668SJoachim Priesner // CHECK-FIXES: auto MMM = [this] { return (*this)(1, 2); }
40489a1d03eSRichard }
40589a1d03eSRichard };
40689a1d03eSRichard
testStdFunction(Thing * t)40789a1d03eSRichard void testStdFunction(Thing *t) {
40889a1d03eSRichard Callback cb;
40989a1d03eSRichard if (t)
41089a1d03eSRichard cb.Reset(std::bind(UseThing, t));
41189a1d03eSRichard // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: prefer a lambda to std::bind
41293990945S5chmidti // CHECK-FIXES: cb.Reset([t] { UseThing(t); });
41389a1d03eSRichard }
414