1*4d6fc14bSjoerg// -*- C++ -*- 2*4d6fc14bSjoerg//===----------------------------------------------------------------------===// 3*4d6fc14bSjoerg// 4*4d6fc14bSjoerg// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 5*4d6fc14bSjoerg// See https://llvm.org/LICENSE.txt for license information. 6*4d6fc14bSjoerg// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 7*4d6fc14bSjoerg// 8*4d6fc14bSjoerg//===----------------------------------------------------------------------===// 9*4d6fc14bSjoerg 10*4d6fc14bSjoerg#ifndef _LIBCPP_FUNCTIONAL_BASE_03 11*4d6fc14bSjoerg#define _LIBCPP_FUNCTIONAL_BASE_03 12*4d6fc14bSjoerg 13*4d6fc14bSjoerg// manual variadic expansion for <functional> 14*4d6fc14bSjoerg 15*4d6fc14bSjoerg// __invoke 16*4d6fc14bSjoerg 17*4d6fc14bSjoergtemplate <class _Ret, class _T1, bool _IsFunc, bool _IsBase> 18*4d6fc14bSjoergstruct __enable_invoke_imp; 19*4d6fc14bSjoerg 20*4d6fc14bSjoergtemplate <class _Ret, class _T1> 21*4d6fc14bSjoergstruct __enable_invoke_imp<_Ret, _T1, true, true> { 22*4d6fc14bSjoerg typedef _Ret _Bullet1; 23*4d6fc14bSjoerg typedef _Bullet1 type; 24*4d6fc14bSjoerg}; 25*4d6fc14bSjoerg 26*4d6fc14bSjoergtemplate <class _Ret, class _T1> 27*4d6fc14bSjoergstruct __enable_invoke_imp<_Ret, _T1, true, false> { 28*4d6fc14bSjoerg typedef _Ret _Bullet2; 29*4d6fc14bSjoerg typedef _Bullet2 type; 30*4d6fc14bSjoerg}; 31*4d6fc14bSjoerg 32*4d6fc14bSjoergtemplate <class _Ret, class _T1> 33*4d6fc14bSjoergstruct __enable_invoke_imp<_Ret, _T1, false, true> { 34*4d6fc14bSjoerg typedef typename add_lvalue_reference< 35*4d6fc14bSjoerg typename __apply_cv<_T1, _Ret>::type 36*4d6fc14bSjoerg >::type _Bullet3; 37*4d6fc14bSjoerg typedef _Bullet3 type; 38*4d6fc14bSjoerg}; 39*4d6fc14bSjoerg 40*4d6fc14bSjoergtemplate <class _Ret, class _T1> 41*4d6fc14bSjoergstruct __enable_invoke_imp<_Ret, _T1, false, false> { 42*4d6fc14bSjoerg typedef typename add_lvalue_reference< 43*4d6fc14bSjoerg typename __apply_cv<decltype(*declval<_T1>()), _Ret>::type 44*4d6fc14bSjoerg >::type _Bullet4; 45*4d6fc14bSjoerg typedef _Bullet4 type; 46*4d6fc14bSjoerg}; 47*4d6fc14bSjoerg 48*4d6fc14bSjoergtemplate <class _Ret, class _T1> 49*4d6fc14bSjoergstruct __enable_invoke_imp<_Ret, _T1*, false, false> { 50*4d6fc14bSjoerg typedef typename add_lvalue_reference< 51*4d6fc14bSjoerg typename __apply_cv<_T1, _Ret>::type 52*4d6fc14bSjoerg >::type _Bullet4; 53*4d6fc14bSjoerg typedef _Bullet4 type; 54*4d6fc14bSjoerg}; 55*4d6fc14bSjoerg 56*4d6fc14bSjoergtemplate <class _Fn, class _T1, 57*4d6fc14bSjoerg class _Traits = __member_pointer_traits<_Fn>, 58*4d6fc14bSjoerg class _Ret = typename _Traits::_ReturnType, 59*4d6fc14bSjoerg class _Class = typename _Traits::_ClassType> 60*4d6fc14bSjoergstruct __enable_invoke : __enable_invoke_imp< 61*4d6fc14bSjoerg _Ret, _T1, 62*4d6fc14bSjoerg is_member_function_pointer<_Fn>::value, 63*4d6fc14bSjoerg is_base_of<_Class, typename remove_reference<_T1>::type>::value> 64*4d6fc14bSjoerg{ 65*4d6fc14bSjoerg}; 66*4d6fc14bSjoerg 67*4d6fc14bSjoerg__nat __invoke(__any, ...); 68*4d6fc14bSjoerg 69*4d6fc14bSjoerg// first bullet 70*4d6fc14bSjoerg 71*4d6fc14bSjoergtemplate <class _Fn, class _T1> 72*4d6fc14bSjoerginline _LIBCPP_INLINE_VISIBILITY 73*4d6fc14bSjoergtypename __enable_invoke<_Fn, _T1>::_Bullet1 74*4d6fc14bSjoerg__invoke(_Fn __f, _T1& __t1) { 75*4d6fc14bSjoerg return (__t1.*__f)(); 76*4d6fc14bSjoerg} 77*4d6fc14bSjoerg 78*4d6fc14bSjoergtemplate <class _Fn, class _T1, class _A0> 79*4d6fc14bSjoerginline _LIBCPP_INLINE_VISIBILITY 80*4d6fc14bSjoergtypename __enable_invoke<_Fn, _T1>::_Bullet1 81*4d6fc14bSjoerg__invoke(_Fn __f, _T1& __t1, _A0& __a0) { 82*4d6fc14bSjoerg return (__t1.*__f)(__a0); 83*4d6fc14bSjoerg} 84*4d6fc14bSjoerg 85*4d6fc14bSjoergtemplate <class _Fn, class _T1, class _A0, class _A1> 86*4d6fc14bSjoerginline _LIBCPP_INLINE_VISIBILITY 87*4d6fc14bSjoergtypename __enable_invoke<_Fn, _T1>::_Bullet1 88*4d6fc14bSjoerg__invoke(_Fn __f, _T1& __t1, _A0& __a0, _A1& __a1) { 89*4d6fc14bSjoerg return (__t1.*__f)(__a0, __a1); 90*4d6fc14bSjoerg} 91*4d6fc14bSjoerg 92*4d6fc14bSjoergtemplate <class _Fn, class _T1, class _A0, class _A1, class _A2> 93*4d6fc14bSjoerginline _LIBCPP_INLINE_VISIBILITY 94*4d6fc14bSjoergtypename __enable_invoke<_Fn, _T1>::_Bullet1 95*4d6fc14bSjoerg__invoke(_Fn __f, _T1& __t1, _A0& __a0, _A1& __a1, _A2& __a2) { 96*4d6fc14bSjoerg return (__t1.*__f)(__a0, __a1, __a2); 97*4d6fc14bSjoerg} 98*4d6fc14bSjoerg 99*4d6fc14bSjoergtemplate <class _Fn, class _T1> 100*4d6fc14bSjoerginline _LIBCPP_INLINE_VISIBILITY 101*4d6fc14bSjoergtypename __enable_invoke<_Fn, _T1>::_Bullet2 102*4d6fc14bSjoerg__invoke(_Fn __f, _T1& __t1) { 103*4d6fc14bSjoerg return ((*__t1).*__f)(); 104*4d6fc14bSjoerg} 105*4d6fc14bSjoerg 106*4d6fc14bSjoergtemplate <class _Fn, class _T1, class _A0> 107*4d6fc14bSjoerginline _LIBCPP_INLINE_VISIBILITY 108*4d6fc14bSjoergtypename __enable_invoke<_Fn, _T1>::_Bullet2 109*4d6fc14bSjoerg__invoke(_Fn __f, _T1& __t1, _A0& __a0) { 110*4d6fc14bSjoerg return ((*__t1).*__f)(__a0); 111*4d6fc14bSjoerg} 112*4d6fc14bSjoerg 113*4d6fc14bSjoergtemplate <class _Fn, class _T1, class _A0, class _A1> 114*4d6fc14bSjoerginline _LIBCPP_INLINE_VISIBILITY 115*4d6fc14bSjoergtypename __enable_invoke<_Fn, _T1>::_Bullet2 116*4d6fc14bSjoerg__invoke(_Fn __f, _T1& __t1, _A0& __a0, _A1& __a1) { 117*4d6fc14bSjoerg return ((*__t1).*__f)(__a0, __a1); 118*4d6fc14bSjoerg} 119*4d6fc14bSjoerg 120*4d6fc14bSjoergtemplate <class _Fn, class _T1, class _A0, class _A1, class _A2> 121*4d6fc14bSjoerginline _LIBCPP_INLINE_VISIBILITY 122*4d6fc14bSjoergtypename __enable_invoke<_Fn, _T1>::_Bullet2 123*4d6fc14bSjoerg__invoke(_Fn __f, _T1& __t1, _A0& __a0, _A1& __a1, _A2& __a2) { 124*4d6fc14bSjoerg return ((*__t1).*__f)(__a0, __a1, __a2); 125*4d6fc14bSjoerg} 126*4d6fc14bSjoerg 127*4d6fc14bSjoergtemplate <class _Fn, class _T1> 128*4d6fc14bSjoerginline _LIBCPP_INLINE_VISIBILITY 129*4d6fc14bSjoergtypename __enable_invoke<_Fn, _T1>::_Bullet3 130*4d6fc14bSjoerg__invoke(_Fn __f, _T1& __t1) { 131*4d6fc14bSjoerg return __t1.*__f; 132*4d6fc14bSjoerg} 133*4d6fc14bSjoerg 134*4d6fc14bSjoergtemplate <class _Fn, class _T1> 135*4d6fc14bSjoerginline _LIBCPP_INLINE_VISIBILITY 136*4d6fc14bSjoergtypename __enable_invoke<_Fn, _T1>::_Bullet4 137*4d6fc14bSjoerg__invoke(_Fn __f, _T1& __t1) { 138*4d6fc14bSjoerg return (*__t1).*__f; 139*4d6fc14bSjoerg} 140*4d6fc14bSjoerg 141*4d6fc14bSjoerg// fifth bullet 142*4d6fc14bSjoerg 143*4d6fc14bSjoergtemplate <class _Fp> 144*4d6fc14bSjoerginline _LIBCPP_INLINE_VISIBILITY 145*4d6fc14bSjoergdecltype(declval<_Fp&>()()) 146*4d6fc14bSjoerg__invoke(_Fp& __f) 147*4d6fc14bSjoerg{ 148*4d6fc14bSjoerg return __f(); 149*4d6fc14bSjoerg} 150*4d6fc14bSjoerg 151*4d6fc14bSjoergtemplate <class _Fp, class _A0> 152*4d6fc14bSjoerginline _LIBCPP_INLINE_VISIBILITY 153*4d6fc14bSjoergdecltype(declval<_Fp&>()(declval<_A0&>())) 154*4d6fc14bSjoerg__invoke(_Fp& __f, _A0& __a0) 155*4d6fc14bSjoerg{ 156*4d6fc14bSjoerg return __f(__a0); 157*4d6fc14bSjoerg} 158*4d6fc14bSjoerg 159*4d6fc14bSjoergtemplate <class _Fp, class _A0, class _A1> 160*4d6fc14bSjoerginline _LIBCPP_INLINE_VISIBILITY 161*4d6fc14bSjoergdecltype(declval<_Fp&>()(declval<_A0&>(), declval<_A1&>())) 162*4d6fc14bSjoerg__invoke(_Fp& __f, _A0& __a0, _A1& __a1) 163*4d6fc14bSjoerg{ 164*4d6fc14bSjoerg return __f(__a0, __a1); 165*4d6fc14bSjoerg} 166*4d6fc14bSjoerg 167*4d6fc14bSjoergtemplate <class _Fp, class _A0, class _A1, class _A2> 168*4d6fc14bSjoerginline _LIBCPP_INLINE_VISIBILITY 169*4d6fc14bSjoergdecltype(declval<_Fp&>()(declval<_A0&>(), declval<_A1&>(), declval<_A2&>())) 170*4d6fc14bSjoerg__invoke(_Fp& __f, _A0& __a0, _A1& __a1, _A2& __a2) 171*4d6fc14bSjoerg{ 172*4d6fc14bSjoerg return __f(__a0, __a1, __a2); 173*4d6fc14bSjoerg} 174*4d6fc14bSjoerg 175*4d6fc14bSjoergtemplate <class _Fp, bool = __has_result_type<__weak_result_type<_Fp> >::value> 176*4d6fc14bSjoergstruct __invoke_return 177*4d6fc14bSjoerg{ 178*4d6fc14bSjoerg typedef typename __weak_result_type<_Fp>::result_type type; 179*4d6fc14bSjoerg}; 180*4d6fc14bSjoerg 181*4d6fc14bSjoergtemplate <class _Fp> 182*4d6fc14bSjoergstruct __invoke_return<_Fp, false> 183*4d6fc14bSjoerg{ 184*4d6fc14bSjoerg typedef decltype(_VSTD::__invoke(declval<_Fp&>())) type; 185*4d6fc14bSjoerg}; 186*4d6fc14bSjoerg 187*4d6fc14bSjoergtemplate <class _Tp, class _A0> 188*4d6fc14bSjoergstruct __invoke_return0 189*4d6fc14bSjoerg{ 190*4d6fc14bSjoerg typedef decltype(_VSTD::__invoke(declval<_Tp&>(), declval<_A0&>())) type; 191*4d6fc14bSjoerg}; 192*4d6fc14bSjoerg 193*4d6fc14bSjoergtemplate <class _Rp, class _Tp, class _A0> 194*4d6fc14bSjoergstruct __invoke_return0<_Rp _Tp::*, _A0> 195*4d6fc14bSjoerg{ 196*4d6fc14bSjoerg typedef typename __enable_invoke<_Rp _Tp::*, _A0>::type type; 197*4d6fc14bSjoerg}; 198*4d6fc14bSjoerg 199*4d6fc14bSjoergtemplate <class _Tp, class _A0, class _A1> 200*4d6fc14bSjoergstruct __invoke_return1 201*4d6fc14bSjoerg{ 202*4d6fc14bSjoerg typedef decltype(_VSTD::__invoke(declval<_Tp&>(), declval<_A0&>(), 203*4d6fc14bSjoerg declval<_A1&>())) type; 204*4d6fc14bSjoerg}; 205*4d6fc14bSjoerg 206*4d6fc14bSjoergtemplate <class _Rp, class _Class, class _A0, class _A1> 207*4d6fc14bSjoergstruct __invoke_return1<_Rp _Class::*, _A0, _A1> { 208*4d6fc14bSjoerg typedef typename __enable_invoke<_Rp _Class::*, _A0>::type type; 209*4d6fc14bSjoerg}; 210*4d6fc14bSjoerg 211*4d6fc14bSjoergtemplate <class _Tp, class _A0, class _A1, class _A2> 212*4d6fc14bSjoergstruct __invoke_return2 213*4d6fc14bSjoerg{ 214*4d6fc14bSjoerg typedef decltype(_VSTD::__invoke(declval<_Tp&>(), declval<_A0&>(), 215*4d6fc14bSjoerg declval<_A1&>(), 216*4d6fc14bSjoerg declval<_A2&>())) type; 217*4d6fc14bSjoerg}; 218*4d6fc14bSjoerg 219*4d6fc14bSjoergtemplate <class _Ret, class _Class, class _A0, class _A1, class _A2> 220*4d6fc14bSjoergstruct __invoke_return2<_Ret _Class::*, _A0, _A1, _A2> { 221*4d6fc14bSjoerg typedef typename __enable_invoke<_Ret _Class::*, _A0>::type type; 222*4d6fc14bSjoerg}; 223*4d6fc14bSjoerg#endif // _LIBCPP_FUNCTIONAL_BASE_03 224