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