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