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