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