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