1227825Stheraven// -*- C++ -*- 2227825Stheraven//===----------------------------------------------------------------------===// 3227825Stheraven// 4227825Stheraven// The LLVM Compiler Infrastructure 5227825Stheraven// 6227825Stheraven// This file is dual licensed under the MIT and the University of Illinois Open 7227825Stheraven// Source Licenses. See LICENSE.TXT for details. 8227825Stheraven// 9227825Stheraven//===----------------------------------------------------------------------===// 10227825Stheraven 11227825Stheraven#ifndef _LIBCPP_FUNCTIONAL_BASE_03 12227825Stheraven#define _LIBCPP_FUNCTIONAL_BASE_03 13227825Stheraven 14227825Stheraven// manual variadic expansion for <functional> 15227825Stheraven 16300770Sdim// __invoke 17227825Stheraven 18300770Sdimtemplate <class _Ret, class _T1, bool _IsFunc, bool _IsBase> 19300770Sdimstruct __enable_invoke_imp; 20227825Stheraven 21300770Sdimtemplate <class _Ret, class _T1> 22300770Sdimstruct __enable_invoke_imp<_Ret, _T1, true, true> { 23300770Sdim typedef _Ret _Bullet1; 24300770Sdim typedef _Bullet1 type; 25227825Stheraven}; 26227825Stheraven 27300770Sdimtemplate <class _Ret, class _T1> 28300770Sdimstruct __enable_invoke_imp<_Ret, _T1, true, false> { 29300770Sdim typedef _Ret _Bullet2; 30300770Sdim typedef _Bullet2 type; 31227825Stheraven}; 32227825Stheraven 33300770Sdimtemplate <class _Ret, class _T1> 34300770Sdimstruct __enable_invoke_imp<_Ret, _T1, false, true> { 35300770Sdim typedef typename add_lvalue_reference< 36300770Sdim typename __apply_cv<_T1, _Ret>::type 37300770Sdim >::type _Bullet3; 38300770Sdim typedef _Bullet3 type; 39227825Stheraven}; 40227825Stheraven 41300770Sdimtemplate <class _Ret, class _T1> 42300770Sdimstruct __enable_invoke_imp<_Ret, _T1, false, false> { 43300770Sdim typedef typename add_lvalue_reference< 44300770Sdim typename __apply_cv<decltype(*_VSTD::declval<_T1>()), _Ret>::type 45300770Sdim >::type _Bullet4; 46300770Sdim typedef _Bullet4 type; 47227825Stheraven}; 48227825Stheraven 49300770Sdimtemplate <class _Ret, class _T1> 50300770Sdimstruct __enable_invoke_imp<_Ret, _T1*, false, false> { 51300770Sdim typedef typename add_lvalue_reference< 52300770Sdim typename __apply_cv<_T1, _Ret>::type 53300770Sdim >::type _Bullet4; 54300770Sdim typedef _Bullet4 type; 55227825Stheraven}; 56227825Stheraven 57300770Sdimtemplate <class _Fn, class _T1, 58300770Sdim class _Traits = __member_pointer_traits<_Fn>, 59300770Sdim class _Ret = typename _Traits::_ReturnType, 60300770Sdim class _Class = typename _Traits::_ClassType> 61300770Sdimstruct __enable_invoke : __enable_invoke_imp< 62300770Sdim _Ret, _T1, 63300770Sdim is_member_function_pointer<_Fn>::value, 64300770Sdim is_base_of<_Class, typename remove_reference<_T1>::type>::value> 65227825Stheraven{ 66227825Stheraven}; 67227825Stheraven 68300770Sdim__nat __invoke(__any, ...); 69227825Stheraven 70227825Stheraven// first bullet 71227825Stheraven 72300770Sdimtemplate <class _Fn, class _T1> 73227825Stheraveninline _LIBCPP_INLINE_VISIBILITY 74300770Sdimtypename __enable_invoke<_Fn, _T1>::_Bullet1 75300770Sdim__invoke(_Fn __f, _T1& __t1) { 76227825Stheraven return (__t1.*__f)(); 77227825Stheraven} 78227825Stheraven 79300770Sdimtemplate <class _Fn, class _T1, class _A0> 80227825Stheraveninline _LIBCPP_INLINE_VISIBILITY 81300770Sdimtypename __enable_invoke<_Fn, _T1>::_Bullet1 82300770Sdim__invoke(_Fn __f, _T1& __t1, _A0& __a0) { 83227825Stheraven return (__t1.*__f)(__a0); 84227825Stheraven} 85227825Stheraven 86300770Sdimtemplate <class _Fn, class _T1, class _A0, class _A1> 87227825Stheraveninline _LIBCPP_INLINE_VISIBILITY 88300770Sdimtypename __enable_invoke<_Fn, _T1>::_Bullet1 89300770Sdim__invoke(_Fn __f, _T1& __t1, _A0& __a0, _A1& __a1) { 90227825Stheraven return (__t1.*__f)(__a0, __a1); 91227825Stheraven} 92227825Stheraven 93300770Sdimtemplate <class _Fn, class _T1, class _A0, class _A1, class _A2> 94227825Stheraveninline _LIBCPP_INLINE_VISIBILITY 95300770Sdimtypename __enable_invoke<_Fn, _T1>::_Bullet1 96300770Sdim__invoke(_Fn __f, _T1& __t1, _A0& __a0, _A1& __a1, _A2& __a2) { 97227825Stheraven return (__t1.*__f)(__a0, __a1, __a2); 98227825Stheraven} 99227825Stheraven 100300770Sdimtemplate <class _Fn, class _T1> 101227825Stheraveninline _LIBCPP_INLINE_VISIBILITY 102300770Sdimtypename __enable_invoke<_Fn, _T1>::_Bullet2 103300770Sdim__invoke(_Fn __f, _T1& __t1) { 104227825Stheraven return ((*__t1).*__f)(); 105227825Stheraven} 106227825Stheraven 107300770Sdimtemplate <class _Fn, class _T1, class _A0> 108227825Stheraveninline _LIBCPP_INLINE_VISIBILITY 109300770Sdimtypename __enable_invoke<_Fn, _T1>::_Bullet2 110300770Sdim__invoke(_Fn __f, _T1& __t1, _A0& __a0) { 111227825Stheraven return ((*__t1).*__f)(__a0); 112227825Stheraven} 113227825Stheraven 114300770Sdimtemplate <class _Fn, class _T1, class _A0, class _A1> 115227825Stheraveninline _LIBCPP_INLINE_VISIBILITY 116300770Sdimtypename __enable_invoke<_Fn, _T1>::_Bullet2 117300770Sdim__invoke(_Fn __f, _T1& __t1, _A0& __a0, _A1& __a1) { 118227825Stheraven return ((*__t1).*__f)(__a0, __a1); 119227825Stheraven} 120227825Stheraven 121300770Sdimtemplate <class _Fn, class _T1, class _A0, class _A1, class _A2> 122227825Stheraveninline _LIBCPP_INLINE_VISIBILITY 123300770Sdimtypename __enable_invoke<_Fn, _T1>::_Bullet2 124300770Sdim__invoke(_Fn __f, _T1& __t1, _A0& __a0, _A1& __a1, _A2& __a2) { 125227825Stheraven return ((*__t1).*__f)(__a0, __a1, __a2); 126227825Stheraven} 127227825Stheraven 128300770Sdimtemplate <class _Fn, class _T1> 129227825Stheraveninline _LIBCPP_INLINE_VISIBILITY 130300770Sdimtypename __enable_invoke<_Fn, _T1>::_Bullet3 131300770Sdim__invoke(_Fn __f, _T1& __t1) { 132227825Stheraven return __t1.*__f; 133227825Stheraven} 134227825Stheraven 135300770Sdimtemplate <class _Fn, class _T1> 136227825Stheraveninline _LIBCPP_INLINE_VISIBILITY 137300770Sdimtypename __enable_invoke<_Fn, _T1>::_Bullet4 138300770Sdim__invoke(_Fn __f, _T1& __t1) { 139227825Stheraven return (*__t1).*__f; 140227825Stheraven} 141227825Stheraven 142227825Stheraven// fifth bullet 143227825Stheraven 144232924Stheraventemplate <class _Fp> 145227825Stheraveninline _LIBCPP_INLINE_VISIBILITY 146300770Sdimdecltype(_VSTD::declval<_Fp&>()()) 147300770Sdim__invoke(_Fp& __f) 148227825Stheraven{ 149227825Stheraven return __f(); 150227825Stheraven} 151227825Stheraven 152232924Stheraventemplate <class _Fp, class _A0> 153227825Stheraveninline _LIBCPP_INLINE_VISIBILITY 154300770Sdimdecltype(_VSTD::declval<_Fp&>()(_VSTD::declval<_A0&>())) 155300770Sdim__invoke(_Fp& __f, _A0& __a0) 156227825Stheraven{ 157227825Stheraven return __f(__a0); 158227825Stheraven} 159227825Stheraven 160232924Stheraventemplate <class _Fp, class _A0, class _A1> 161227825Stheraveninline _LIBCPP_INLINE_VISIBILITY 162300770Sdimdecltype(_VSTD::declval<_Fp&>()(_VSTD::declval<_A0&>(), _VSTD::declval<_A1&>())) 163300770Sdim__invoke(_Fp& __f, _A0& __a0, _A1& __a1) 164227825Stheraven{ 165227825Stheraven return __f(__a0, __a1); 166227825Stheraven} 167227825Stheraven 168232924Stheraventemplate <class _Fp, class _A0, class _A1, class _A2> 169227825Stheraveninline _LIBCPP_INLINE_VISIBILITY 170300770Sdimdecltype(_VSTD::declval<_Fp&>()(_VSTD::declval<_A0&>(), _VSTD::declval<_A1&>(), _VSTD::declval<_A2&>())) 171300770Sdim__invoke(_Fp& __f, _A0& __a0, _A1& __a1, _A2& __a2) 172227825Stheraven{ 173227825Stheraven return __f(__a0, __a1, __a2); 174227825Stheraven} 175227825Stheraven 176232924Stheraventemplate <class _Fp, bool = __has_result_type<__weak_result_type<_Fp> >::value> 177227825Stheravenstruct __invoke_return 178227825Stheraven{ 179232924Stheraven typedef typename __weak_result_type<_Fp>::result_type type; 180227825Stheraven}; 181227825Stheraven 182232924Stheraventemplate <class _Fp> 183232924Stheravenstruct __invoke_return<_Fp, false> 184227825Stheraven{ 185300770Sdim typedef decltype(__invoke(_VSTD::declval<_Fp&>())) type; 186227825Stheraven}; 187227825Stheraven 188227825Stheraventemplate <class _Tp, class _A0> 189227825Stheravenstruct __invoke_return0 190227825Stheraven{ 191300770Sdim typedef decltype(__invoke(_VSTD::declval<_Tp&>(), _VSTD::declval<_A0&>())) type; 192227825Stheraven}; 193227825Stheraven 194232924Stheraventemplate <class _Rp, class _Tp, class _A0> 195232924Stheravenstruct __invoke_return0<_Rp _Tp::*, _A0> 196227825Stheraven{ 197300770Sdim typedef typename __enable_invoke<_Rp _Tp::*, _A0>::type type; 198227825Stheraven}; 199227825Stheraven 200227825Stheraventemplate <class _Tp, class _A0, class _A1> 201227825Stheravenstruct __invoke_return1 202227825Stheraven{ 203300770Sdim typedef decltype(__invoke(_VSTD::declval<_Tp&>(), _VSTD::declval<_A0&>(), 204300770Sdim _VSTD::declval<_A1&>())) type; 205227825Stheraven}; 206227825Stheraven 207300770Sdimtemplate <class _Rp, class _Class, class _A0, class _A1> 208300770Sdimstruct __invoke_return1<_Rp _Class::*, _A0, _A1> { 209300770Sdim typedef typename __enable_invoke<_Rp _Class::*, _A0>::type type; 210300770Sdim}; 211300770Sdim 212227825Stheraventemplate <class _Tp, class _A0, class _A1, class _A2> 213227825Stheravenstruct __invoke_return2 214227825Stheraven{ 215300770Sdim typedef decltype(__invoke(_VSTD::declval<_Tp&>(), _VSTD::declval<_A0&>(), 216300770Sdim _VSTD::declval<_A1&>(), 217300770Sdim _VSTD::declval<_A2&>())) type; 218227825Stheraven}; 219227825Stheraven 220300770Sdimtemplate <class _Ret, class _Class, class _A0, class _A1, class _A2> 221300770Sdimstruct __invoke_return2<_Ret _Class::*, _A0, _A1, _A2> { 222300770Sdim typedef typename __enable_invoke<_Ret _Class::*, _A0>::type type; 223288943Sdim}; 224227825Stheraven#endif // _LIBCPP_FUNCTIONAL_BASE_03 225