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