17a984708SDavid Chisnall// -*- C++ -*- 27a984708SDavid Chisnall//===----------------------------------------------------------------------===// 37a984708SDavid Chisnall// 47a984708SDavid Chisnall// The LLVM Compiler Infrastructure 57a984708SDavid Chisnall// 67a984708SDavid Chisnall// This file is dual licensed under the MIT and the University of Illinois Open 77a984708SDavid Chisnall// Source Licenses. See LICENSE.TXT for details. 87a984708SDavid Chisnall// 97a984708SDavid Chisnall//===----------------------------------------------------------------------===// 107a984708SDavid Chisnall 117a984708SDavid Chisnall#ifndef _LIBCPP_FUNCTIONAL_BASE_03 127a984708SDavid Chisnall#define _LIBCPP_FUNCTIONAL_BASE_03 137a984708SDavid Chisnall 147a984708SDavid Chisnall// manual variadic expansion for <functional> 157a984708SDavid Chisnall 167a984708SDavid Chisnall// __invoke 177a984708SDavid Chisnall 18*9729cf09SDimitry Andrictemplate <class _Ret, class _T1, bool _IsFunc, bool _IsBase> 19*9729cf09SDimitry Andricstruct __enable_invoke_imp; 20*9729cf09SDimitry Andric 21*9729cf09SDimitry Andrictemplate <class _Ret, class _T1> 22*9729cf09SDimitry Andricstruct __enable_invoke_imp<_Ret, _T1, true, true> { 23*9729cf09SDimitry Andric typedef _Ret _Bullet1; 24*9729cf09SDimitry Andric typedef _Bullet1 type; 25*9729cf09SDimitry Andric}; 26*9729cf09SDimitry Andric 27*9729cf09SDimitry Andrictemplate <class _Ret, class _T1> 28*9729cf09SDimitry Andricstruct __enable_invoke_imp<_Ret, _T1, true, false> { 29*9729cf09SDimitry Andric typedef _Ret _Bullet2; 30*9729cf09SDimitry Andric typedef _Bullet2 type; 31*9729cf09SDimitry Andric}; 32*9729cf09SDimitry Andric 33*9729cf09SDimitry Andrictemplate <class _Ret, class _T1> 34*9729cf09SDimitry Andricstruct __enable_invoke_imp<_Ret, _T1, false, true> { 35*9729cf09SDimitry Andric typedef typename add_lvalue_reference< 36*9729cf09SDimitry Andric typename __apply_cv<_T1, _Ret>::type 37*9729cf09SDimitry Andric >::type _Bullet3; 38*9729cf09SDimitry Andric typedef _Bullet3 type; 39*9729cf09SDimitry Andric}; 40*9729cf09SDimitry Andric 41*9729cf09SDimitry Andrictemplate <class _Ret, class _T1> 42*9729cf09SDimitry Andricstruct __enable_invoke_imp<_Ret, _T1, false, false> { 43*9729cf09SDimitry Andric typedef typename add_lvalue_reference< 44*9729cf09SDimitry Andric typename __apply_cv<decltype(*_VSTD::declval<_T1>()), _Ret>::type 45*9729cf09SDimitry Andric >::type _Bullet4; 46*9729cf09SDimitry Andric typedef _Bullet4 type; 47*9729cf09SDimitry Andric}; 48*9729cf09SDimitry Andric 49*9729cf09SDimitry Andrictemplate <class _Ret, class _T1> 50*9729cf09SDimitry Andricstruct __enable_invoke_imp<_Ret, _T1*, false, false> { 51*9729cf09SDimitry Andric typedef typename add_lvalue_reference< 52*9729cf09SDimitry Andric typename __apply_cv<_T1, _Ret>::type 53*9729cf09SDimitry Andric >::type _Bullet4; 54*9729cf09SDimitry Andric typedef _Bullet4 type; 55*9729cf09SDimitry Andric}; 56*9729cf09SDimitry Andric 57*9729cf09SDimitry Andrictemplate <class _Fn, class _T1, 58*9729cf09SDimitry Andric class _Traits = __member_pointer_traits<_Fn>, 59*9729cf09SDimitry Andric class _Ret = typename _Traits::_ReturnType, 60*9729cf09SDimitry Andric class _Class = typename _Traits::_ClassType> 61*9729cf09SDimitry Andricstruct __enable_invoke : __enable_invoke_imp< 62*9729cf09SDimitry Andric _Ret, _T1, 63*9729cf09SDimitry Andric is_member_function_pointer<_Fn>::value, 64*9729cf09SDimitry Andric is_base_of<_Class, typename remove_reference<_T1>::type>::value> 65*9729cf09SDimitry Andric{ 66*9729cf09SDimitry Andric}; 67*9729cf09SDimitry Andric 68*9729cf09SDimitry Andric__nat __invoke(__any, ...); 697a984708SDavid Chisnall 707a984708SDavid Chisnall// first bullet 717a984708SDavid Chisnall 72*9729cf09SDimitry Andrictemplate <class _Fn, class _T1> 737a984708SDavid Chisnallinline _LIBCPP_INLINE_VISIBILITY 74*9729cf09SDimitry Andrictypename __enable_invoke<_Fn, _T1>::_Bullet1 75*9729cf09SDimitry Andric__invoke(_Fn __f, _T1& __t1) { 767a984708SDavid Chisnall return (__t1.*__f)(); 777a984708SDavid Chisnall} 787a984708SDavid Chisnall 79*9729cf09SDimitry Andrictemplate <class _Fn, class _T1, class _A0> 807a984708SDavid Chisnallinline _LIBCPP_INLINE_VISIBILITY 81*9729cf09SDimitry Andrictypename __enable_invoke<_Fn, _T1>::_Bullet1 82*9729cf09SDimitry Andric__invoke(_Fn __f, _T1& __t1, _A0& __a0) { 837a984708SDavid Chisnall return (__t1.*__f)(__a0); 847a984708SDavid Chisnall} 857a984708SDavid Chisnall 86*9729cf09SDimitry Andrictemplate <class _Fn, class _T1, class _A0, class _A1> 877a984708SDavid Chisnallinline _LIBCPP_INLINE_VISIBILITY 88*9729cf09SDimitry Andrictypename __enable_invoke<_Fn, _T1>::_Bullet1 89*9729cf09SDimitry Andric__invoke(_Fn __f, _T1& __t1, _A0& __a0, _A1& __a1) { 907a984708SDavid Chisnall return (__t1.*__f)(__a0, __a1); 917a984708SDavid Chisnall} 927a984708SDavid Chisnall 93*9729cf09SDimitry Andrictemplate <class _Fn, class _T1, class _A0, class _A1, class _A2> 947a984708SDavid Chisnallinline _LIBCPP_INLINE_VISIBILITY 95*9729cf09SDimitry Andrictypename __enable_invoke<_Fn, _T1>::_Bullet1 96*9729cf09SDimitry Andric__invoke(_Fn __f, _T1& __t1, _A0& __a0, _A1& __a1, _A2& __a2) { 977a984708SDavid Chisnall return (__t1.*__f)(__a0, __a1, __a2); 987a984708SDavid Chisnall} 997a984708SDavid Chisnall 100*9729cf09SDimitry Andrictemplate <class _Fn, class _T1> 1017a984708SDavid Chisnallinline _LIBCPP_INLINE_VISIBILITY 102*9729cf09SDimitry Andrictypename __enable_invoke<_Fn, _T1>::_Bullet2 103*9729cf09SDimitry Andric__invoke(_Fn __f, _T1& __t1) { 1047a984708SDavid Chisnall return ((*__t1).*__f)(); 1057a984708SDavid Chisnall} 1067a984708SDavid Chisnall 107*9729cf09SDimitry Andrictemplate <class _Fn, class _T1, class _A0> 1087a984708SDavid Chisnallinline _LIBCPP_INLINE_VISIBILITY 109*9729cf09SDimitry Andrictypename __enable_invoke<_Fn, _T1>::_Bullet2 110*9729cf09SDimitry Andric__invoke(_Fn __f, _T1& __t1, _A0& __a0) { 1117a984708SDavid Chisnall return ((*__t1).*__f)(__a0); 1127a984708SDavid Chisnall} 1137a984708SDavid Chisnall 114*9729cf09SDimitry Andrictemplate <class _Fn, class _T1, class _A0, class _A1> 1157a984708SDavid Chisnallinline _LIBCPP_INLINE_VISIBILITY 116*9729cf09SDimitry Andrictypename __enable_invoke<_Fn, _T1>::_Bullet2 117*9729cf09SDimitry Andric__invoke(_Fn __f, _T1& __t1, _A0& __a0, _A1& __a1) { 1187a984708SDavid Chisnall return ((*__t1).*__f)(__a0, __a1); 1197a984708SDavid Chisnall} 1207a984708SDavid Chisnall 121*9729cf09SDimitry Andrictemplate <class _Fn, class _T1, class _A0, class _A1, class _A2> 1227a984708SDavid Chisnallinline _LIBCPP_INLINE_VISIBILITY 123*9729cf09SDimitry Andrictypename __enable_invoke<_Fn, _T1>::_Bullet2 124*9729cf09SDimitry Andric__invoke(_Fn __f, _T1& __t1, _A0& __a0, _A1& __a1, _A2& __a2) { 1257a984708SDavid Chisnall return ((*__t1).*__f)(__a0, __a1, __a2); 1267a984708SDavid Chisnall} 1277a984708SDavid Chisnall 128*9729cf09SDimitry Andrictemplate <class _Fn, class _T1> 1297a984708SDavid Chisnallinline _LIBCPP_INLINE_VISIBILITY 130*9729cf09SDimitry Andrictypename __enable_invoke<_Fn, _T1>::_Bullet3 131*9729cf09SDimitry Andric__invoke(_Fn __f, _T1& __t1) { 1327a984708SDavid Chisnall return __t1.*__f; 1337a984708SDavid Chisnall} 1347a984708SDavid Chisnall 135*9729cf09SDimitry Andrictemplate <class _Fn, class _T1> 1367a984708SDavid Chisnallinline _LIBCPP_INLINE_VISIBILITY 137*9729cf09SDimitry Andrictypename __enable_invoke<_Fn, _T1>::_Bullet4 138*9729cf09SDimitry Andric__invoke(_Fn __f, _T1& __t1) { 1397a984708SDavid Chisnall return (*__t1).*__f; 1407a984708SDavid Chisnall} 1417a984708SDavid Chisnall 1427a984708SDavid Chisnall// fifth bullet 1437a984708SDavid Chisnall 14494e3ee44SDavid Chisnalltemplate <class _Fp> 1457a984708SDavid Chisnallinline _LIBCPP_INLINE_VISIBILITY 146*9729cf09SDimitry Andricdecltype(_VSTD::declval<_Fp&>()()) 147*9729cf09SDimitry Andric__invoke(_Fp& __f) 1487a984708SDavid Chisnall{ 1497a984708SDavid Chisnall return __f(); 1507a984708SDavid Chisnall} 1517a984708SDavid Chisnall 15294e3ee44SDavid Chisnalltemplate <class _Fp, class _A0> 1537a984708SDavid Chisnallinline _LIBCPP_INLINE_VISIBILITY 154*9729cf09SDimitry Andricdecltype(_VSTD::declval<_Fp&>()(_VSTD::declval<_A0&>())) 155*9729cf09SDimitry Andric__invoke(_Fp& __f, _A0& __a0) 1567a984708SDavid Chisnall{ 1577a984708SDavid Chisnall return __f(__a0); 1587a984708SDavid Chisnall} 1597a984708SDavid Chisnall 16094e3ee44SDavid Chisnalltemplate <class _Fp, class _A0, class _A1> 1617a984708SDavid Chisnallinline _LIBCPP_INLINE_VISIBILITY 162*9729cf09SDimitry Andricdecltype(_VSTD::declval<_Fp&>()(_VSTD::declval<_A0&>(), _VSTD::declval<_A1&>())) 163*9729cf09SDimitry Andric__invoke(_Fp& __f, _A0& __a0, _A1& __a1) 1647a984708SDavid Chisnall{ 1657a984708SDavid Chisnall return __f(__a0, __a1); 1667a984708SDavid Chisnall} 1677a984708SDavid Chisnall 16894e3ee44SDavid Chisnalltemplate <class _Fp, class _A0, class _A1, class _A2> 1697a984708SDavid Chisnallinline _LIBCPP_INLINE_VISIBILITY 170*9729cf09SDimitry Andricdecltype(_VSTD::declval<_Fp&>()(_VSTD::declval<_A0&>(), _VSTD::declval<_A1&>(), _VSTD::declval<_A2&>())) 171*9729cf09SDimitry Andric__invoke(_Fp& __f, _A0& __a0, _A1& __a1, _A2& __a2) 1727a984708SDavid Chisnall{ 1737a984708SDavid Chisnall return __f(__a0, __a1, __a2); 1747a984708SDavid Chisnall} 1757a984708SDavid Chisnall 17694e3ee44SDavid Chisnalltemplate <class _Fp, bool = __has_result_type<__weak_result_type<_Fp> >::value> 1777a984708SDavid Chisnallstruct __invoke_return 1787a984708SDavid Chisnall{ 17994e3ee44SDavid Chisnall typedef typename __weak_result_type<_Fp>::result_type type; 1807a984708SDavid Chisnall}; 1817a984708SDavid Chisnall 18294e3ee44SDavid Chisnalltemplate <class _Fp> 18394e3ee44SDavid Chisnallstruct __invoke_return<_Fp, false> 1847a984708SDavid Chisnall{ 185*9729cf09SDimitry Andric typedef decltype(__invoke(_VSTD::declval<_Fp&>())) type; 1867a984708SDavid Chisnall}; 1877a984708SDavid Chisnall 1887a984708SDavid Chisnalltemplate <class _Tp, class _A0> 1897a984708SDavid Chisnallstruct __invoke_return0 1907a984708SDavid Chisnall{ 191*9729cf09SDimitry Andric typedef decltype(__invoke(_VSTD::declval<_Tp&>(), _VSTD::declval<_A0&>())) type; 1927a984708SDavid Chisnall}; 1937a984708SDavid Chisnall 19494e3ee44SDavid Chisnalltemplate <class _Rp, class _Tp, class _A0> 19594e3ee44SDavid Chisnallstruct __invoke_return0<_Rp _Tp::*, _A0> 1967a984708SDavid Chisnall{ 197*9729cf09SDimitry Andric typedef typename __enable_invoke<_Rp _Tp::*, _A0>::type type; 1987a984708SDavid Chisnall}; 1997a984708SDavid Chisnall 2007a984708SDavid Chisnalltemplate <class _Tp, class _A0, class _A1> 2017a984708SDavid Chisnallstruct __invoke_return1 2027a984708SDavid Chisnall{ 203*9729cf09SDimitry Andric typedef decltype(__invoke(_VSTD::declval<_Tp&>(), _VSTD::declval<_A0&>(), 204*9729cf09SDimitry Andric _VSTD::declval<_A1&>())) type; 205*9729cf09SDimitry Andric}; 206*9729cf09SDimitry Andric 207*9729cf09SDimitry Andrictemplate <class _Rp, class _Class, class _A0, class _A1> 208*9729cf09SDimitry Andricstruct __invoke_return1<_Rp _Class::*, _A0, _A1> { 209*9729cf09SDimitry Andric typedef typename __enable_invoke<_Rp _Class::*, _A0>::type type; 2107a984708SDavid Chisnall}; 2117a984708SDavid Chisnall 2127a984708SDavid Chisnalltemplate <class _Tp, class _A0, class _A1, class _A2> 2137a984708SDavid Chisnallstruct __invoke_return2 2147a984708SDavid Chisnall{ 215*9729cf09SDimitry Andric typedef decltype(__invoke(_VSTD::declval<_Tp&>(), _VSTD::declval<_A0&>(), 216*9729cf09SDimitry Andric _VSTD::declval<_A1&>(), 217*9729cf09SDimitry Andric _VSTD::declval<_A2&>())) type; 2187a984708SDavid Chisnall}; 2197a984708SDavid Chisnall 220*9729cf09SDimitry Andrictemplate <class _Ret, class _Class, class _A0, class _A1, class _A2> 221*9729cf09SDimitry Andricstruct __invoke_return2<_Ret _Class::*, _A0, _A1, _A2> { 222*9729cf09SDimitry Andric typedef typename __enable_invoke<_Ret _Class::*, _A0>::type type; 223854fa44bSDimitry Andric}; 2247a984708SDavid Chisnall#endif // _LIBCPP_FUNCTIONAL_BASE_03 225