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   assert(globalMemCounter.checkOutstandingNewEq(0));
64   {
65     std::function<int(int)> f1 = A(1);
66     std::function<int(int)> f2 = A(2);
67     assert(A::count == 2);
68     assert(globalMemCounter.checkOutstandingNewEq(2));
69     assert(f1.target<A>()->id() == 1);
70     assert(f2.target<A>()->id() == 2);
71     f1.swap(f2);
72     assert(A::count == 2);
73     assert(globalMemCounter.checkOutstandingNewEq(2));
74     assert(f1.target<A>()->id() == 2);
75     assert(f2.target<A>()->id() == 1);
76   }
77   assert(A::count == 0);
78   assert(globalMemCounter.checkOutstandingNewEq(0));
79   {
80     std::function<int(int)> f1 = A(1);
81     std::function<int(int)> f2 = g;
82     assert(A::count == 1);
83     assert(globalMemCounter.checkOutstandingNewEq(1));
84     assert(f1.target<A>()->id() == 1);
85     assert(*f2.target<int (*)(int)>() == g);
86     f1.swap(f2);
87     assert(A::count == 1);
88     assert(globalMemCounter.checkOutstandingNewEq(1));
89     assert(*f1.target<int (*)(int)>() == g);
90     assert(f2.target<A>()->id() == 1);
91   }
92   assert(A::count == 0);
93   assert(globalMemCounter.checkOutstandingNewEq(0));
94   {
95     std::function<int(int)> f1 = g;
96     std::function<int(int)> f2 = A(1);
97     assert(A::count == 1);
98     assert(globalMemCounter.checkOutstandingNewEq(1));
99     assert(*f1.target<int (*)(int)>() == g);
100     assert(f2.target<A>()->id() == 1);
101     f1.swap(f2);
102     assert(A::count == 1);
103     assert(globalMemCounter.checkOutstandingNewEq(1));
104     assert(f1.target<A>()->id() == 1);
105     assert(*f2.target<int (*)(int)>() == g);
106   }
107   assert(A::count == 0);
108   assert(globalMemCounter.checkOutstandingNewEq(0));
109   {
110     std::function<int(int)> f1 = g;
111     std::function<int(int)> f2 = h;
112     assert(A::count == 0);
113     assert(globalMemCounter.checkOutstandingNewEq(0));
114     assert(*f1.target<int (*)(int)>() == g);
115     assert(*f2.target<int (*)(int)>() == h);
116     f1.swap(f2);
117     assert(A::count == 0);
118     assert(globalMemCounter.checkOutstandingNewEq(0));
119     assert(*f1.target<int (*)(int)>() == h);
120     assert(*f2.target<int (*)(int)>() == g);
121   }
122   assert(A::count == 0);
123   assert(globalMemCounter.checkOutstandingNewEq(0));
124   {
125     std::function<int(int)> f1 = A(1);
126     assert(A::count == 1);
127     {
128       DisableAllocationGuard guard;
129       ((void)guard);
130       f1.swap(f1);
131     }
132     assert(A::count == 1);
133     assert(f1.target<A>()->id() == 1);
134   }
135   assert(A::count == 0);
136   assert(globalMemCounter.checkOutstandingNewEq(0));
137   {
138     std::function<int()> f1 = g0;
139     DisableAllocationGuard guard;
140     ((void)guard);
141     f1.swap(f1);
142     assert(*f1.target<int (*)()>() == g0);
143   }
144   assert(globalMemCounter.checkOutstandingNewEq(0));
145   {
146     std::function<int(int, int)> f1 = g2;
147     DisableAllocationGuard guard;
148     ((void)guard);
149     f1.swap(f1);
150     assert(*f1.target<int (*)(int, int)>() == g2);
151   }
152   assert(globalMemCounter.checkOutstandingNewEq(0));
153   {
154     std::function<int(int, int, int)> f1 = g3;
155     DisableAllocationGuard guard;
156     ((void)guard);
157     f1.swap(f1);
158     assert(*f1.target<int (*)(int, int, int)>() == g3);
159   }
160   assert(globalMemCounter.checkOutstandingNewEq(0));
161   {
162     std::function<int()> f1 = A(1);
163     assert(A::count == 1);
164     DisableAllocationGuard guard;
165     ((void)guard);
166     f1.swap(f1);
167     assert(A::count == 1);
168     assert(f1.target<A>()->id() == 1);
169   }
170   assert(globalMemCounter.checkOutstandingNewEq(0));
171   assert(A::count == 0);
172   {
173     std::function<int(int, int)> f1 = A(2);
174     assert(A::count == 1);
175     DisableAllocationGuard guard;
176     ((void)guard);
177     f1.swap(f1);
178     assert(A::count == 1);
179     assert(f1.target<A>()->id() == 2);
180   }
181   assert(globalMemCounter.checkOutstandingNewEq(0));
182   assert(A::count == 0);
183   {
184     std::function<int(int, int, int)> f1 = A(3);
185     assert(A::count == 1);
186     DisableAllocationGuard guard;
187     ((void)guard);
188     f1.swap(f1);
189     assert(A::count == 1);
190     assert(f1.target<A>()->id() == 3);
191   }
192   assert(globalMemCounter.checkOutstandingNewEq(0));
193   assert(A::count == 0);
194 
195   return 0;
196 }
197