1 // -*- C++ -*-
2 //===----------------------------------------------------------------------===//
3 //
4 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
5 // See https://llvm.org/LICENSE.txt for license information.
6 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7 //
8 //===----------------------------------------------------------------------===//
9 
10 #ifndef _LIBCPP___FUNCTIONAL_INVOKE_H
11 #define _LIBCPP___FUNCTIONAL_INVOKE_H
12 
13 #include <__config>
14 #include <__type_traits/add_lvalue_reference.h>
15 #include <__type_traits/apply_cv.h>
16 #include <__type_traits/conditional.h>
17 #include <__type_traits/decay.h>
18 #include <__type_traits/enable_if.h>
19 #include <__type_traits/integral_constant.h>
20 #include <__type_traits/is_base_of.h>
21 #include <__type_traits/is_core_convertible.h>
22 #include <__type_traits/is_member_function_pointer.h>
23 #include <__type_traits/is_member_object_pointer.h>
24 #include <__type_traits/is_reference_wrapper.h>
25 #include <__type_traits/is_same.h>
26 #include <__type_traits/is_void.h>
27 #include <__type_traits/remove_cv.h>
28 #include <__utility/declval.h>
29 #include <__utility/forward.h>
30 
31 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
32 #  pragma GCC system_header
33 #endif
34 
35 // TODO: Disentangle the type traits and std::invoke properly
36 
37 _LIBCPP_BEGIN_NAMESPACE_STD
38 
39 struct __any
40 {
41     __any(...);
42 };
43 
44 struct __nat
45 {
46 #ifndef _LIBCPP_CXX03_LANG
47     __nat() = delete;
48     __nat(const __nat&) = delete;
49     __nat& operator=(const __nat&) = delete;
50     ~__nat() = delete;
51 #endif
52 };
53 
54 template <class _MP, bool _IsMemberFunctionPtr, bool _IsMemberObjectPtr>
55 struct __member_pointer_traits_imp
56 {
57 };
58 
59 template <class _Rp, class _Class, class ..._Param>
60 struct __member_pointer_traits_imp<_Rp (_Class::*)(_Param...), true, false>
61 {
62     typedef _Class _ClassType;
63     typedef _Rp _ReturnType;
64     typedef _Rp (_FnType) (_Param...);
65 };
66 
67 template <class _Rp, class _Class, class ..._Param>
68 struct __member_pointer_traits_imp<_Rp (_Class::*)(_Param..., ...), true, false>
69 {
70     typedef _Class _ClassType;
71     typedef _Rp _ReturnType;
72     typedef _Rp (_FnType) (_Param..., ...);
73 };
74 
75 template <class _Rp, class _Class, class ..._Param>
76 struct __member_pointer_traits_imp<_Rp (_Class::*)(_Param...) const, true, false>
77 {
78     typedef _Class const _ClassType;
79     typedef _Rp _ReturnType;
80     typedef _Rp (_FnType) (_Param...);
81 };
82 
83 template <class _Rp, class _Class, class ..._Param>
84 struct __member_pointer_traits_imp<_Rp (_Class::*)(_Param..., ...) const, true, false>
85 {
86     typedef _Class const _ClassType;
87     typedef _Rp _ReturnType;
88     typedef _Rp (_FnType) (_Param..., ...);
89 };
90 
91 template <class _Rp, class _Class, class ..._Param>
92 struct __member_pointer_traits_imp<_Rp (_Class::*)(_Param...) volatile, true, false>
93 {
94     typedef _Class volatile _ClassType;
95     typedef _Rp _ReturnType;
96     typedef _Rp (_FnType) (_Param...);
97 };
98 
99 template <class _Rp, class _Class, class ..._Param>
100 struct __member_pointer_traits_imp<_Rp (_Class::*)(_Param..., ...) volatile, true, false>
101 {
102     typedef _Class volatile _ClassType;
103     typedef _Rp _ReturnType;
104     typedef _Rp (_FnType) (_Param..., ...);
105 };
106 
107 template <class _Rp, class _Class, class ..._Param>
108 struct __member_pointer_traits_imp<_Rp (_Class::*)(_Param...) const volatile, true, false>
109 {
110     typedef _Class const volatile _ClassType;
111     typedef _Rp _ReturnType;
112     typedef _Rp (_FnType) (_Param...);
113 };
114 
115 template <class _Rp, class _Class, class ..._Param>
116 struct __member_pointer_traits_imp<_Rp (_Class::*)(_Param..., ...) const volatile, true, false>
117 {
118     typedef _Class const volatile _ClassType;
119     typedef _Rp _ReturnType;
120     typedef _Rp (_FnType) (_Param..., ...);
121 };
122 
123 template <class _Rp, class _Class, class ..._Param>
124 struct __member_pointer_traits_imp<_Rp (_Class::*)(_Param...) &, true, false>
125 {
126     typedef _Class& _ClassType;
127     typedef _Rp _ReturnType;
128     typedef _Rp (_FnType) (_Param...);
129 };
130 
131 template <class _Rp, class _Class, class ..._Param>
132 struct __member_pointer_traits_imp<_Rp (_Class::*)(_Param..., ...) &, true, false>
133 {
134     typedef _Class& _ClassType;
135     typedef _Rp _ReturnType;
136     typedef _Rp (_FnType) (_Param..., ...);
137 };
138 
139 template <class _Rp, class _Class, class ..._Param>
140 struct __member_pointer_traits_imp<_Rp (_Class::*)(_Param...) const&, true, false>
141 {
142     typedef _Class const& _ClassType;
143     typedef _Rp _ReturnType;
144     typedef _Rp (_FnType) (_Param...);
145 };
146 
147 template <class _Rp, class _Class, class ..._Param>
148 struct __member_pointer_traits_imp<_Rp (_Class::*)(_Param..., ...) const&, true, false>
149 {
150     typedef _Class const& _ClassType;
151     typedef _Rp _ReturnType;
152     typedef _Rp (_FnType) (_Param..., ...);
153 };
154 
155 template <class _Rp, class _Class, class ..._Param>
156 struct __member_pointer_traits_imp<_Rp (_Class::*)(_Param...) volatile&, true, false>
157 {
158     typedef _Class volatile& _ClassType;
159     typedef _Rp _ReturnType;
160     typedef _Rp (_FnType) (_Param...);
161 };
162 
163 template <class _Rp, class _Class, class ..._Param>
164 struct __member_pointer_traits_imp<_Rp (_Class::*)(_Param..., ...) volatile&, true, false>
165 {
166     typedef _Class volatile& _ClassType;
167     typedef _Rp _ReturnType;
168     typedef _Rp (_FnType) (_Param..., ...);
169 };
170 
171 template <class _Rp, class _Class, class ..._Param>
172 struct __member_pointer_traits_imp<_Rp (_Class::*)(_Param...) const volatile&, true, false>
173 {
174     typedef _Class const volatile& _ClassType;
175     typedef _Rp _ReturnType;
176     typedef _Rp (_FnType) (_Param...);
177 };
178 
179 template <class _Rp, class _Class, class ..._Param>
180 struct __member_pointer_traits_imp<_Rp (_Class::*)(_Param..., ...) const volatile&, true, false>
181 {
182     typedef _Class const volatile& _ClassType;
183     typedef _Rp _ReturnType;
184     typedef _Rp (_FnType) (_Param..., ...);
185 };
186 
187 template <class _Rp, class _Class, class ..._Param>
188 struct __member_pointer_traits_imp<_Rp (_Class::*)(_Param...) &&, true, false>
189 {
190     typedef _Class&& _ClassType;
191     typedef _Rp _ReturnType;
192     typedef _Rp (_FnType) (_Param...);
193 };
194 
195 template <class _Rp, class _Class, class ..._Param>
196 struct __member_pointer_traits_imp<_Rp (_Class::*)(_Param..., ...) &&, true, false>
197 {
198     typedef _Class&& _ClassType;
199     typedef _Rp _ReturnType;
200     typedef _Rp (_FnType) (_Param..., ...);
201 };
202 
203 template <class _Rp, class _Class, class ..._Param>
204 struct __member_pointer_traits_imp<_Rp (_Class::*)(_Param...) const&&, true, false>
205 {
206     typedef _Class const&& _ClassType;
207     typedef _Rp _ReturnType;
208     typedef _Rp (_FnType) (_Param...);
209 };
210 
211 template <class _Rp, class _Class, class ..._Param>
212 struct __member_pointer_traits_imp<_Rp (_Class::*)(_Param..., ...) const&&, true, false>
213 {
214     typedef _Class const&& _ClassType;
215     typedef _Rp _ReturnType;
216     typedef _Rp (_FnType) (_Param..., ...);
217 };
218 
219 template <class _Rp, class _Class, class ..._Param>
220 struct __member_pointer_traits_imp<_Rp (_Class::*)(_Param...) volatile&&, true, false>
221 {
222     typedef _Class volatile&& _ClassType;
223     typedef _Rp _ReturnType;
224     typedef _Rp (_FnType) (_Param...);
225 };
226 
227 template <class _Rp, class _Class, class ..._Param>
228 struct __member_pointer_traits_imp<_Rp (_Class::*)(_Param..., ...) volatile&&, true, false>
229 {
230     typedef _Class volatile&& _ClassType;
231     typedef _Rp _ReturnType;
232     typedef _Rp (_FnType) (_Param..., ...);
233 };
234 
235 template <class _Rp, class _Class, class ..._Param>
236 struct __member_pointer_traits_imp<_Rp (_Class::*)(_Param...) const volatile&&, true, false>
237 {
238     typedef _Class const volatile&& _ClassType;
239     typedef _Rp _ReturnType;
240     typedef _Rp (_FnType) (_Param...);
241 };
242 
243 template <class _Rp, class _Class, class ..._Param>
244 struct __member_pointer_traits_imp<_Rp (_Class::*)(_Param..., ...) const volatile&&, true, false>
245 {
246     typedef _Class const volatile&& _ClassType;
247     typedef _Rp _ReturnType;
248     typedef _Rp (_FnType) (_Param..., ...);
249 };
250 
251 template <class _Rp, class _Class>
252 struct __member_pointer_traits_imp<_Rp _Class::*, false, true>
253 {
254     typedef _Class _ClassType;
255     typedef _Rp _ReturnType;
256 };
257 
258 template <class _MP>
259 struct __member_pointer_traits
260     : public __member_pointer_traits_imp<typename remove_cv<_MP>::type,
261                     is_member_function_pointer<_MP>::value,
262                     is_member_object_pointer<_MP>::value>
263 {
264 //     typedef ... _ClassType;
265 //     typedef ... _ReturnType;
266 //     typedef ... _FnType;
267 };
268 
269 template <class _DecayedFp>
270 struct __member_pointer_class_type {};
271 
272 template <class _Ret, class _ClassType>
273 struct __member_pointer_class_type<_Ret _ClassType::*> {
274   typedef _ClassType type;
275 };
276 
277 template <class _Fp, class _A0,
278          class _DecayFp = typename decay<_Fp>::type,
279          class _DecayA0 = typename decay<_A0>::type,
280          class _ClassT = typename __member_pointer_class_type<_DecayFp>::type>
281 using __enable_if_bullet1 = typename enable_if
282     <
283         is_member_function_pointer<_DecayFp>::value
284         && is_base_of<_ClassT, _DecayA0>::value
285     >::type;
286 
287 template <class _Fp, class _A0,
288          class _DecayFp = typename decay<_Fp>::type,
289          class _DecayA0 = typename decay<_A0>::type>
290 using __enable_if_bullet2 = typename enable_if
291     <
292         is_member_function_pointer<_DecayFp>::value
293         && __is_reference_wrapper<_DecayA0>::value
294     >::type;
295 
296 template <class _Fp, class _A0,
297          class _DecayFp = typename decay<_Fp>::type,
298          class _DecayA0 = typename decay<_A0>::type,
299          class _ClassT = typename __member_pointer_class_type<_DecayFp>::type>
300 using __enable_if_bullet3 = typename enable_if
301     <
302         is_member_function_pointer<_DecayFp>::value
303         && !is_base_of<_ClassT, _DecayA0>::value
304         && !__is_reference_wrapper<_DecayA0>::value
305     >::type;
306 
307 template <class _Fp, class _A0,
308          class _DecayFp = typename decay<_Fp>::type,
309          class _DecayA0 = typename decay<_A0>::type,
310          class _ClassT = typename __member_pointer_class_type<_DecayFp>::type>
311 using __enable_if_bullet4 = typename enable_if
312     <
313         is_member_object_pointer<_DecayFp>::value
314         && is_base_of<_ClassT, _DecayA0>::value
315     >::type;
316 
317 template <class _Fp, class _A0,
318          class _DecayFp = typename decay<_Fp>::type,
319          class _DecayA0 = typename decay<_A0>::type>
320 using __enable_if_bullet5 = typename enable_if
321     <
322         is_member_object_pointer<_DecayFp>::value
323         && __is_reference_wrapper<_DecayA0>::value
324     >::type;
325 
326 template <class _Fp, class _A0,
327          class _DecayFp = typename decay<_Fp>::type,
328          class _DecayA0 = typename decay<_A0>::type,
329          class _ClassT = typename __member_pointer_class_type<_DecayFp>::type>
330 using __enable_if_bullet6 = typename enable_if
331     <
332         is_member_object_pointer<_DecayFp>::value
333         && !is_base_of<_ClassT, _DecayA0>::value
334         && !__is_reference_wrapper<_DecayA0>::value
335     >::type;
336 
337 // __invoke forward declarations
338 
339 // fall back - none of the bullets
340 
341 template <class ..._Args>
342 __nat __invoke(__any, _Args&& ...__args);
343 
344 // bullets 1, 2 and 3
345 
346 template <class _Fp, class _A0, class ..._Args,
347           class = __enable_if_bullet1<_Fp, _A0> >
348 inline _LIBCPP_INLINE_VISIBILITY
349 _LIBCPP_CONSTEXPR decltype((std::declval<_A0>().*std::declval<_Fp>())(std::declval<_Args>()...))
350 __invoke(_Fp&& __f, _A0&& __a0, _Args&& ...__args)
351     _NOEXCEPT_(noexcept((static_cast<_A0&&>(__a0).*__f)(static_cast<_Args&&>(__args)...)))
352     { return           (static_cast<_A0&&>(__a0).*__f)(static_cast<_Args&&>(__args)...); }
353 
354 template <class _Fp, class _A0, class ..._Args,
355           class = __enable_if_bullet2<_Fp, _A0> >
356 inline _LIBCPP_INLINE_VISIBILITY
357 _LIBCPP_CONSTEXPR decltype((std::declval<_A0>().get().*std::declval<_Fp>())(std::declval<_Args>()...))
358 __invoke(_Fp&& __f, _A0&& __a0, _Args&& ...__args)
359     _NOEXCEPT_(noexcept((__a0.get().*__f)(static_cast<_Args&&>(__args)...)))
360     { return          (__a0.get().*__f)(static_cast<_Args&&>(__args)...); }
361 
362 template <class _Fp, class _A0, class ..._Args,
363           class = __enable_if_bullet3<_Fp, _A0> >
364 inline _LIBCPP_INLINE_VISIBILITY
365 _LIBCPP_CONSTEXPR decltype(((*std::declval<_A0>()).*std::declval<_Fp>())(std::declval<_Args>()...))
366 __invoke(_Fp&& __f, _A0&& __a0, _Args&& ...__args)
367     _NOEXCEPT_(noexcept(((*static_cast<_A0&&>(__a0)).*__f)(static_cast<_Args&&>(__args)...)))
368     { return          ((*static_cast<_A0&&>(__a0)).*__f)(static_cast<_Args&&>(__args)...); }
369 
370 // bullets 4, 5 and 6
371 
372 template <class _Fp, class _A0,
373           class = __enable_if_bullet4<_Fp, _A0> >
374 inline _LIBCPP_INLINE_VISIBILITY
375 _LIBCPP_CONSTEXPR decltype(std::declval<_A0>().*std::declval<_Fp>())
376 __invoke(_Fp&& __f, _A0&& __a0)
377     _NOEXCEPT_(noexcept(static_cast<_A0&&>(__a0).*__f))
378     { return          static_cast<_A0&&>(__a0).*__f; }
379 
380 template <class _Fp, class _A0,
381           class = __enable_if_bullet5<_Fp, _A0> >
382 inline _LIBCPP_INLINE_VISIBILITY
383 _LIBCPP_CONSTEXPR decltype(std::declval<_A0>().get().*std::declval<_Fp>())
384 __invoke(_Fp&& __f, _A0&& __a0)
385     _NOEXCEPT_(noexcept(__a0.get().*__f))
386     { return          __a0.get().*__f; }
387 
388 template <class _Fp, class _A0,
389           class = __enable_if_bullet6<_Fp, _A0> >
390 inline _LIBCPP_INLINE_VISIBILITY
391 _LIBCPP_CONSTEXPR decltype((*std::declval<_A0>()).*std::declval<_Fp>())
392 __invoke(_Fp&& __f, _A0&& __a0)
393     _NOEXCEPT_(noexcept((*static_cast<_A0&&>(__a0)).*__f))
394     { return          (*static_cast<_A0&&>(__a0)).*__f; }
395 
396 // bullet 7
397 
398 template <class _Fp, class ..._Args>
399 inline _LIBCPP_INLINE_VISIBILITY
400 _LIBCPP_CONSTEXPR decltype(std::declval<_Fp>()(std::declval<_Args>()...))
401 __invoke(_Fp&& __f, _Args&& ...__args)
402     _NOEXCEPT_(noexcept(static_cast<_Fp&&>(__f)(static_cast<_Args&&>(__args)...)))
403     { return          static_cast<_Fp&&>(__f)(static_cast<_Args&&>(__args)...); }
404 
405 // __invokable
406 template <class _Ret, class _Fp, class ..._Args>
407 struct __invokable_r
408 {
409   template <class _XFp, class ..._XArgs>
410   static decltype(std::__invoke(declval<_XFp>(), declval<_XArgs>()...)) __try_call(int);
411   template <class _XFp, class ..._XArgs>
412   static __nat __try_call(...);
413 
414   // FIXME: Check that _Ret, _Fp, and _Args... are all complete types, cv void,
415   // or incomplete array types as required by the standard.
416   using _Result = decltype(__try_call<_Fp, _Args...>(0));
417 
418   using type = typename conditional<
419       _IsNotSame<_Result, __nat>::value,
420       typename conditional< is_void<_Ret>::value, true_type, __is_core_convertible<_Result, _Ret> >::type,
421       false_type >::type;
422   static const bool value = type::value;
423 };
424 template <class _Fp, class ..._Args>
425 using __invokable = __invokable_r<void, _Fp, _Args...>;
426 
427 template <bool _IsInvokable, bool _IsCVVoid, class _Ret, class _Fp, class ..._Args>
428 struct __nothrow_invokable_r_imp {
429   static const bool value = false;
430 };
431 
432 template <class _Ret, class _Fp, class ..._Args>
433 struct __nothrow_invokable_r_imp<true, false, _Ret, _Fp, _Args...>
434 {
435     typedef __nothrow_invokable_r_imp _ThisT;
436 
437     template <class _Tp>
438     static void __test_noexcept(_Tp) _NOEXCEPT;
439 
440     static const bool value = noexcept(_ThisT::__test_noexcept<_Ret>(
441         _VSTD::__invoke(declval<_Fp>(), declval<_Args>()...)));
442 };
443 
444 template <class _Ret, class _Fp, class ..._Args>
445 struct __nothrow_invokable_r_imp<true, true, _Ret, _Fp, _Args...>
446 {
447     static const bool value = noexcept(
448         _VSTD::__invoke(declval<_Fp>(), declval<_Args>()...));
449 };
450 
451 template <class _Ret, class _Fp, class ..._Args>
452 using __nothrow_invokable_r =
453     __nothrow_invokable_r_imp<
454             __invokable_r<_Ret, _Fp, _Args...>::value,
455             is_void<_Ret>::value,
456             _Ret, _Fp, _Args...
457     >;
458 
459 template <class _Fp, class ..._Args>
460 using __nothrow_invokable =
461     __nothrow_invokable_r_imp<
462             __invokable<_Fp, _Args...>::value,
463             true, void, _Fp, _Args...
464     >;
465 
466 template <class _Fp, class ..._Args>
467 struct __invoke_of
468     : public enable_if<
469         __invokable<_Fp, _Args...>::value,
470         typename __invokable_r<void, _Fp, _Args...>::_Result>
471 {
472 };
473 
474 template <class _Ret, bool = is_void<_Ret>::value>
475 struct __invoke_void_return_wrapper
476 {
477     template <class ..._Args>
478     static _Ret __call(_Args&&... __args) {
479         return std::__invoke(std::forward<_Args>(__args)...);
480     }
481 };
482 
483 template <class _Ret>
484 struct __invoke_void_return_wrapper<_Ret, true>
485 {
486     template <class ..._Args>
487     static void __call(_Args&&... __args) {
488         std::__invoke(std::forward<_Args>(__args)...);
489     }
490 };
491 
492 #if _LIBCPP_STD_VER > 14
493 
494 // is_invocable
495 
496 template <class _Fn, class ..._Args>
497 struct _LIBCPP_TEMPLATE_VIS is_invocable
498     : integral_constant<bool, __invokable<_Fn, _Args...>::value> {};
499 
500 template <class _Ret, class _Fn, class ..._Args>
501 struct _LIBCPP_TEMPLATE_VIS is_invocable_r
502     : integral_constant<bool, __invokable_r<_Ret, _Fn, _Args...>::value> {};
503 
504 template <class _Fn, class ..._Args>
505 inline constexpr bool is_invocable_v = is_invocable<_Fn, _Args...>::value;
506 
507 template <class _Ret, class _Fn, class ..._Args>
508 inline constexpr bool is_invocable_r_v = is_invocable_r<_Ret, _Fn, _Args...>::value;
509 
510 // is_nothrow_invocable
511 
512 template <class _Fn, class ..._Args>
513 struct _LIBCPP_TEMPLATE_VIS is_nothrow_invocable
514     : integral_constant<bool, __nothrow_invokable<_Fn, _Args...>::value> {};
515 
516 template <class _Ret, class _Fn, class ..._Args>
517 struct _LIBCPP_TEMPLATE_VIS is_nothrow_invocable_r
518     : integral_constant<bool, __nothrow_invokable_r<_Ret, _Fn, _Args...>::value> {};
519 
520 template <class _Fn, class ..._Args>
521 inline constexpr bool is_nothrow_invocable_v = is_nothrow_invocable<_Fn, _Args...>::value;
522 
523 template <class _Ret, class _Fn, class ..._Args>
524 inline constexpr bool is_nothrow_invocable_r_v = is_nothrow_invocable_r<_Ret, _Fn, _Args...>::value;
525 
526 template <class _Fn, class... _Args>
527 struct _LIBCPP_TEMPLATE_VIS invoke_result
528     : __invoke_of<_Fn, _Args...>
529 {
530 };
531 
532 template <class _Fn, class... _Args>
533 using invoke_result_t = typename invoke_result<_Fn, _Args...>::type;
534 
535 template <class _Fn, class ..._Args>
536 _LIBCPP_CONSTEXPR_AFTER_CXX17 invoke_result_t<_Fn, _Args...>
537 invoke(_Fn&& __f, _Args&&... __args)
538     noexcept(is_nothrow_invocable_v<_Fn, _Args...>)
539 {
540     return _VSTD::__invoke(_VSTD::forward<_Fn>(__f), _VSTD::forward<_Args>(__args)...);
541 }
542 
543 #endif // _LIBCPP_STD_VER > 14
544 
545 _LIBCPP_END_NAMESPACE_STD
546 
547 #endif // _LIBCPP___FUNCTIONAL_INVOKE_H
548