1*fe6060f1SDimitry Andric // -*- C++ -*-
2*fe6060f1SDimitry Andric //===----------------------------------------------------------------------===//
3*fe6060f1SDimitry Andric //
4*fe6060f1SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
5*fe6060f1SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
6*fe6060f1SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7*fe6060f1SDimitry Andric //
8*fe6060f1SDimitry Andric //===----------------------------------------------------------------------===//
9*fe6060f1SDimitry Andric 
10*fe6060f1SDimitry Andric #ifndef _LIBCPP___FUNCTIONAL_INVOKE_H
11*fe6060f1SDimitry Andric #define _LIBCPP___FUNCTIONAL_INVOKE_H
12*fe6060f1SDimitry Andric 
13*fe6060f1SDimitry Andric #include <__config>
14*fe6060f1SDimitry Andric #include <__functional/weak_result_type.h>
15*fe6060f1SDimitry Andric #include <__utility/forward.h>
16*fe6060f1SDimitry Andric #include <type_traits>
17*fe6060f1SDimitry Andric 
18*fe6060f1SDimitry Andric #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
19*fe6060f1SDimitry Andric #pragma GCC system_header
20*fe6060f1SDimitry Andric #endif
21*fe6060f1SDimitry Andric 
22*fe6060f1SDimitry Andric _LIBCPP_BEGIN_NAMESPACE_STD
23*fe6060f1SDimitry Andric 
24*fe6060f1SDimitry Andric template <class _Ret, bool = is_void<_Ret>::value>
25*fe6060f1SDimitry Andric struct __invoke_void_return_wrapper
26*fe6060f1SDimitry Andric {
27*fe6060f1SDimitry Andric #ifndef _LIBCPP_CXX03_LANG
28*fe6060f1SDimitry Andric     template <class ..._Args>
29*fe6060f1SDimitry Andric     static _Ret __call(_Args&&... __args) {
30*fe6060f1SDimitry Andric         return _VSTD::__invoke(_VSTD::forward<_Args>(__args)...);
31*fe6060f1SDimitry Andric     }
32*fe6060f1SDimitry Andric #else
33*fe6060f1SDimitry Andric     template <class _Fn>
34*fe6060f1SDimitry Andric     static _Ret __call(_Fn __f) {
35*fe6060f1SDimitry Andric         return _VSTD::__invoke(__f);
36*fe6060f1SDimitry Andric     }
37*fe6060f1SDimitry Andric 
38*fe6060f1SDimitry Andric     template <class _Fn, class _A0>
39*fe6060f1SDimitry Andric     static _Ret __call(_Fn __f, _A0& __a0) {
40*fe6060f1SDimitry Andric         return _VSTD::__invoke(__f, __a0);
41*fe6060f1SDimitry Andric     }
42*fe6060f1SDimitry Andric 
43*fe6060f1SDimitry Andric     template <class _Fn, class _A0, class _A1>
44*fe6060f1SDimitry Andric     static _Ret __call(_Fn __f, _A0& __a0, _A1& __a1) {
45*fe6060f1SDimitry Andric         return _VSTD::__invoke(__f, __a0, __a1);
46*fe6060f1SDimitry Andric     }
47*fe6060f1SDimitry Andric 
48*fe6060f1SDimitry Andric     template <class _Fn, class _A0, class _A1, class _A2>
49*fe6060f1SDimitry Andric     static _Ret __call(_Fn __f, _A0& __a0, _A1& __a1, _A2& __a2){
50*fe6060f1SDimitry Andric         return _VSTD::__invoke(__f, __a0, __a1, __a2);
51*fe6060f1SDimitry Andric     }
52*fe6060f1SDimitry Andric #endif
53*fe6060f1SDimitry Andric };
54*fe6060f1SDimitry Andric 
55*fe6060f1SDimitry Andric template <class _Ret>
56*fe6060f1SDimitry Andric struct __invoke_void_return_wrapper<_Ret, true>
57*fe6060f1SDimitry Andric {
58*fe6060f1SDimitry Andric #ifndef _LIBCPP_CXX03_LANG
59*fe6060f1SDimitry Andric     template <class ..._Args>
60*fe6060f1SDimitry Andric     static void __call(_Args&&... __args) {
61*fe6060f1SDimitry Andric         _VSTD::__invoke(_VSTD::forward<_Args>(__args)...);
62*fe6060f1SDimitry Andric     }
63*fe6060f1SDimitry Andric #else
64*fe6060f1SDimitry Andric     template <class _Fn>
65*fe6060f1SDimitry Andric     static void __call(_Fn __f) {
66*fe6060f1SDimitry Andric         _VSTD::__invoke(__f);
67*fe6060f1SDimitry Andric     }
68*fe6060f1SDimitry Andric 
69*fe6060f1SDimitry Andric     template <class _Fn, class _A0>
70*fe6060f1SDimitry Andric     static void __call(_Fn __f, _A0& __a0) {
71*fe6060f1SDimitry Andric         _VSTD::__invoke(__f, __a0);
72*fe6060f1SDimitry Andric     }
73*fe6060f1SDimitry Andric 
74*fe6060f1SDimitry Andric     template <class _Fn, class _A0, class _A1>
75*fe6060f1SDimitry Andric     static void __call(_Fn __f, _A0& __a0, _A1& __a1) {
76*fe6060f1SDimitry Andric         _VSTD::__invoke(__f, __a0, __a1);
77*fe6060f1SDimitry Andric     }
78*fe6060f1SDimitry Andric 
79*fe6060f1SDimitry Andric     template <class _Fn, class _A0, class _A1, class _A2>
80*fe6060f1SDimitry Andric     static void __call(_Fn __f, _A0& __a0, _A1& __a1, _A2& __a2) {
81*fe6060f1SDimitry Andric         _VSTD::__invoke(__f, __a0, __a1, __a2);
82*fe6060f1SDimitry Andric     }
83*fe6060f1SDimitry Andric #endif
84*fe6060f1SDimitry Andric };
85*fe6060f1SDimitry Andric 
86*fe6060f1SDimitry Andric #if _LIBCPP_STD_VER > 14
87*fe6060f1SDimitry Andric 
88*fe6060f1SDimitry Andric template <class _Fn, class ..._Args>
89*fe6060f1SDimitry Andric _LIBCPP_CONSTEXPR_AFTER_CXX17 invoke_result_t<_Fn, _Args...>
90*fe6060f1SDimitry Andric invoke(_Fn&& __f, _Args&&... __args)
91*fe6060f1SDimitry Andric     noexcept(is_nothrow_invocable_v<_Fn, _Args...>)
92*fe6060f1SDimitry Andric {
93*fe6060f1SDimitry Andric     return _VSTD::__invoke(_VSTD::forward<_Fn>(__f), _VSTD::forward<_Args>(__args)...);
94*fe6060f1SDimitry Andric }
95*fe6060f1SDimitry Andric 
96*fe6060f1SDimitry Andric #endif // _LIBCPP_STD_VER > 14
97*fe6060f1SDimitry Andric 
98*fe6060f1SDimitry Andric _LIBCPP_END_NAMESPACE_STD
99*fe6060f1SDimitry Andric 
100*fe6060f1SDimitry Andric #endif // _LIBCPP___FUNCTIONAL_INVOKE_H
101