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