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

source code of libcxx/test/std/utilities/function.objects/func.wrap/func.wrap.func/func.wrap.func.con/F.pass.cpp