__functional_base_03 revision 302408
113978Smrkam// -*- C++ -*- 213978Smrkam//===----------------------------------------------------------------------===// 313978Smrkam// 413978Smrkam// The LLVM Compiler Infrastructure 513978Smrkam// 613978Smrkam// This file is dual licensed under the MIT and the University of Illinois Open 713978Smrkam// Source Licenses. See LICENSE.TXT for details. 813978Smrkam// 913978Smrkam//===----------------------------------------------------------------------===// 1013978Smrkam 1113978Smrkam#ifndef _LIBCPP_FUNCTIONAL_BASE_03 1213978Smrkam#define _LIBCPP_FUNCTIONAL_BASE_03 1313978Smrkam 1413978Smrkam// manual variadic expansion for <functional> 1513978Smrkam 1613978Smrkam// __invoke 1713978Smrkam 1813978Smrkamtemplate <class _Ret, class _T1, bool _IsFunc, bool _IsBase> 1913978Smrkamstruct __enable_invoke_imp; 2013978Smrkam 2113978Smrkamtemplate <class _Ret, class _T1> 2213978Smrkamstruct __enable_invoke_imp<_Ret, _T1, true, true> { 2313978Smrkam typedef _Ret _Bullet1; 2414305Smrkam typedef _Bullet1 type; 2513978Smrkam}; 2613978Smrkam 2713978Smrkamtemplate <class _Ret, class _T1> 2813978Smrkamstruct __enable_invoke_imp<_Ret, _T1, true, false> { 2913978Smrkam typedef _Ret _Bullet2; 3013978Smrkam typedef _Bullet2 type; 3113978Smrkam}; 3213978Smrkam 3313978Smrkamtemplate <class _Ret, class _T1> 3414305Smrkamstruct __enable_invoke_imp<_Ret, _T1, false, true> { 3513978Smrkam typedef typename add_lvalue_reference< 3613978Smrkam typename __apply_cv<_T1, _Ret>::type 3713978Smrkam >::type _Bullet3; 3813978Smrkam typedef _Bullet3 type; 3913978Smrkam}; 4013978Smrkam 4113978Smrkamtemplate <class _Ret, class _T1> 4213978Smrkamstruct __enable_invoke_imp<_Ret, _T1, false, false> { 4314305Smrkam typedef typename add_lvalue_reference< 4413978Smrkam typename __apply_cv<decltype(*_VSTD::declval<_T1>()), _Ret>::type 4514801Sprr >::type _Bullet4; 4614801Sprr typedef _Bullet4 type; 4713978Smrkam}; 4813978Smrkam 4913978Smrkamtemplate <class _Ret, class _T1> 5013978Smrkamstruct __enable_invoke_imp<_Ret, _T1*, false, false> { 5114305Smrkam typedef typename add_lvalue_reference< 5213978Smrkam typename __apply_cv<_T1, _Ret>::type 5313978Smrkam >::type _Bullet4; 5413978Smrkam typedef _Bullet4 type; 5513978Smrkam}; 5613978Smrkam 5713978Smrkamtemplate <class _Fn, class _T1, 5813978Smrkam class _Traits = __member_pointer_traits<_Fn>, 5914305Smrkam class _Ret = typename _Traits::_ReturnType, 6013978Smrkam class _Class = typename _Traits::_ClassType> 6114305Smrkamstruct __enable_invoke : __enable_invoke_imp< 6213978Smrkam _Ret, _T1, 6314305Smrkam is_member_function_pointer<_Fn>::value, 6414305Smrkam is_base_of<_Class, typename remove_reference<_T1>::type>::value> 6514305Smrkam{ 6614305Smrkam}; 6713978Smrkam 6813978Smrkam__nat __invoke(__any, ...); 6913978Smrkam 7013978Smrkam// first bullet 7113978Smrkam 7213978Smrkamtemplate <class _Fn, class _T1> 7313978Smrkaminline _LIBCPP_INLINE_VISIBILITY 7413978Smrkamtypename __enable_invoke<_Fn, _T1>::_Bullet1 7513978Smrkam__invoke(_Fn __f, _T1& __t1) { 7613978Smrkam return (__t1.*__f)(); 7713978Smrkam} 7813978Smrkam 7913978Smrkamtemplate <class _Fn, class _T1, class _A0> 8013978Smrkaminline _LIBCPP_INLINE_VISIBILITY 8113978Smrkamtypename __enable_invoke<_Fn, _T1>::_Bullet1 8213978Smrkam__invoke(_Fn __f, _T1& __t1, _A0& __a0) { 8313978Smrkam return (__t1.*__f)(__a0); 8413978Smrkam} 8513978Smrkam 8613978Smrkamtemplate <class _Fn, class _T1, class _A0, class _A1> 8713978Smrkaminline _LIBCPP_INLINE_VISIBILITY 8813978Smrkamtypename __enable_invoke<_Fn, _T1>::_Bullet1 8913978Smrkam__invoke(_Fn __f, _T1& __t1, _A0& __a0, _A1& __a1) { 9013978Smrkam return (__t1.*__f)(__a0, __a1); 9113978Smrkam} 9213978Smrkam 9313978Smrkamtemplate <class _Fn, class _T1, class _A0, class _A1, class _A2> 9413978Smrkaminline _LIBCPP_INLINE_VISIBILITY 9513978Smrkamtypename __enable_invoke<_Fn, _T1>::_Bullet1 9613978Smrkam__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