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
24class A {
25 int data_[10];
26
27public:
28 static int count;
29
30 explicit A(int j) {
31 ++count;
32 data_[0] = j;
33 }
34
35 A(const A &a) {
36 ++count;
37 for (int i = 0; i < 10; ++i)
38 data_[i] = a.data_[i];
39 }
40
41 ~A() { --count; }
42
43 int operator()(int i) const {
44 for (int j = 0; j < 10; ++j)
45 i += data_[j];
46 return i;
47 }
48
49 int operator()() const { return -1; }
50 int operator()(int, int) const { return -2; }
51 int operator()(int, int, int) const { return -3; }
52
53 int id() const { return data_[0]; }
54};
55
56int A::count = 0;
57
58int g0() { return 0; }
59int g(int) { return 0; }
60int h(int) { return 1; }
61int g2(int, int) { return 2; }
62int g3(int, int, int) { return 3; }
63
64int 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(x&: 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(x&: 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(x&: 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(x&: 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(x&: 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(x&: 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(x&: 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(x&: 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(x&: 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(x&: 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(x&: 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

source code of libcxx/test/std/utilities/function.objects/func.wrap/func.wrap.func/func.wrap.func.mod/swap.pass.cpp