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     assert(f.target<A>());
79     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     assert(f.target<int(*)(int)>());
88     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     assert(f.target<int(*)(int)>() == 0);
97     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     assert(f.target<int (A::*)(int) const>() != 0);
105     }
106     {
107     std::function<void(int)> f;
108     f = &g;
109     assert(f);
110     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 #endif
122 
123   return 0;
124 }
125