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 | /////////////////////////////////////////////////////////////////////////////// |
65 | int foo() { return 42; } |
66 | int foo(int) { return 42; } |
67 | int foo(int, int) { return 42; } |
68 | int foo(int, int, int) { return 42; } |
69 | |
70 | int foo(...) { return 42; } |
71 | int foo(int, ...) { return 42; } |
72 | int foo(int, int, ...) { return 42; } |
73 | int foo(int, int, int, ...) { return 42; } |
74 | |
75 | /////////////////////////////////////////////////////////////////////////////// |
76 | struct 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 |
119 | struct 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 | |
142 | struct MemData { |
143 | int foo; |
144 | }; |
145 | |
146 | // Create a non-null free function by taking the address of |
147 | // &static_cast<Tp&>(foo); |
148 | template <class Tp> |
149 | struct Creator { |
150 | static Tp create() { |
151 | return &foo; |
152 | } |
153 | }; |
154 | |
155 | // Create a non-null member pointer. |
156 | template <class Ret, class Class> |
157 | struct Creator<Ret Class::*> { |
158 | typedef Ret Class::*ReturnType; |
159 | static ReturnType create() { |
160 | return &Class::foo; |
161 | } |
162 | }; |
163 | |
164 | template <class TestFn, class Fn> |
165 | void 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 | |
180 | void 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 | |
191 | void 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 | |
240 | void test_md() { |
241 | test_imp<int MemData::*, int(MemData&)>(); |
242 | } |
243 | |
244 | int main(int, char**) { |
245 | test_func(); |
246 | test_mf(); |
247 | test_md(); |
248 | |
249 | return 0; |
250 | } |
251 | |