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<class F>
16 // requires CopyConstructible<F> && Callable<F, ArgTypes..>
17 // && Convertible<Callable<F, ArgTypes...>::result_type
18 // operator=(F f);
19
20 #include <functional>
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()32 A()
33 {
34 ++count;
35 for (int i = 0; i < 10; ++i)
36 data_[i] = i;
37 }
38
A(const A &)39 A(const A&) {++count;}
40
~A()41 ~A() {--count;}
42
operator ()(int i) const43 int operator()(int i) const
44 {
45 for (int j = 0; j < 10; ++j)
46 i += data_[j];
47 return i;
48 }
49
foo(int) const50 int foo(int) const {return 1;}
51 };
52
53 int A::count = 0;
54
g(int)55 int g(int) {return 0;}
56
57 #if TEST_STD_VER >= 11
58 struct RValueCallable {
59 template <class ...Args>
operator ()RValueCallable60 void operator()(Args&&...) && {}
61 };
62 struct LValueCallable {
63 template <class ...Args>
operator ()LValueCallable64 void operator()(Args&&...) & {}
65 };
66 #endif
67
main(int,char **)68 int main(int, char**)
69 {
70 globalMemCounter.reset();
71 assert(globalMemCounter.checkOutstandingNewEq(0));
72 {
73 std::function<int(int)> f;
74 f = A();
75 assert(A::count == 1);
76 assert(globalMemCounter.checkOutstandingNewEq(1));
77 RTTI_ASSERT(f.target<A>());
78 RTTI_ASSERT(f.target<int(*)(int)>() == 0);
79 }
80 assert(A::count == 0);
81 assert(globalMemCounter.checkOutstandingNewEq(0));
82 {
83 std::function<int(int)> f;
84 f = g;
85 assert(globalMemCounter.checkOutstandingNewEq(0));
86 RTTI_ASSERT(f.target<int(*)(int)>());
87 RTTI_ASSERT(f.target<A>() == 0);
88 }
89 assert(globalMemCounter.checkOutstandingNewEq(0));
90 {
91 std::function<int(int)> f;
92 f = (int (*)(int))0;
93 assert(!f);
94 assert(globalMemCounter.checkOutstandingNewEq(0));
95 RTTI_ASSERT(f.target<int(*)(int)>() == 0);
96 RTTI_ASSERT(f.target<A>() == 0);
97 }
98 {
99 std::function<int(const A*, int)> f;
100 f = &A::foo;
101 assert(f);
102 assert(globalMemCounter.checkOutstandingNewEq(0));
103 RTTI_ASSERT(f.target<int (A::*)(int) const>() != 0);
104 }
105 {
106 std::function<void(int)> f;
107 f = &g;
108 assert(f);
109 RTTI_ASSERT(f.target<int(*)(int)>() != 0);
110 f(1);
111 }
112 #if TEST_STD_VER >= 11
113 {
114 using Fn = std::function<void(int, int, int)>;
115 static_assert(std::is_assignable<Fn&, LValueCallable&>::value, "");
116 static_assert(std::is_assignable<Fn&, LValueCallable>::value, "");
117 static_assert(!std::is_assignable<Fn&, RValueCallable&>::value, "");
118 static_assert(!std::is_assignable<Fn&, RValueCallable>::value, "");
119 }
120 {
121 using Fn = std::function<void(int, int, int)>;
122 static_assert(std::is_assignable<Fn&, Fn&&>::value, "");
123 }
124 {
125 using F1 = std::function<void(int, int)>;
126 using F2 = std::function<void(int, int, int)>;
127 static_assert(!std::is_assignable<F1&, F2&&>::value, "");
128 }
129 {
130 using F1 = std::function<int(int, int)>;
131 using F2 = std::function<A (int, int)>;
132 static_assert(!std::is_assignable<F1&, F2&&>::value, "");
133 static_assert(!std::is_assignable<F2&, F1&&>::value, "");
134 }
135 #endif
136
137 return 0;
138 }
139