1 //===----------------------------------------------------------------------===//
2 //
3 // The LLVM Compiler Infrastructure
4 //
5 // This file is dual licensed under the MIT and the University of Illinois Open
6 // Source Licenses. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9
10 // <functional>
11
12 // class function<R(ArgTypes...)>
13
14 // function(Fp);
15
16 // Ensure that __not_null works for all function types.
17 // See https://bugs.llvm.org/show_bug.cgi?id=23589
18
19 //------------------------------------------------------------------------------
20 // TESTING std::function<...>::__not_null(Callable)
21 //
22 // Concerns:
23 // 1) The call __not_null(Callable) is well formed and correct for each
24 // possible 'Callable' type category. These categories include:
25 // 1a) function pointers
26 // 1b) member function pointer
27 // 1c) member data pointer
28 // 1d) callable class type
29 // 1e) lambdas
30 // Categories 1a, 1b, and 1c are 'Nullable' types. Only objects of these
31 // types can be null. The other categories are not tested here.
32 // 3) '__not_null(Callable)' is well formed when the call signature includes
33 // varargs.
34 // 4) '__not_null(Callable)' works for Callable types with all arities less
35 // than or equal to 3 in C++03.
36 // 5) '__not_null(Callable)' works when 'Callable' is a member function
37 // pointer to a cv or ref qualified function type.
38 //
39 // Plan:
40 // 1 For categories 1a, 1b and 1c define a set of
41 // 'Callable' objects for this category. This set should include examples
42 // of arity 0, 1, 2 and possible 3 including versions with varargs as the
43 // last parameter.
44 //
45 // 2 For each 'Callable' object in categories 1a, 1b and 1c do the following.
46 //
47 // 1 Define a type 'std::function<Sig>' as 'F' where 'Sig' is compatible with
48 // the signature of the 'Callable' object.
49 //
50 // 2 Create an object of type 'F' using a null pointer of type 'Callable'.
51 // Check that 'F.target<Callable>()' is null.
52 //
53 // 3 Create an object of type 'F' that is not null. Check that
54 // 'F.target<Callable>()' is not null and is equal to the original
55 // argument.
56
57 #include <functional>
58 #include <type_traits>
59 #include <cassert>
60
61 #include "test_macros.h"
62
63 ///////////////////////////////////////////////////////////////////////////////
foo()64 int foo() { return 42; }
foo(int)65 int foo(int) { return 42; }
foo(int,int)66 int foo(int, int) { return 42; }
foo(int,int,int)67 int foo(int, int, int) { return 42; }
68
foo(...)69 int foo(...) { return 42; }
foo(int,...)70 int foo(int, ...) { return 42; }
foo(int,int,...)71 int foo(int, int, ...) { return 42; }
foo(int,int,int,...)72 int foo(int, int, int, ...) { return 42; }
73
74 ///////////////////////////////////////////////////////////////////////////////
75 struct MemFun03 {
fooMemFun0376 int foo() { return 42; }
fooMemFun0377 int foo() const { return 42; }
fooMemFun0378 int foo() volatile { return 42; }
fooMemFun0379 int foo() const volatile { return 42; }
80
fooMemFun0381 int foo(int) { return 42; }
fooMemFun0382 int foo(int) const { return 42; }
fooMemFun0383 int foo(int) volatile { return 42; }
fooMemFun0384 int foo(int) const volatile { return 42; }
85
fooMemFun0386 int foo(int, int) { return 42; }
fooMemFun0387 int foo(int, int) const { return 42; }
fooMemFun0388 int foo(int, int) volatile { return 42; }
fooMemFun0389 int foo(int, int) const volatile { return 42; }
90
fooMemFun0391 int foo(int, int, int) { return 42; }
fooMemFun0392 int foo(int, int, int) const { return 42; }
fooMemFun0393 int foo(int, int, int) volatile { return 42; }
fooMemFun0394 int foo(int, int, int) const volatile { return 42; }
95
fooMemFun0396 int foo(...) { return 42; }
fooMemFun0397 int foo(...) const { return 42; }
fooMemFun0398 int foo(...) volatile { return 42; }
fooMemFun0399 int foo(...) const volatile { return 42; }
100
fooMemFun03101 int foo(int, ...) { return 42; }
fooMemFun03102 int foo(int, ...) const { return 42; }
fooMemFun03103 int foo(int, ...) volatile { return 42; }
fooMemFun03104 int foo(int, ...) const volatile { return 42; }
105
fooMemFun03106 int foo(int, int, ...) { return 42; }
fooMemFun03107 int foo(int, int, ...) const { return 42; }
fooMemFun03108 int foo(int, int, ...) volatile { return 42; }
fooMemFun03109 int foo(int, int, ...) const volatile { return 42; }
110
fooMemFun03111 int foo(int, int, int, ...) { return 42; }
fooMemFun03112 int foo(int, int, int, ...) const { return 42; }
fooMemFun03113 int foo(int, int, int, ...) volatile { return 42; }
fooMemFun03114 int foo(int, int, int, ...) const volatile { return 42; }
115 };
116
117 #if TEST_STD_VER >= 11
118 struct MemFun11 {
fooMemFun11119 int foo() & { return 42; }
fooMemFun11120 int foo() const & { return 42; }
fooMemFun11121 int foo() volatile & { return 42; }
fooMemFun11122 int foo() const volatile & { return 42; }
123
fooMemFun11124 int foo(...) & { return 42; }
fooMemFun11125 int foo(...) const & { return 42; }
fooMemFun11126 int foo(...) volatile & { return 42; }
fooMemFun11127 int foo(...) const volatile & { return 42; }
128
fooMemFun11129 int foo() && { return 42; }
fooMemFun11130 int foo() const && { return 42; }
fooMemFun11131 int foo() volatile && { return 42; }
fooMemFun11132 int foo() const volatile && { return 42; }
133
fooMemFun11134 int foo(...) && { return 42; }
fooMemFun11135 int foo(...) const && { return 42; }
fooMemFun11136 int foo(...) volatile && { return 42; }
fooMemFun11137 int foo(...) const volatile && { return 42; }
138 };
139 #endif // TEST_STD_VER >= 11
140
141 struct MemData {
142 int foo;
143 };
144
145 // Create a non-null free function by taking the address of
146 // &static_cast<Tp&>(foo);
147 template <class Tp>
148 struct Creator {
createCreator149 static Tp create() {
150 return &foo;
151 }
152 };
153
154 // Create a non-null member pointer.
155 template <class Ret, class Class>
156 struct Creator<Ret Class::*> {
157 typedef Ret Class::*ReturnType;
createCreator158 static ReturnType create() {
159 return &Class::foo;
160 }
161 };
162
163 template <class TestFn, class Fn>
test_imp()164 void test_imp() {
165 { // Check that the null value is detected
166 TestFn tf = nullptr;
167 std::function<Fn> f = tf;
168 assert(f.template target<TestFn>() == nullptr);
169 }
170 { // Check that the non-null value is detected.
171 TestFn tf = Creator<TestFn>::create();
172 assert(tf != nullptr);
173 std::function<Fn> f = tf;
174 assert(f.template target<TestFn>() != nullptr);
175 assert(*f.template target<TestFn>() == tf);
176 }
177 }
178
test_func()179 void test_func() {
180 test_imp<int(*)(), int()>();
181 test_imp<int(*)(...), int()>();
182 test_imp<int(*)(int), int(int)>();
183 test_imp<int(*)(int, ...), int(int)>();
184 test_imp<int(*)(int, int), int(int, int)>();
185 test_imp<int(*)(int, int, ...), int(int, int)>();
186 test_imp<int(*)(int, int, int), int(int, int, int)>();
187 test_imp<int(*)(int, int, int, ...), int(int, int, int)>();
188 }
189
test_mf()190 void test_mf() {
191 test_imp<int(MemFun03::*)(), int(MemFun03&)>();
192 test_imp<int(MemFun03::*)(...), int(MemFun03&)>();
193 test_imp<int(MemFun03::*)() const, int(MemFun03&)>();
194 test_imp<int(MemFun03::*)(...) const, int(MemFun03&)>();
195 test_imp<int(MemFun03::*)() volatile, int(MemFun03&)>();
196 test_imp<int(MemFun03::*)(...) volatile, int(MemFun03&)>();
197 test_imp<int(MemFun03::*)() const volatile, int(MemFun03&)>();
198 test_imp<int(MemFun03::*)(...) const volatile, int(MemFun03&)>();
199
200 test_imp<int(MemFun03::*)(int), int(MemFun03&, int)>();
201 test_imp<int(MemFun03::*)(int, ...), int(MemFun03&, int)>();
202 test_imp<int(MemFun03::*)(int) const, int(MemFun03&, int)>();
203 test_imp<int(MemFun03::*)(int, ...) const, int(MemFun03&, int)>();
204 test_imp<int(MemFun03::*)(int) volatile, int(MemFun03&, int)>();
205 test_imp<int(MemFun03::*)(int, ...) volatile, int(MemFun03&, int)>();
206 test_imp<int(MemFun03::*)(int) const volatile, int(MemFun03&, int)>();
207 test_imp<int(MemFun03::*)(int, ...) const volatile, int(MemFun03&, int)>();
208
209 test_imp<int(MemFun03::*)(int, int), int(MemFun03&, int, int)>();
210 test_imp<int(MemFun03::*)(int, int, ...), int(MemFun03&, int, int)>();
211 test_imp<int(MemFun03::*)(int, int) const, int(MemFun03&, int, int)>();
212 test_imp<int(MemFun03::*)(int, int, ...) const, int(MemFun03&, int, int)>();
213 test_imp<int(MemFun03::*)(int, int) volatile, int(MemFun03&, int, int)>();
214 test_imp<int(MemFun03::*)(int, int, ...) volatile, int(MemFun03&, int, int)>();
215 test_imp<int(MemFun03::*)(int, int) const volatile, int(MemFun03&, int, int)>();
216 test_imp<int(MemFun03::*)(int, int, ...) const volatile, int(MemFun03&, int, int)>();
217
218 #if TEST_STD_VER >= 11
219 test_imp<int(MemFun11::*)() &, int(MemFun11&)>();
220 test_imp<int(MemFun11::*)(...) &, int(MemFun11&)>();
221 test_imp<int(MemFun11::*)() const &, int(MemFun11&)>();
222 test_imp<int(MemFun11::*)(...) const &, int(MemFun11&)>();
223 test_imp<int(MemFun11::*)() volatile &, int(MemFun11&)>();
224 test_imp<int(MemFun11::*)(...) volatile &, int(MemFun11&)>();
225 test_imp<int(MemFun11::*)() const volatile &, int(MemFun11&)>();
226 test_imp<int(MemFun11::*)(...) const volatile &, int(MemFun11&)>();
227
228 test_imp<int(MemFun11::*)() &&, int(MemFun11&&)>();
229 test_imp<int(MemFun11::*)(...) &&, int(MemFun11&&)>();
230 test_imp<int(MemFun11::*)() const &&, int(MemFun11&&)>();
231 test_imp<int(MemFun11::*)(...) const &&, int(MemFun11&&)>();
232 test_imp<int(MemFun11::*)() volatile &&, int(MemFun11&&)>();
233 test_imp<int(MemFun11::*)(...) volatile &&, int(MemFun11&&)>();
234 test_imp<int(MemFun11::*)() const volatile &&, int(MemFun11&&)>();
235 test_imp<int(MemFun11::*)(...) const volatile &&, int(MemFun11&&)>();
236 #endif
237 }
238
test_md()239 void test_md() {
240 test_imp<int MemData::*, int(MemData&)>();
241 }
242
main()243 int main() {
244 test_func();
245 test_mf();
246 test_md();
247 }
248