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(Fp);
16
17// Ensure that __not_null works for all function types.
18// See https://llvm.org/PR23589
19
20//------------------------------------------------------------------------------
21// TESTING std::function<...>::__not_null(Callable)
22//
23// Concerns:
24// 1) The call __not_null(Callable) is well formed and correct for each
25// possible 'Callable' type category. These categories include:
26// 1a) function pointers
27// 1b) member function pointer
28// 1c) member data pointer
29// 1d) callable class type
30// 1e) lambdas
31// Categories 1a, 1b, and 1c are 'Nullable' types. Only objects of these
32// types can be null. The other categories are not tested here.
33// 3) '__not_null(Callable)' is well formed when the call signature includes
34// varargs.
35// 4) '__not_null(Callable)' works for Callable types with all arities less
36// than or equal to 3 in C++03.
37// 5) '__not_null(Callable)' works when 'Callable' is a member function
38// pointer to a cv or ref qualified function type.
39//
40// Plan:
41// 1 For categories 1a, 1b and 1c define a set of
42// 'Callable' objects for this category. This set should include examples
43// of arity 0, 1, 2 and possible 3 including versions with varargs as the
44// last parameter.
45//
46// 2 For each 'Callable' object in categories 1a, 1b and 1c do the following.
47//
48// 1 Define a type 'std::function<Sig>' as 'F' where 'Sig' is compatible with
49// the signature of the 'Callable' object.
50//
51// 2 Create an object of type 'F' using a null pointer of type 'Callable'.
52// Check that 'F.target<Callable>()' is null.
53//
54// 3 Create an object of type 'F' that is not null. Check that
55// 'F.target<Callable>()' is not null and is equal to the original
56// argument.
57
58#include <functional>
59#include <type_traits>
60#include <cassert>
61
62#include "test_macros.h"
63
64///////////////////////////////////////////////////////////////////////////////
65int foo() { return 42; }
66int foo(int) { return 42; }
67int foo(int, int) { return 42; }
68int foo(int, int, int) { return 42; }
69
70int foo(...) { return 42; }
71int foo(int, ...) { return 42; }
72int foo(int, int, ...) { return 42; }
73int foo(int, int, int, ...) { return 42; }
74
75///////////////////////////////////////////////////////////////////////////////
76struct MemFun03 {
77 int foo() { return 42; }
78 int foo() const { return 42; }
79 int foo() volatile { return 42; }
80 int foo() const volatile { return 42; }
81
82 int foo(int) { return 42; }
83 int foo(int) const { return 42; }
84 int foo(int) volatile { return 42; }
85 int foo(int) const volatile { return 42; }
86
87 int foo(int, int) { return 42; }
88 int foo(int, int) const { return 42; }
89 int foo(int, int) volatile { return 42; }
90 int foo(int, int) const volatile { return 42; }
91
92 int foo(int, int, int) { return 42; }
93 int foo(int, int, int) const { return 42; }
94 int foo(int, int, int) volatile { return 42; }
95 int foo(int, int, int) const volatile { return 42; }
96
97 int foo(...) { return 42; }
98 int foo(...) const { return 42; }
99 int foo(...) volatile { return 42; }
100 int foo(...) const volatile { return 42; }
101
102 int foo(int, ...) { return 42; }
103 int foo(int, ...) const { return 42; }
104 int foo(int, ...) volatile { return 42; }
105 int foo(int, ...) const volatile { return 42; }
106
107 int foo(int, int, ...) { return 42; }
108 int foo(int, int, ...) const { return 42; }
109 int foo(int, int, ...) volatile { return 42; }
110 int foo(int, int, ...) const volatile { return 42; }
111
112 int foo(int, int, int, ...) { return 42; }
113 int foo(int, int, int, ...) const { return 42; }
114 int foo(int, int, int, ...) volatile { return 42; }
115 int foo(int, int, int, ...) const volatile { return 42; }
116};
117
118#if TEST_STD_VER >= 11
119struct MemFun11 {
120 int foo() & { return 42; }
121 int foo() const & { return 42; }
122 int foo() volatile & { return 42; }
123 int foo() const volatile & { return 42; }
124
125 int foo(...) & { return 42; }
126 int foo(...) const & { return 42; }
127 int foo(...) volatile & { return 42; }
128 int foo(...) const volatile & { return 42; }
129
130 int foo() && { return 42; }
131 int foo() const && { return 42; }
132 int foo() volatile && { return 42; }
133 int foo() const volatile && { return 42; }
134
135 int foo(...) && { return 42; }
136 int foo(...) const && { return 42; }
137 int foo(...) volatile && { return 42; }
138 int foo(...) const volatile && { return 42; }
139};
140#endif // TEST_STD_VER >= 11
141
142struct MemData {
143 int foo;
144};
145
146// Create a non-null free function by taking the address of
147// &static_cast<Tp&>(foo);
148template <class Tp>
149struct Creator {
150 static Tp create() {
151 return &foo;
152 }
153};
154
155// Create a non-null member pointer.
156template <class Ret, class Class>
157struct Creator<Ret Class::*> {
158 typedef Ret Class::*ReturnType;
159 static ReturnType create() {
160 return &Class::foo;
161 }
162};
163
164template <class TestFn, class Fn>
165void test_imp() {
166 { // Check that the null value is detected
167 TestFn tf = nullptr;
168 std::function<Fn> f = tf;
169 RTTI_ASSERT(f.template target<TestFn>() == nullptr);
170 }
171 { // Check that the non-null value is detected.
172 TestFn tf = Creator<TestFn>::create();
173 assert(tf != nullptr);
174 std::function<Fn> f = tf;
175 RTTI_ASSERT(f.template target<TestFn>() != nullptr);
176 RTTI_ASSERT(*f.template target<TestFn>() == tf);
177 }
178}
179
180void test_func() {
181 test_imp<int(*)(), int()>();
182 test_imp<int(*)(...), int()>();
183 test_imp<int(*)(int), int(int)>();
184 test_imp<int(*)(int, ...), int(int)>();
185 test_imp<int(*)(int, int), int(int, int)>();
186 test_imp<int(*)(int, int, ...), int(int, int)>();
187 test_imp<int(*)(int, int, int), int(int, int, int)>();
188 test_imp<int(*)(int, int, int, ...), int(int, int, int)>();
189}
190
191void test_mf() {
192 test_imp<int(MemFun03::*)(), int(MemFun03&)>();
193 test_imp<int(MemFun03::*)(...), int(MemFun03&)>();
194 test_imp<int(MemFun03::*)() const, int(MemFun03&)>();
195 test_imp<int(MemFun03::*)(...) const, int(MemFun03&)>();
196 test_imp<int(MemFun03::*)() volatile, int(MemFun03&)>();
197 test_imp<int(MemFun03::*)(...) volatile, int(MemFun03&)>();
198 test_imp<int(MemFun03::*)() const volatile, int(MemFun03&)>();
199 test_imp<int(MemFun03::*)(...) const volatile, int(MemFun03&)>();
200
201 test_imp<int(MemFun03::*)(int), int(MemFun03&, int)>();
202 test_imp<int(MemFun03::*)(int, ...), int(MemFun03&, int)>();
203 test_imp<int(MemFun03::*)(int) const, int(MemFun03&, int)>();
204 test_imp<int(MemFun03::*)(int, ...) const, int(MemFun03&, int)>();
205 test_imp<int(MemFun03::*)(int) volatile, int(MemFun03&, int)>();
206 test_imp<int(MemFun03::*)(int, ...) volatile, int(MemFun03&, int)>();
207 test_imp<int(MemFun03::*)(int) const volatile, int(MemFun03&, int)>();
208 test_imp<int(MemFun03::*)(int, ...) const volatile, int(MemFun03&, int)>();
209
210 test_imp<int(MemFun03::*)(int, int), int(MemFun03&, int, int)>();
211 test_imp<int(MemFun03::*)(int, int, ...), int(MemFun03&, int, int)>();
212 test_imp<int(MemFun03::*)(int, int) const, int(MemFun03&, int, int)>();
213 test_imp<int(MemFun03::*)(int, int, ...) const, int(MemFun03&, int, int)>();
214 test_imp<int(MemFun03::*)(int, int) volatile, int(MemFun03&, int, int)>();
215 test_imp<int(MemFun03::*)(int, int, ...) volatile, int(MemFun03&, int, int)>();
216 test_imp<int(MemFun03::*)(int, int) const volatile, int(MemFun03&, int, int)>();
217 test_imp<int(MemFun03::*)(int, int, ...) const volatile, int(MemFun03&, int, int)>();
218
219#if TEST_STD_VER >= 11
220 test_imp<int(MemFun11::*)() &, int(MemFun11&)>();
221 test_imp<int(MemFun11::*)(...) &, int(MemFun11&)>();
222 test_imp<int(MemFun11::*)() const &, int(MemFun11&)>();
223 test_imp<int(MemFun11::*)(...) const &, int(MemFun11&)>();
224 test_imp<int(MemFun11::*)() volatile &, int(MemFun11&)>();
225 test_imp<int(MemFun11::*)(...) volatile &, int(MemFun11&)>();
226 test_imp<int(MemFun11::*)() const volatile &, int(MemFun11&)>();
227 test_imp<int(MemFun11::*)(...) const volatile &, int(MemFun11&)>();
228
229 test_imp<int(MemFun11::*)() &&, int(MemFun11&&)>();
230 test_imp<int(MemFun11::*)(...) &&, int(MemFun11&&)>();
231 test_imp<int(MemFun11::*)() const &&, int(MemFun11&&)>();
232 test_imp<int(MemFun11::*)(...) const &&, int(MemFun11&&)>();
233 test_imp<int(MemFun11::*)() volatile &&, int(MemFun11&&)>();
234 test_imp<int(MemFun11::*)(...) volatile &&, int(MemFun11&&)>();
235 test_imp<int(MemFun11::*)() const volatile &&, int(MemFun11&&)>();
236 test_imp<int(MemFun11::*)(...) const volatile &&, int(MemFun11&&)>();
237#endif
238}
239
240void test_md() {
241 test_imp<int MemData::*, int(MemData&)>();
242}
243
244int main(int, char**) {
245 test_func();
246 test_mf();
247 test_md();
248
249 return 0;
250}
251

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