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// template <MoveConstructible R, MoveConstructible ... ArgTypes>
16// void swap(function<R(ArgTypes...)>&, function<R(ArgTypes...)>&) noexcept;
17
18#include <functional>
19#include <cstdlib>
20#include <cassert>
21
22#include "test_macros.h"
23#include "count_new.h"
24
25class A
26{
27 int data_[10];
28public:
29 static int count;
30
31 explicit A(int j)
32 {
33 ++count;
34 data_[0] = j;
35 }
36
37 A(const A& a)
38 {
39 ++count;
40 for (int i = 0; i < 10; ++i)
41 data_[i] = a.data_[i];
42 }
43
44 ~A() {--count;}
45
46 int operator()(int i) const
47 {
48 for (int j = 0; j < 10; ++j)
49 i += data_[j];
50 return i;
51 }
52
53 int id() const {return data_[0];}
54};
55
56int A::count = 0;
57
58int g(int) {return 0;}
59int h(int) {return 1;}
60
61int main(int, char**)
62{
63 globalMemCounter.reset();
64 assert(globalMemCounter.checkOutstandingNewEq(0));
65 {
66 std::function<int(int)> f1 = A(1);
67 std::function<int(int)> f2 = A(2);
68#if TEST_STD_VER >= 11
69 static_assert(noexcept(swap(f1, f2)), "" );
70#endif
71 assert(A::count == 2);
72 assert(globalMemCounter.checkOutstandingNewLessThanOrEqual(2));
73 RTTI_ASSERT(f1.target<A>()->id() == 1);
74 RTTI_ASSERT(f2.target<A>()->id() == 2);
75 swap(x&: f1, y&: f2);
76 assert(A::count == 2);
77 assert(globalMemCounter.checkOutstandingNewLessThanOrEqual(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#if TEST_STD_VER >= 11
87 static_assert(noexcept(swap(f1, f2)), "" );
88#endif
89 assert(A::count == 1);
90 assert(globalMemCounter.checkOutstandingNewLessThanOrEqual(1));
91 RTTI_ASSERT(f1.target<A>()->id() == 1);
92 RTTI_ASSERT(*f2.target<int(*)(int)>() == g);
93 swap(x&: f1, y&: f2);
94 assert(A::count == 1);
95 assert(globalMemCounter.checkOutstandingNewLessThanOrEqual(1));
96 RTTI_ASSERT(*f1.target<int(*)(int)>() == g);
97 RTTI_ASSERT(f2.target<A>()->id() == 1);
98 }
99 assert(A::count == 0);
100 assert(globalMemCounter.checkOutstandingNewEq(0));
101 {
102 std::function<int(int)> f1 = g;
103 std::function<int(int)> f2 = A(1);
104#if TEST_STD_VER >= 11
105 static_assert(noexcept(swap(f1, f2)), "" );
106#endif
107 assert(A::count == 1);
108 assert(globalMemCounter.checkOutstandingNewLessThanOrEqual(1));
109 RTTI_ASSERT(*f1.target<int(*)(int)>() == g);
110 RTTI_ASSERT(f2.target<A>()->id() == 1);
111 swap(x&: f1, y&: f2);
112 assert(A::count == 1);
113 assert(globalMemCounter.checkOutstandingNewLessThanOrEqual(1));
114 RTTI_ASSERT(f1.target<A>()->id() == 1);
115 RTTI_ASSERT(*f2.target<int(*)(int)>() == g);
116 }
117 assert(A::count == 0);
118 assert(globalMemCounter.checkOutstandingNewEq(0));
119 {
120 std::function<int(int)> f1 = g;
121 std::function<int(int)> f2 = h;
122#if TEST_STD_VER >= 11
123 static_assert(noexcept(swap(f1, f2)), "" );
124#endif
125 assert(A::count == 0);
126 assert(globalMemCounter.checkOutstandingNewLessThanOrEqual(0));
127 RTTI_ASSERT(*f1.target<int(*)(int)>() == g);
128 RTTI_ASSERT(*f2.target<int(*)(int)>() == h);
129 swap(x&: f1, y&: f2);
130 assert(A::count == 0);
131 assert(globalMemCounter.checkOutstandingNewLessThanOrEqual(0));
132 RTTI_ASSERT(*f1.target<int(*)(int)>() == h);
133 RTTI_ASSERT(*f2.target<int(*)(int)>() == g);
134 }
135 assert(A::count == 0);
136 assert(globalMemCounter.checkOutstandingNewEq(0));
137
138 return 0;
139}
140

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