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 | // result_of<Fn(ArgTypes...)> |
12 | |
13 | // ADDITIONAL_COMPILE_FLAGS: -D_LIBCPP_ENABLE_CXX20_REMOVED_TYPE_TRAITS |
14 | // ADDITIONAL_COMPILE_FLAGS: -D_LIBCPP_DISABLE_DEPRECATION_WARNINGS |
15 | |
16 | #include <type_traits> |
17 | #include <cassert> |
18 | #include <functional> |
19 | #include <memory> |
20 | #include "test_macros.h" |
21 | |
22 | struct S |
23 | { |
24 | typedef short (*FreeFunc)(long); |
25 | operator FreeFunc() const; |
26 | double operator()(char, int&); |
27 | double const& operator()(char, int&) const; |
28 | double volatile& operator()(char, int&) volatile; |
29 | double const volatile& operator()(char, int&) const volatile; |
30 | }; |
31 | |
32 | |
33 | struct SD : public S { }; |
34 | |
35 | struct NotDerived {}; |
36 | |
37 | template <class Tp> |
38 | struct Voider { |
39 | typedef void type; |
40 | }; |
41 | |
42 | template <class T, class = void> |
43 | struct HasType : std::false_type {}; |
44 | |
45 | template <class T> |
46 | struct HasType<T, typename Voider<typename T::type>::type> : std::true_type {}; |
47 | |
48 | #if TEST_STD_VER > 14 |
49 | template <typename T, typename U> |
50 | struct test_invoke_result; |
51 | |
52 | template <typename Fn, typename ...Args, typename Ret> |
53 | struct test_invoke_result<Fn(Args...), Ret> |
54 | { |
55 | static void call() |
56 | { |
57 | static_assert(std::is_invocable<Fn, Args...>::value, "" ); |
58 | static_assert(std::is_invocable_r<Ret, Fn, Args...>::value, "" ); |
59 | ASSERT_SAME_TYPE(Ret, typename std::invoke_result<Fn, Args...>::type); |
60 | } |
61 | }; |
62 | #endif |
63 | |
64 | template <class T, class U> |
65 | void test_result_of() |
66 | { |
67 | ASSERT_SAME_TYPE(U, typename std::result_of<T>::type); |
68 | #if TEST_STD_VER > 14 |
69 | test_invoke_result<T, U>::call(); |
70 | #endif |
71 | } |
72 | |
73 | #if TEST_STD_VER > 14 |
74 | template <typename T> |
75 | struct test_invoke_no_result; |
76 | |
77 | template <typename Fn, typename ...Args> |
78 | struct test_invoke_no_result<Fn(Args...)> |
79 | { |
80 | static void call() |
81 | { |
82 | static_assert(std::is_invocable<Fn, Args...>::value == false, "" ); |
83 | static_assert((!HasType<std::invoke_result<Fn, Args...> >::value), "" ); |
84 | } |
85 | }; |
86 | #endif |
87 | |
88 | template <class T> |
89 | void test_no_result() |
90 | { |
91 | #if TEST_STD_VER >= 11 |
92 | static_assert((!HasType<std::result_of<T> >::value), "" ); |
93 | #endif |
94 | #if TEST_STD_VER > 14 |
95 | test_invoke_no_result<T>::call(); |
96 | #endif |
97 | } |
98 | |
99 | int main(int, char**) |
100 | { |
101 | typedef NotDerived ND; |
102 | { // functor object |
103 | test_result_of<S(int), short> (); |
104 | test_result_of<S&(unsigned char, int&), double> (); |
105 | test_result_of<S const&(unsigned char, int&), double const &> (); |
106 | test_result_of<S volatile&(unsigned char, int&), double volatile&> (); |
107 | test_result_of<S const volatile&(unsigned char, int&), double const volatile&> (); |
108 | } |
109 | { // pointer to function |
110 | typedef bool (&RF0)(); |
111 | typedef bool* (&RF1)(int); |
112 | typedef bool& (&RF2)(int, int); |
113 | typedef bool const& (&RF3)(int, int, int); |
114 | typedef bool (&RF4)(int, ...); |
115 | typedef bool (*PF0)(); |
116 | typedef bool* (*PF1)(int); |
117 | typedef bool& (*PF2)(int, int); |
118 | typedef bool const& (*PF3)(int, int, int); |
119 | typedef bool (*PF4)(int, ...); |
120 | typedef bool (*&PRF0)(); |
121 | typedef bool* (*&PRF1)(int); |
122 | typedef bool& (*&PRF2)(int, int); |
123 | typedef bool const& (*&PRF3)(int, int, int); |
124 | typedef bool (*&PRF4)(int, ...); |
125 | test_result_of<RF0(), bool>(); |
126 | test_result_of<RF1(int), bool*>(); |
127 | test_result_of<RF2(int, long), bool&>(); |
128 | test_result_of<RF3(int, long, int), bool const&>(); |
129 | test_result_of<RF4(int, float, void*), bool>(); |
130 | test_result_of<PF0(), bool>(); |
131 | test_result_of<PF1(int), bool*>(); |
132 | test_result_of<PF2(int, long), bool&>(); |
133 | test_result_of<PF3(int, long, int), bool const&>(); |
134 | test_result_of<PF4(int, float, void*), bool>(); |
135 | test_result_of<PRF0(), bool>(); |
136 | test_result_of<PRF1(int), bool*>(); |
137 | test_result_of<PRF2(int, long), bool&>(); |
138 | test_result_of<PRF3(int, long, int), bool const&>(); |
139 | test_result_of<PRF4(int, float, void*), bool>(); |
140 | } |
141 | { // pointer to member function |
142 | |
143 | typedef int (S::*PMS0)(); |
144 | typedef int* (S::*PMS1)(long); |
145 | typedef int& (S::*PMS2)(long, int); |
146 | typedef const int& (S::*PMS3)(int, ...); |
147 | test_result_of<PMS0( S), int> (); |
148 | test_result_of<PMS0( S&), int> (); |
149 | test_result_of<PMS0( S*), int> (); |
150 | test_result_of<PMS0( S*&), int> (); |
151 | test_result_of<PMS0( std::reference_wrapper<S>), int> (); |
152 | test_result_of<PMS0(const std::reference_wrapper<S>&), int> (); |
153 | test_result_of<PMS0( std::reference_wrapper<SD>), int> (); |
154 | test_result_of<PMS0(const std::reference_wrapper<SD>&), int> (); |
155 | test_result_of<PMS0(std::unique_ptr<S>), int> (); |
156 | test_result_of<PMS0(std::unique_ptr<SD>), int> (); |
157 | test_no_result<PMS0(const S&)>(); |
158 | test_no_result<PMS0(volatile S&)>(); |
159 | test_no_result<PMS0(const volatile S&)>(); |
160 | test_no_result<PMS0(ND & )>(); |
161 | test_no_result<PMS0(const ND& )>(); |
162 | test_no_result<PMS0(std::unique_ptr<S const> )>(); |
163 | test_no_result<PMS0(std::reference_wrapper<S const>)>(); |
164 | test_no_result<PMS0(std::reference_wrapper<ND> )>(); |
165 | test_no_result<PMS0(std::unique_ptr<ND> )>(); |
166 | |
167 | test_result_of<PMS1( S, int), int*> (); |
168 | test_result_of<PMS1( S&, int), int*> (); |
169 | test_result_of<PMS1( S*, int), int*> (); |
170 | test_result_of<PMS1( S*&, int), int*> (); |
171 | test_result_of<PMS1(std::unique_ptr<S>, int), int*> (); |
172 | test_result_of<PMS1(std::unique_ptr<SD>, int), int*> (); |
173 | test_result_of<PMS1(std::reference_wrapper<S>, int), int*> (); |
174 | test_result_of<PMS1(const std::reference_wrapper<S>&, int), int*> (); |
175 | test_result_of<PMS1(std::reference_wrapper<SD>, int), int*> (); |
176 | test_result_of<PMS1(const std::reference_wrapper<SD>&, int), int*> (); |
177 | test_no_result<PMS1(const S&, int)>(); |
178 | test_no_result<PMS1(volatile S&, int)>(); |
179 | test_no_result<PMS1(const volatile S&, int)>(); |
180 | test_no_result<PMS1(ND &, int)>(); |
181 | test_no_result<PMS1(const ND&, int)>(); |
182 | test_no_result<PMS1(std::unique_ptr<S const>, int)>(); |
183 | test_no_result<PMS1(std::reference_wrapper<S const>, int)>(); |
184 | test_no_result<PMS1(std::reference_wrapper<ND>, int)>(); |
185 | test_no_result<PMS1(std::unique_ptr<ND>, int)>(); |
186 | |
187 | test_result_of<PMS2( S, int, int), int&> (); |
188 | test_result_of<PMS2( S&, int, int), int&> (); |
189 | test_result_of<PMS2( S*, int, int), int&> (); |
190 | test_result_of<PMS2( S*&, int, int), int&> (); |
191 | test_result_of<PMS2(std::unique_ptr<S>, int, int), int&> (); |
192 | test_result_of<PMS2(std::unique_ptr<SD>, int, int), int&> (); |
193 | test_result_of<PMS2(std::reference_wrapper<S>, int, int), int&> (); |
194 | test_result_of<PMS2(const std::reference_wrapper<S>&, int, int), int&> (); |
195 | test_result_of<PMS2(std::reference_wrapper<SD>, int, int), int&> (); |
196 | test_result_of<PMS2(const std::reference_wrapper<SD>&, int, int), int&> (); |
197 | test_no_result<PMS2(const S&, int, int)>(); |
198 | test_no_result<PMS2(volatile S&, int, int)>(); |
199 | test_no_result<PMS2(const volatile S&, int, int)>(); |
200 | test_no_result<PMS2(std::unique_ptr<S const>, int, int)>(); |
201 | test_no_result<PMS2(std::reference_wrapper<S const>, int, int)>(); |
202 | test_no_result<PMS2(const ND&, int, int)>(); |
203 | test_no_result<PMS2(std::reference_wrapper<ND>, int, int)>(); |
204 | test_no_result<PMS2(std::unique_ptr<ND>, int, int)>(); |
205 | |
206 | test_result_of<PMS3(S&, int), const int &>(); |
207 | test_result_of<PMS3(S&, int, long), const int &>(); |
208 | |
209 | typedef int (S::*PMS0C)() const; |
210 | typedef int* (S::*PMS1C)(long) const; |
211 | typedef int& (S::*PMS2C)(long, int) const; |
212 | typedef const int& (S::*PMS3C)(int, ...) const; |
213 | test_result_of<PMS0C( S), int> (); |
214 | test_result_of<PMS0C( S&), int> (); |
215 | test_result_of<PMS0C(const S&), int> (); |
216 | test_result_of<PMS0C( S*), int> (); |
217 | test_result_of<PMS0C(const S*), int> (); |
218 | test_result_of<PMS0C( S*&), int> (); |
219 | test_result_of<PMS0C(const S*&), int> (); |
220 | test_result_of<PMS0C(std::unique_ptr<S>), int> (); |
221 | test_result_of<PMS0C(std::unique_ptr<SD>), int> (); |
222 | test_result_of<PMS0C(std::reference_wrapper<S> ), int> (); |
223 | test_result_of<PMS0C(std::reference_wrapper<const S> ), int> (); |
224 | test_result_of<PMS0C(const std::reference_wrapper<S> & ), int> (); |
225 | test_result_of<PMS0C(const std::reference_wrapper<const S> &), int> (); |
226 | test_result_of<PMS0C(std::reference_wrapper<SD> ), int> (); |
227 | test_result_of<PMS0C(std::reference_wrapper<const SD> ), int> (); |
228 | test_result_of<PMS0C(const std::reference_wrapper<SD> & ), int> (); |
229 | test_result_of<PMS0C(const std::reference_wrapper<const SD> &), int> (); |
230 | test_no_result<PMS0C(volatile S&)>(); |
231 | test_no_result<PMS0C(const volatile S&)>(); |
232 | |
233 | test_result_of<PMS1C( S, int), int*> (); |
234 | test_result_of<PMS1C( S&, int), int*> (); |
235 | test_result_of<PMS1C(const S&, int), int*> (); |
236 | test_result_of<PMS1C( S*, int), int*> (); |
237 | test_result_of<PMS1C(const S*, int), int*> (); |
238 | test_result_of<PMS1C( S*&, int), int*> (); |
239 | test_result_of<PMS1C(const S*&, int), int*> (); |
240 | test_result_of<PMS1C(std::unique_ptr<S>, int), int*> (); |
241 | test_no_result<PMS1C(volatile S&, int)>(); |
242 | test_no_result<PMS1C(const volatile S&, int)>(); |
243 | |
244 | test_result_of<PMS2C( S, int, int), int&> (); |
245 | test_result_of<PMS2C( S&, int, int), int&> (); |
246 | test_result_of<PMS2C(const S&, int, int), int&> (); |
247 | test_result_of<PMS2C( S*, int, int), int&> (); |
248 | test_result_of<PMS2C(const S*, int, int), int&> (); |
249 | test_result_of<PMS2C( S*&, int, int), int&> (); |
250 | test_result_of<PMS2C(const S*&, int, int), int&> (); |
251 | test_result_of<PMS2C(std::unique_ptr<S>, int, int), int&> (); |
252 | test_no_result<PMS2C(volatile S&, int, int)>(); |
253 | test_no_result<PMS2C(const volatile S&, int, int)>(); |
254 | |
255 | test_result_of<PMS3C(S&, int), const int &>(); |
256 | test_result_of<PMS3C(S&, int, long), const int &>(); |
257 | |
258 | typedef int (S::*PMS0V)() volatile; |
259 | typedef int* (S::*PMS1V)(long) volatile; |
260 | typedef int& (S::*PMS2V)(long, int) volatile; |
261 | typedef const int& (S::*PMS3V)(int, ...) volatile; |
262 | test_result_of<PMS0V( S), int> (); |
263 | test_result_of<PMS0V( S&), int> (); |
264 | test_result_of<PMS0V(volatile S&), int> (); |
265 | test_result_of<PMS0V( S*), int> (); |
266 | test_result_of<PMS0V(volatile S*), int> (); |
267 | test_result_of<PMS0V( S*&), int> (); |
268 | test_result_of<PMS0V(volatile S*&), int> (); |
269 | test_result_of<PMS0V(std::unique_ptr<S>), int> (); |
270 | test_no_result<PMS0V(const S&)>(); |
271 | test_no_result<PMS0V(const volatile S&)>(); |
272 | |
273 | test_result_of<PMS1V( S, int), int*> (); |
274 | test_result_of<PMS1V( S&, int), int*> (); |
275 | test_result_of<PMS1V(volatile S&, int), int*> (); |
276 | test_result_of<PMS1V( S*, int), int*> (); |
277 | test_result_of<PMS1V(volatile S*, int), int*> (); |
278 | test_result_of<PMS1V( S*&, int), int*> (); |
279 | test_result_of<PMS1V(volatile S*&, int), int*> (); |
280 | test_result_of<PMS1V(std::unique_ptr<S>, int), int*> (); |
281 | test_no_result<PMS1V(const S&, int)>(); |
282 | test_no_result<PMS1V(const volatile S&, int)>(); |
283 | |
284 | test_result_of<PMS2V( S, int, int), int&> (); |
285 | test_result_of<PMS2V( S&, int, int), int&> (); |
286 | test_result_of<PMS2V(volatile S&, int, int), int&> (); |
287 | test_result_of<PMS2V( S*, int, int), int&> (); |
288 | test_result_of<PMS2V(volatile S*, int, int), int&> (); |
289 | test_result_of<PMS2V( S*&, int, int), int&> (); |
290 | test_result_of<PMS2V(volatile S*&, int, int), int&> (); |
291 | test_result_of<PMS2V(std::unique_ptr<S>, int, int), int&> (); |
292 | test_no_result<PMS2V(const S&, int, int)>(); |
293 | test_no_result<PMS2V(const volatile S&, int, int)>(); |
294 | |
295 | test_result_of<PMS3V(S&, int), const int &>(); |
296 | test_result_of<PMS3V(S&, int, long), const int &>(); |
297 | |
298 | typedef int (S::*PMS0CV)() const volatile; |
299 | typedef int* (S::*PMS1CV)(long) const volatile; |
300 | typedef int& (S::*PMS2CV)(long, int) const volatile; |
301 | typedef const int& (S::*PMS3CV)(int, ...) const volatile; |
302 | test_result_of<PMS0CV( S), int> (); |
303 | test_result_of<PMS0CV( S&), int> (); |
304 | test_result_of<PMS0CV(const S&), int> (); |
305 | test_result_of<PMS0CV(volatile S&), int> (); |
306 | test_result_of<PMS0CV(const volatile S&), int> (); |
307 | test_result_of<PMS0CV( S*), int> (); |
308 | test_result_of<PMS0CV(const S*), int> (); |
309 | test_result_of<PMS0CV(volatile S*), int> (); |
310 | test_result_of<PMS0CV(const volatile S*), int> (); |
311 | test_result_of<PMS0CV( S*&), int> (); |
312 | test_result_of<PMS0CV(const S*&), int> (); |
313 | test_result_of<PMS0CV(volatile S*&), int> (); |
314 | test_result_of<PMS0CV(const volatile S*&), int> (); |
315 | test_result_of<PMS0CV(std::unique_ptr<S>), int> (); |
316 | |
317 | test_result_of<PMS1CV( S, int), int*> (); |
318 | test_result_of<PMS1CV( S&, int), int*> (); |
319 | test_result_of<PMS1CV(const S&, int), int*> (); |
320 | test_result_of<PMS1CV(volatile S&, int), int*> (); |
321 | test_result_of<PMS1CV(const volatile S&, int), int*> (); |
322 | test_result_of<PMS1CV( S*, int), int*> (); |
323 | test_result_of<PMS1CV(const S*, int), int*> (); |
324 | test_result_of<PMS1CV(volatile S*, int), int*> (); |
325 | test_result_of<PMS1CV(const volatile S*, int), int*> (); |
326 | test_result_of<PMS1CV( S*&, int), int*> (); |
327 | test_result_of<PMS1CV(const S*&, int), int*> (); |
328 | test_result_of<PMS1CV(volatile S*&, int), int*> (); |
329 | test_result_of<PMS1CV(const volatile S*&, int), int*> (); |
330 | test_result_of<PMS1CV(std::unique_ptr<S>, int), int*> (); |
331 | |
332 | test_result_of<PMS2CV( S, int, int), int&> (); |
333 | test_result_of<PMS2CV( S&, int, int), int&> (); |
334 | test_result_of<PMS2CV(const S&, int, int), int&> (); |
335 | test_result_of<PMS2CV(volatile S&, int, int), int&> (); |
336 | test_result_of<PMS2CV(const volatile S&, int, int), int&> (); |
337 | test_result_of<PMS2CV( S*, int, int), int&> (); |
338 | test_result_of<PMS2CV(const S*, int, int), int&> (); |
339 | test_result_of<PMS2CV(volatile S*, int, int), int&> (); |
340 | test_result_of<PMS2CV(const volatile S*, int, int), int&> (); |
341 | test_result_of<PMS2CV( S*&, int, int), int&> (); |
342 | test_result_of<PMS2CV(const S*&, int, int), int&> (); |
343 | test_result_of<PMS2CV(volatile S*&, int, int), int&> (); |
344 | test_result_of<PMS2CV(const volatile S*&, int, int), int&> (); |
345 | test_result_of<PMS2CV(std::unique_ptr<S>, int, int), int&> (); |
346 | |
347 | test_result_of<PMS3CV(S&, int), const int &>(); |
348 | test_result_of<PMS3CV(S&, int, long), const int &>(); |
349 | } |
350 | { // pointer to member data |
351 | typedef char S::*PMD; |
352 | test_result_of<PMD(S&), char &>(); |
353 | test_result_of<PMD(S*), char &>(); |
354 | test_result_of<PMD(S* const), char &>(); |
355 | test_result_of<PMD(const S&), const char&> (); |
356 | test_result_of<PMD(const S*), const char&> (); |
357 | test_result_of<PMD(volatile S&), volatile char&> (); |
358 | test_result_of<PMD(volatile S*), volatile char&> (); |
359 | test_result_of<PMD(const volatile S&), const volatile char&> (); |
360 | test_result_of<PMD(const volatile S*), const volatile char&> (); |
361 | test_result_of<PMD(SD&), char &>(); |
362 | test_result_of<PMD(SD const&), const char&>(); |
363 | test_result_of<PMD(SD*), char&>(); |
364 | test_result_of<PMD(const SD*), const char&>(); |
365 | test_result_of<PMD(std::unique_ptr<S>), char &>(); |
366 | test_result_of<PMD(std::unique_ptr<S const>), const char&>(); |
367 | #if TEST_STD_VER >= 11 |
368 | test_result_of<PMD(std::reference_wrapper<S>), char&>(); |
369 | test_result_of<PMD(std::reference_wrapper<S const>), const char&>(); |
370 | #endif |
371 | test_no_result<PMD(ND&)>(); |
372 | } |
373 | |
374 | return 0; |
375 | } |
376 | |