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