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
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 
33     A()
34     {
35         ++count;
36         for (int i = 0; i < 10; ++i)
37             data_[i] = i;
38     }
39 
40     A(const A&) {++count;}
41 
42     ~A() {--count;}
43 
44     int operator()(int i) const
45     {
46         for (int j = 0; j < 10; ++j)
47             i += data_[j];
48         return i;
49     }
50 
51     int foo(int) const {return 1;}
52 };
53 
54 int A::count = 0;
55 
56 int g(int) {return 0;}
57 
58 #if TEST_STD_VER >= 11
59 struct RValueCallable {
60     template <class ...Args>
61     void operator()(Args&&...) && {}
62 };
63 struct LValueCallable {
64     template <class ...Args>
65     void operator()(Args&&...) & {}
66 };
67 #endif
68 
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