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 18 template <class _Ret, class _T1, bool _IsFunc, bool _IsBase> 19 struct __enable_invoke_imp; 20 21 template <class _Ret, class _T1> 22 struct __enable_invoke_imp<_Ret, _T1, true, true> { 23 typedef _Ret _Bullet1; 24 typedef _Bullet1 type; 25 }; 26 27 template <class _Ret, class _T1> 28 struct __enable_invoke_imp<_Ret, _T1, true, false> { 29 typedef _Ret _Bullet2; 30 typedef _Bullet2 type; 31 }; 32 33 template <class _Ret, class _T1> 34 struct __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 41 template <class _Ret, class _T1> 42 struct __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 49 template <class _Ret, class _T1> 50 struct __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 57 template <class _Fn, class _T1, 58 class _Traits = __member_pointer_traits<_Fn>, 59 class _Ret = typename _Traits::_ReturnType, 60 class _Class = typename _Traits::_ClassType> 61 struct __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 72 template <class _Fn, class _T1> 73 inline _LIBCPP_INLINE_VISIBILITY 74 typename __enable_invoke<_Fn, _T1>::_Bullet1 75 __invoke(_Fn __f, _T1& __t1) { 76 return (__t1.*__f)(); 77 } 78 79 template <class _Fn, class _T1, class _A0> 80 inline _LIBCPP_INLINE_VISIBILITY 81 typename __enable_invoke<_Fn, _T1>::_Bullet1 82 __invoke(_Fn __f, _T1& __t1, _A0& __a0) { 83 return (__t1.*__f)(__a0); 84 } 85 86 template <class _Fn, class _T1, class _A0, class _A1> 87 inline _LIBCPP_INLINE_VISIBILITY 88 typename __enable_invoke<_Fn, _T1>::_Bullet1 89 __invoke(_Fn __f, _T1& __t1, _A0& __a0, _A1& __a1) { 90 return (__t1.*__f)(__a0, __a1); 91 } 92 93 template <class _Fn, class _T1, class _A0, class _A1, class _A2> 94 inline _LIBCPP_INLINE_VISIBILITY 95 typename __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 100 template <class _Fn, class _T1> 101 inline _LIBCPP_INLINE_VISIBILITY 102 typename __enable_invoke<_Fn, _T1>::_Bullet2 103 __invoke(_Fn __f, _T1& __t1) { 104 return ((*__t1).*__f)(); 105 } 106 107 template <class _Fn, class _T1, class _A0> 108 inline _LIBCPP_INLINE_VISIBILITY 109 typename __enable_invoke<_Fn, _T1>::_Bullet2 110 __invoke(_Fn __f, _T1& __t1, _A0& __a0) { 111 return ((*__t1).*__f)(__a0); 112 } 113 114 template <class _Fn, class _T1, class _A0, class _A1> 115 inline _LIBCPP_INLINE_VISIBILITY 116 typename __enable_invoke<_Fn, _T1>::_Bullet2 117 __invoke(_Fn __f, _T1& __t1, _A0& __a0, _A1& __a1) { 118 return ((*__t1).*__f)(__a0, __a1); 119 } 120 121 template <class _Fn, class _T1, class _A0, class _A1, class _A2> 122 inline _LIBCPP_INLINE_VISIBILITY 123 typename __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 128 template <class _Fn, class _T1> 129 inline _LIBCPP_INLINE_VISIBILITY 130 typename __enable_invoke<_Fn, _T1>::_Bullet3 131 __invoke(_Fn __f, _T1& __t1) { 132 return __t1.*__f; 133 } 134 135 template <class _Fn, class _T1> 136 inline _LIBCPP_INLINE_VISIBILITY 137 typename __enable_invoke<_Fn, _T1>::_Bullet4 138 __invoke(_Fn __f, _T1& __t1) { 139 return (*__t1).*__f; 140 } 141 142 // fifth bullet 143 144 template <class _Fp> 145 inline _LIBCPP_INLINE_VISIBILITY 146 decltype(_VSTD::declval<_Fp&>()()) 147 __invoke(_Fp& __f) 148 { 149 return __f(); 150 } 151 152 template <class _Fp, class _A0> 153 inline _LIBCPP_INLINE_VISIBILITY 154 decltype(_VSTD::declval<_Fp&>()(_VSTD::declval<_A0&>())) 155 __invoke(_Fp& __f, _A0& __a0) 156 { 157 return __f(__a0); 158 } 159 160 template <class _Fp, class _A0, class _A1> 161 inline _LIBCPP_INLINE_VISIBILITY 162 decltype(_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 168 template <class _Fp, class _A0, class _A1, class _A2> 169 inline _LIBCPP_INLINE_VISIBILITY 170 decltype(_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 176 template <class _Fp, bool = __has_result_type<__weak_result_type<_Fp> >::value> 177 struct __invoke_return 178 { 179 typedef typename __weak_result_type<_Fp>::result_type type; 180 }; 181 182 template <class _Fp> 183 struct __invoke_return<_Fp, false> 184 { 185 typedef decltype(__invoke(_VSTD::declval<_Fp&>())) type; 186 }; 187 188 template <class _Tp, class _A0> 189 struct __invoke_return0 190 { 191 typedef decltype(__invoke(_VSTD::declval<_Tp&>(), _VSTD::declval<_A0&>())) type; 192 }; 193 194 template <class _Rp, class _Tp, class _A0> 195 struct __invoke_return0<_Rp _Tp::*, _A0> 196 { 197 typedef typename __enable_invoke<_Rp _Tp::*, _A0>::type type; 198 }; 199 200 template <class _Tp, class _A0, class _A1> 201 struct __invoke_return1 202 { 203 typedef decltype(__invoke(_VSTD::declval<_Tp&>(), _VSTD::declval<_A0&>(), 204 _VSTD::declval<_A1&>())) type; 205 }; 206 207 template <class _Rp, class _Class, class _A0, class _A1> 208 struct __invoke_return1<_Rp _Class::*, _A0, _A1> { 209 typedef typename __enable_invoke<_Rp _Class::*, _A0>::type type; 210 }; 211 212 template <class _Tp, class _A0, class _A1, class _A2> 213 struct __invoke_return2 214 { 215 typedef decltype(__invoke(_VSTD::declval<_Tp&>(), _VSTD::declval<_A0&>(), 216 _VSTD::declval<_A1&>(), 217 _VSTD::declval<_A2&>())) type; 218 }; 219 220 template <class _Ret, class _Class, class _A0, class _A1, class _A2> 221 struct __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