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