1 //===----------------------------------------------------------------------===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 
9 // <functional>
10 
11 // class function<R(ArgTypes...)>
12 
13 // function& operator=(const function& f);
14 
15 // This test runs in C++03, but we have deprecated using std::function in C++03.
16 // ADDITIONAL_COMPILE_FLAGS: -D_LIBCPP_DISABLE_DEPRECATION_WARNINGS -D_LIBCPP_ENABLE_CXX03_FUNCTION
17 
18 #include <cassert>
19 #include <functional>
20 #include <utility>
21 
22 #include "test_macros.h"
23 #include "count_new.h"
24 
25 class A {
26   int data_[10];
27 
28 public:
29   static int count;
30 
31   A() {
32     ++count;
33     for (int i = 0; i < 10; ++i)
34       data_[i] = i;
35   }
36 
37   A(const A &) { ++count; }
38 
39   ~A() { --count; }
40 
41   int operator()(int i) const {
42     for (int j = 0; j < 10; ++j)
43       i += data_[j];
44     return i;
45   }
46 };
47 
48 int A::count = 0;
49 
50 int g0() { return 0; }
51 int g(int) { return 0; }
52 int g2(int, int) { return 2; }
53 int g3(int, int, int) { return 3; }
54 
55 int main(int, char**) {
56   globalMemCounter.reset();
57   assert(globalMemCounter.checkOutstandingNewEq(0));
58   {
59     std::function<int(int)> f = A();
60     assert(A::count == 1);
61     assert(globalMemCounter.checkOutstandingNewEq(1));
62     RTTI_ASSERT(f.target<A>());
63     RTTI_ASSERT(f.target<int (*)(int)>() == 0);
64     std::function<int(int)> f2;
65     f2 = f;
66     assert(A::count == 2);
67     assert(globalMemCounter.checkOutstandingNewEq(2));
68     RTTI_ASSERT(f2.target<A>());
69     RTTI_ASSERT(f2.target<int (*)(int)>() == 0);
70   }
71   assert(A::count == 0);
72   assert(globalMemCounter.checkOutstandingNewEq(0));
73   {
74     std::function<int(int)> f = g;
75     assert(globalMemCounter.checkOutstandingNewEq(0));
76     RTTI_ASSERT(f.target<int (*)(int)>());
77     RTTI_ASSERT(f.target<A>() == 0);
78     std::function<int(int)> f2;
79     f2 = f;
80     assert(globalMemCounter.checkOutstandingNewEq(0));
81     RTTI_ASSERT(f2.target<int (*)(int)>());
82     RTTI_ASSERT(f2.target<A>() == 0);
83   }
84   assert(globalMemCounter.checkOutstandingNewEq(0));
85   {
86     std::function<int(int)> f;
87     assert(globalMemCounter.checkOutstandingNewEq(0));
88     RTTI_ASSERT(f.target<int (*)(int)>() == 0);
89     RTTI_ASSERT(f.target<A>() == 0);
90     std::function<int(int)> f2;
91     f2 = f;
92     assert(globalMemCounter.checkOutstandingNewEq(0));
93     RTTI_ASSERT(f2.target<int (*)(int)>() == 0);
94     RTTI_ASSERT(f2.target<A>() == 0);
95   }
96   {
97     typedef std::function<int()> Func;
98     Func f = g0;
99     Func& fr = (f = (Func &)f);
100     assert(&fr == &f);
101     RTTI_ASSERT(*f.target<int(*)()>() == g0);
102   }
103   {
104     typedef std::function<int(int)> Func;
105     Func f = g;
106     Func& fr = (f = (Func &)f);
107     assert(&fr == &f);
108     RTTI_ASSERT(*f.target<int(*)(int)>() == g);
109   }
110   {
111     typedef std::function<int(int, int)> Func;
112     Func f = g2;
113     Func& fr = (f = (Func &)f);
114     assert(&fr == &f);
115     RTTI_ASSERT(*f.target<int(*)(int, int)>() == g2);
116   }
117   {
118     typedef std::function<int(int, int, int)> Func;
119     Func f = g3;
120     Func& fr = (f = (Func &)f);
121     assert(&fr == &f);
122     RTTI_ASSERT(*f.target<int(*)(int, int, int)>() == g3);
123   }
124 #if TEST_STD_VER >= 11
125   assert(globalMemCounter.checkOutstandingNewEq(0));
126   {
127     std::function<int(int)> f = A();
128     assert(A::count == 1);
129     assert(globalMemCounter.checkOutstandingNewEq(1));
130     RTTI_ASSERT(f.target<A>());
131     RTTI_ASSERT(f.target<int (*)(int)>() == 0);
132     std::function<int(int)> f2;
133     f2 = std::move(f);
134     assert(A::count == 1);
135     assert(globalMemCounter.checkOutstandingNewEq(1));
136     RTTI_ASSERT(f2.target<A>());
137     RTTI_ASSERT(f2.target<int (*)(int)>() == 0);
138     RTTI_ASSERT(f.target<A>() == 0);
139     RTTI_ASSERT(f.target<int (*)(int)>() == 0);
140   }
141 #endif
142 
143   return 0;
144 }
145