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 // function(F);
16 
17 #include <functional>
18 #include <cassert>
19 
20 #include "test_macros.h"
21 #include "count_new.h"
22 
23 class A
24 {
25     int data_[10];
26 public:
27     static int count;
28 
A()29     A()
30     {
31         ++count;
32         for (int i = 0; i < 10; ++i)
33             data_[i] = i;
34     }
35 
A(const A &)36     A(const A&) {++count;}
37 
~A()38     ~A() {--count;}
39 
operator ()(int i) const40     int operator()(int i) const
41     {
42         for (int j = 0; j < 10; ++j)
43             i += data_[j];
44         return i;
45     }
46 
foo(int) const47     int foo(int) const {return 1;}
48 };
49 
50 int A::count = 0;
51 
g(int)52 int g(int) {return 0;}
53 
54 #if TEST_STD_VER >= 11
55 struct RValueCallable {
56     template <class ...Args>
operator ()RValueCallable57     void operator()(Args&&...) && {}
58 };
59 struct LValueCallable {
60     template <class ...Args>
operator ()LValueCallable61     void operator()(Args&&...) & {}
62 };
63 #endif
64 
main(int,char **)65 int main(int, char**)
66 {
67     globalMemCounter.reset();
68     assert(globalMemCounter.checkOutstandingNewEq(0));
69     {
70     std::function<int(int)> f = A();
71     assert(A::count == 1);
72     assert(globalMemCounter.checkOutstandingNewLessThanOrEqual(1));
73     RTTI_ASSERT(f.target<A>());
74     RTTI_ASSERT(f.target<int(*)(int)>() == 0);
75     }
76     assert(A::count == 0);
77     assert(globalMemCounter.checkOutstandingNewEq(0));
78     {
79     std::function<int(int)> f = g;
80     assert(globalMemCounter.checkOutstandingNewEq(0));
81     RTTI_ASSERT(f.target<int(*)(int)>());
82     RTTI_ASSERT(f.target<A>() == 0);
83     }
84     assert(globalMemCounter.checkOutstandingNewEq(0));
85     {
86     std::function<int(int)> f = (int (*)(int))0;
87     assert(!f);
88     assert(globalMemCounter.checkOutstandingNewEq(0));
89     RTTI_ASSERT(f.target<int(*)(int)>() == 0);
90     RTTI_ASSERT(f.target<A>() == 0);
91     }
92     {
93     std::function<int(const A*, int)> f = &A::foo;
94     assert(f);
95     assert(globalMemCounter.checkOutstandingNewEq(0));
96     RTTI_ASSERT(f.target<int (A::*)(int) const>() != 0);
97     }
98     {
99       std::function<void(int)> f(&g);
100       assert(f);
101       RTTI_ASSERT(f.target<int(*)(int)>() != 0);
102       f(1);
103     }
104     {
105         std::function <void()> f(static_cast<void (*)()>(0));
106         assert(!f);
107     }
108 #if TEST_STD_VER >= 11
109     {
110         using Fn = std::function<void(int, int, int)>;
111         static_assert(std::is_constructible<Fn, LValueCallable&>::value, "");
112         static_assert(std::is_constructible<Fn, LValueCallable>::value, "");
113         static_assert(!std::is_constructible<Fn, RValueCallable&>::value, "");
114         static_assert(!std::is_constructible<Fn, RValueCallable>::value, "");
115     }
116 #endif
117 
118   return 0;
119 }
120