15a83710eSEric Fiselier //===----------------------------------------------------------------------===//
25a83710eSEric Fiselier //
357b08b09SChandler Carruth // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
457b08b09SChandler Carruth // See https://llvm.org/LICENSE.txt for license information.
557b08b09SChandler Carruth // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
65a83710eSEric Fiselier //
75a83710eSEric Fiselier //===----------------------------------------------------------------------===//
85a83710eSEric Fiselier 
95a83710eSEric Fiselier // <functional>
105a83710eSEric Fiselier 
115a83710eSEric Fiselier // class function<R(ArgTypes...)>
125a83710eSEric Fiselier 
135a83710eSEric Fiselier // function& operator=(const function& f);
145a83710eSEric Fiselier 
15b4fb705eSLouis Dionne // This test runs in C++03, but we have deprecated using std::function in C++03.
16*c475e31aSNikolas Klauser // ADDITIONAL_COMPILE_FLAGS: -D_LIBCPP_DISABLE_DEPRECATION_WARNINGS -D_LIBCPP_ENABLE_CXX03_FUNCTION
17b4fb705eSLouis Dionne 
185a83710eSEric Fiselier #include <functional>
195a83710eSEric Fiselier #include <cassert>
205a83710eSEric Fiselier 
212c8c71f1SEric Fiselier #include "test_macros.h"
22cc89063bSNico Weber #include "count_new.h"
235a83710eSEric Fiselier 
24d566c345SEric Fiselier class A {
255a83710eSEric Fiselier   int data_[10];
26d566c345SEric Fiselier 
275a83710eSEric Fiselier public:
285a83710eSEric Fiselier   static int count;
295a83710eSEric Fiselier 
A()30d566c345SEric Fiselier   A() {
315a83710eSEric Fiselier     ++count;
325a83710eSEric Fiselier     for (int i = 0; i < 10; ++i)
335a83710eSEric Fiselier       data_[i] = i;
345a83710eSEric Fiselier   }
355a83710eSEric Fiselier 
A(const A &)365a83710eSEric Fiselier   A(const A &) { ++count; }
375a83710eSEric Fiselier 
~A()385a83710eSEric Fiselier   ~A() { --count; }
395a83710eSEric Fiselier 
operator ()(int i) const40d566c345SEric Fiselier   int operator()(int i) const {
415a83710eSEric Fiselier     for (int j = 0; j < 10; ++j)
425a83710eSEric Fiselier       i += data_[j];
435a83710eSEric Fiselier     return i;
445a83710eSEric Fiselier   }
455a83710eSEric Fiselier };
465a83710eSEric Fiselier 
475a83710eSEric Fiselier int A::count = 0;
485a83710eSEric Fiselier 
g0()49d566c345SEric Fiselier int g0() { return 0; }
g(int)505a83710eSEric Fiselier int g(int) { return 0; }
g2(int,int)51d566c345SEric Fiselier int g2(int, int) { return 2; }
g3(int,int,int)52d566c345SEric Fiselier int g3(int, int, int) { return 3; }
535a83710eSEric Fiselier 
main(int,char **)542df59c50SJF Bastien int main(int, char**) {
559c5d0ea6SDan Albert   globalMemCounter.reset();
562cbc654dSEric Fiselier   assert(globalMemCounter.checkOutstandingNewEq(0));
575a83710eSEric Fiselier   {
585a83710eSEric Fiselier     std::function<int(int)> f = A();
595a83710eSEric Fiselier     assert(A::count == 1);
602cbc654dSEric Fiselier     assert(globalMemCounter.checkOutstandingNewEq(1));
61bb09ef95SLouis Dionne     RTTI_ASSERT(f.target<A>());
62bb09ef95SLouis Dionne     RTTI_ASSERT(f.target<int (*)(int)>() == 0);
635a83710eSEric Fiselier     std::function<int(int)> f2;
645a83710eSEric Fiselier     f2 = f;
655a83710eSEric Fiselier     assert(A::count == 2);
662cbc654dSEric Fiselier     assert(globalMemCounter.checkOutstandingNewEq(2));
67bb09ef95SLouis Dionne     RTTI_ASSERT(f2.target<A>());
68bb09ef95SLouis Dionne     RTTI_ASSERT(f2.target<int (*)(int)>() == 0);
695a83710eSEric Fiselier   }
705a83710eSEric Fiselier   assert(A::count == 0);
712cbc654dSEric Fiselier   assert(globalMemCounter.checkOutstandingNewEq(0));
725a83710eSEric Fiselier   {
735a83710eSEric Fiselier     std::function<int(int)> f = g;
742cbc654dSEric Fiselier     assert(globalMemCounter.checkOutstandingNewEq(0));
75bb09ef95SLouis Dionne     RTTI_ASSERT(f.target<int (*)(int)>());
76bb09ef95SLouis Dionne     RTTI_ASSERT(f.target<A>() == 0);
775a83710eSEric Fiselier     std::function<int(int)> f2;
785a83710eSEric Fiselier     f2 = f;
792cbc654dSEric Fiselier     assert(globalMemCounter.checkOutstandingNewEq(0));
80bb09ef95SLouis Dionne     RTTI_ASSERT(f2.target<int (*)(int)>());
81bb09ef95SLouis Dionne     RTTI_ASSERT(f2.target<A>() == 0);
825a83710eSEric Fiselier   }
832cbc654dSEric Fiselier   assert(globalMemCounter.checkOutstandingNewEq(0));
845a83710eSEric Fiselier   {
855a83710eSEric Fiselier     std::function<int(int)> f;
862cbc654dSEric Fiselier     assert(globalMemCounter.checkOutstandingNewEq(0));
87bb09ef95SLouis Dionne     RTTI_ASSERT(f.target<int (*)(int)>() == 0);
88bb09ef95SLouis Dionne     RTTI_ASSERT(f.target<A>() == 0);
895a83710eSEric Fiselier     std::function<int(int)> f2;
905a83710eSEric Fiselier     f2 = f;
912cbc654dSEric Fiselier     assert(globalMemCounter.checkOutstandingNewEq(0));
92bb09ef95SLouis Dionne     RTTI_ASSERT(f2.target<int (*)(int)>() == 0);
93bb09ef95SLouis Dionne     RTTI_ASSERT(f2.target<A>() == 0);
945a83710eSEric Fiselier   }
95d566c345SEric Fiselier   {
96d566c345SEric Fiselier     typedef std::function<int()> Func;
97d566c345SEric Fiselier     Func f = g0;
986669e59fSRoman Lebedev     Func& fr = (f = (Func &)f);
99d566c345SEric Fiselier     assert(&fr == &f);
100bb09ef95SLouis Dionne     RTTI_ASSERT(*f.target<int(*)()>() == g0);
101d566c345SEric Fiselier   }
102d566c345SEric Fiselier   {
103d566c345SEric Fiselier     typedef std::function<int(int)> Func;
104d566c345SEric Fiselier     Func f = g;
1056669e59fSRoman Lebedev     Func& fr = (f = (Func &)f);
106d566c345SEric Fiselier     assert(&fr == &f);
107bb09ef95SLouis Dionne     RTTI_ASSERT(*f.target<int(*)(int)>() == g);
108d566c345SEric Fiselier   }
109d566c345SEric Fiselier   {
110d566c345SEric Fiselier     typedef std::function<int(int, int)> Func;
111d566c345SEric Fiselier     Func f = g2;
1126669e59fSRoman Lebedev     Func& fr = (f = (Func &)f);
113d566c345SEric Fiselier     assert(&fr == &f);
114bb09ef95SLouis Dionne     RTTI_ASSERT(*f.target<int(*)(int, int)>() == g2);
115d566c345SEric Fiselier   }
116d566c345SEric Fiselier   {
117d566c345SEric Fiselier     typedef std::function<int(int, int, int)> Func;
118d566c345SEric Fiselier     Func f = g3;
1196669e59fSRoman Lebedev     Func& fr = (f = (Func &)f);
120d566c345SEric Fiselier     assert(&fr == &f);
121bb09ef95SLouis Dionne     RTTI_ASSERT(*f.target<int(*)(int, int, int)>() == g3);
122d566c345SEric Fiselier   }
1232c8c71f1SEric Fiselier #if TEST_STD_VER >= 11
1242cbc654dSEric Fiselier   assert(globalMemCounter.checkOutstandingNewEq(0));
1255a83710eSEric Fiselier   {
1265a83710eSEric Fiselier     std::function<int(int)> f = A();
1275a83710eSEric Fiselier     assert(A::count == 1);
1282cbc654dSEric Fiselier     assert(globalMemCounter.checkOutstandingNewEq(1));
129bb09ef95SLouis Dionne     RTTI_ASSERT(f.target<A>());
130bb09ef95SLouis Dionne     RTTI_ASSERT(f.target<int (*)(int)>() == 0);
1315a83710eSEric Fiselier     std::function<int(int)> f2;
1325a83710eSEric Fiselier     f2 = std::move(f);
1335a83710eSEric Fiselier     assert(A::count == 1);
1342cbc654dSEric Fiselier     assert(globalMemCounter.checkOutstandingNewEq(1));
135bb09ef95SLouis Dionne     RTTI_ASSERT(f2.target<A>());
136bb09ef95SLouis Dionne     RTTI_ASSERT(f2.target<int (*)(int)>() == 0);
137bb09ef95SLouis Dionne     RTTI_ASSERT(f.target<A>() == 0);
138bb09ef95SLouis Dionne     RTTI_ASSERT(f.target<int (*)(int)>() == 0);
1395a83710eSEric Fiselier   }
1402c8c71f1SEric Fiselier #endif
1412df59c50SJF Bastien 
1422df59c50SJF Bastien   return 0;
1435a83710eSEric Fiselier }
144