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