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