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

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