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