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 // void swap(function& other);
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
17 
18 #include <functional>
19 #include <cassert>
20 
21 #include "count_new.h"
22 
23 #include "test_macros.h"
24 
25 class A {
26   int data_[10];
27 
28 public:
29   static int count;
30 
A(int j)31   explicit A(int j) {
32     ++count;
33     data_[0] = j;
34   }
35 
A(const A & a)36   A(const A &a) {
37     ++count;
38     for (int i = 0; i < 10; ++i)
39       data_[i] = a.data_[i];
40   }
41 
~A()42   ~A() { --count; }
43 
operator ()(int i) const44   int operator()(int i) const {
45     for (int j = 0; j < 10; ++j)
46       i += data_[j];
47     return i;
48   }
49 
operator ()() const50   int operator()() const { return -1; }
operator ()(int,int) const51   int operator()(int, int) const { return -2; }
operator ()(int,int,int) const52   int operator()(int, int, int) const { return -3; }
53 
id() const54   int id() const { return data_[0]; }
55 };
56 
57 int A::count = 0;
58 
g0()59 int g0() { return 0; }
g(int)60 int g(int) { return 0; }
h(int)61 int h(int) { return 1; }
g2(int,int)62 int g2(int, int) { return 2; }
g3(int,int,int)63 int g3(int, int, int) { return 3; }
64 
main(int,char **)65 int main(int, char**) {
66   globalMemCounter.reset();
67   assert(globalMemCounter.checkOutstandingNewEq(0));
68   {
69     std::function<int(int)> f1 = A(1);
70     std::function<int(int)> f2 = A(2);
71     assert(A::count == 2);
72     assert(globalMemCounter.checkOutstandingNewEq(2));
73     RTTI_ASSERT(f1.target<A>()->id() == 1);
74     RTTI_ASSERT(f2.target<A>()->id() == 2);
75     f1.swap(f2);
76     assert(A::count == 2);
77     assert(globalMemCounter.checkOutstandingNewEq(2));
78     RTTI_ASSERT(f1.target<A>()->id() == 2);
79     RTTI_ASSERT(f2.target<A>()->id() == 1);
80   }
81   assert(A::count == 0);
82   assert(globalMemCounter.checkOutstandingNewEq(0));
83   {
84     std::function<int(int)> f1 = A(1);
85     std::function<int(int)> f2 = g;
86     assert(A::count == 1);
87     assert(globalMemCounter.checkOutstandingNewEq(1));
88     RTTI_ASSERT(f1.target<A>()->id() == 1);
89     RTTI_ASSERT(*f2.target<int (*)(int)>() == g);
90     f1.swap(f2);
91     assert(A::count == 1);
92     assert(globalMemCounter.checkOutstandingNewEq(1));
93     RTTI_ASSERT(*f1.target<int (*)(int)>() == g);
94     RTTI_ASSERT(f2.target<A>()->id() == 1);
95   }
96   assert(A::count == 0);
97   assert(globalMemCounter.checkOutstandingNewEq(0));
98   {
99     std::function<int(int)> f1 = g;
100     std::function<int(int)> f2 = A(1);
101     assert(A::count == 1);
102     assert(globalMemCounter.checkOutstandingNewEq(1));
103     RTTI_ASSERT(*f1.target<int (*)(int)>() == g);
104     RTTI_ASSERT(f2.target<A>()->id() == 1);
105     f1.swap(f2);
106     assert(A::count == 1);
107     assert(globalMemCounter.checkOutstandingNewEq(1));
108     RTTI_ASSERT(f1.target<A>()->id() == 1);
109     RTTI_ASSERT(*f2.target<int (*)(int)>() == g);
110   }
111   assert(A::count == 0);
112   assert(globalMemCounter.checkOutstandingNewEq(0));
113   {
114     std::function<int(int)> f1 = g;
115     std::function<int(int)> f2 = h;
116     assert(A::count == 0);
117     assert(globalMemCounter.checkOutstandingNewEq(0));
118     RTTI_ASSERT(*f1.target<int (*)(int)>() == g);
119     RTTI_ASSERT(*f2.target<int (*)(int)>() == h);
120     f1.swap(f2);
121     assert(A::count == 0);
122     assert(globalMemCounter.checkOutstandingNewEq(0));
123     RTTI_ASSERT(*f1.target<int (*)(int)>() == h);
124     RTTI_ASSERT(*f2.target<int (*)(int)>() == g);
125   }
126   assert(A::count == 0);
127   assert(globalMemCounter.checkOutstandingNewEq(0));
128   {
129     std::function<int(int)> f1 = A(1);
130     assert(A::count == 1);
131     {
132       DisableAllocationGuard guard;
133       ((void)guard);
134       f1.swap(f1);
135     }
136     assert(A::count == 1);
137     RTTI_ASSERT(f1.target<A>()->id() == 1);
138   }
139   assert(A::count == 0);
140   assert(globalMemCounter.checkOutstandingNewEq(0));
141   {
142     std::function<int()> f1 = g0;
143     DisableAllocationGuard guard;
144     ((void)guard);
145     f1.swap(f1);
146     RTTI_ASSERT(*f1.target<int (*)()>() == g0);
147   }
148   assert(globalMemCounter.checkOutstandingNewEq(0));
149   {
150     std::function<int(int, int)> f1 = g2;
151     DisableAllocationGuard guard;
152     ((void)guard);
153     f1.swap(f1);
154     RTTI_ASSERT(*f1.target<int (*)(int, int)>() == g2);
155   }
156   assert(globalMemCounter.checkOutstandingNewEq(0));
157   {
158     std::function<int(int, int, int)> f1 = g3;
159     DisableAllocationGuard guard;
160     ((void)guard);
161     f1.swap(f1);
162     RTTI_ASSERT(*f1.target<int (*)(int, int, int)>() == g3);
163   }
164   assert(globalMemCounter.checkOutstandingNewEq(0));
165   {
166     std::function<int()> f1 = A(1);
167     assert(A::count == 1);
168     DisableAllocationGuard guard;
169     ((void)guard);
170     f1.swap(f1);
171     assert(A::count == 1);
172     RTTI_ASSERT(f1.target<A>()->id() == 1);
173   }
174   assert(globalMemCounter.checkOutstandingNewEq(0));
175   assert(A::count == 0);
176   {
177     std::function<int(int, int)> f1 = A(2);
178     assert(A::count == 1);
179     DisableAllocationGuard guard;
180     ((void)guard);
181     f1.swap(f1);
182     assert(A::count == 1);
183     RTTI_ASSERT(f1.target<A>()->id() == 2);
184   }
185   assert(globalMemCounter.checkOutstandingNewEq(0));
186   assert(A::count == 0);
187   {
188     std::function<int(int, int, int)> f1 = A(3);
189     assert(A::count == 1);
190     DisableAllocationGuard guard;
191     ((void)guard);
192     f1.swap(f1);
193     assert(A::count == 1);
194     RTTI_ASSERT(f1.target<A>()->id() == 3);
195   }
196   assert(globalMemCounter.checkOutstandingNewEq(0));
197   assert(A::count == 0);
198 
199   return 0;
200 }
201