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