1fe6060f1SDimitry Andric // -*- C++ -*- 2fe6060f1SDimitry Andric //===----------------------------------------------------------------------===// 3fe6060f1SDimitry Andric // 4fe6060f1SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 5fe6060f1SDimitry Andric // See https://llvm.org/LICENSE.txt for license information. 6fe6060f1SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 7fe6060f1SDimitry Andric // 8fe6060f1SDimitry Andric //===----------------------------------------------------------------------===// 9fe6060f1SDimitry Andric 10fe6060f1SDimitry Andric #ifndef _LIBCPP___FUNCTIONAL_INVOKE_H 11fe6060f1SDimitry Andric #define _LIBCPP___FUNCTIONAL_INVOKE_H 12fe6060f1SDimitry Andric 13fe6060f1SDimitry Andric #include <__config> 14*81ad6265SDimitry Andric #include <__type_traits/add_lvalue_reference.h> 15*81ad6265SDimitry Andric #include <__type_traits/apply_cv.h> 16*81ad6265SDimitry Andric #include <__type_traits/conditional.h> 17*81ad6265SDimitry Andric #include <__type_traits/decay.h> 18*81ad6265SDimitry Andric #include <__type_traits/enable_if.h> 19*81ad6265SDimitry Andric #include <__type_traits/integral_constant.h> 20*81ad6265SDimitry Andric #include <__type_traits/is_base_of.h> 21*81ad6265SDimitry Andric #include <__type_traits/is_core_convertible.h> 22*81ad6265SDimitry Andric #include <__type_traits/is_member_function_pointer.h> 23*81ad6265SDimitry Andric #include <__type_traits/is_member_object_pointer.h> 24*81ad6265SDimitry Andric #include <__type_traits/is_reference_wrapper.h> 25*81ad6265SDimitry Andric #include <__type_traits/is_same.h> 26*81ad6265SDimitry Andric #include <__type_traits/is_void.h> 27*81ad6265SDimitry Andric #include <__type_traits/remove_cv.h> 28*81ad6265SDimitry Andric #include <__utility/declval.h> 29fe6060f1SDimitry Andric #include <__utility/forward.h> 30fe6060f1SDimitry Andric 31fe6060f1SDimitry Andric #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) 32fe6060f1SDimitry Andric # pragma GCC system_header 33fe6060f1SDimitry Andric #endif 34fe6060f1SDimitry Andric 35*81ad6265SDimitry Andric // TODO: Disentangle the type traits and std::invoke properly 36*81ad6265SDimitry Andric 37fe6060f1SDimitry Andric _LIBCPP_BEGIN_NAMESPACE_STD 38fe6060f1SDimitry Andric 39*81ad6265SDimitry Andric struct __any 40*81ad6265SDimitry Andric { 41*81ad6265SDimitry Andric __any(...); 42*81ad6265SDimitry Andric }; 43*81ad6265SDimitry Andric 44*81ad6265SDimitry Andric struct __nat 45*81ad6265SDimitry Andric { 46*81ad6265SDimitry Andric #ifndef _LIBCPP_CXX03_LANG 47*81ad6265SDimitry Andric __nat() = delete; 48*81ad6265SDimitry Andric __nat(const __nat&) = delete; 49*81ad6265SDimitry Andric __nat& operator=(const __nat&) = delete; 50*81ad6265SDimitry Andric ~__nat() = delete; 51*81ad6265SDimitry Andric #endif 52*81ad6265SDimitry Andric }; 53*81ad6265SDimitry Andric 54*81ad6265SDimitry Andric template <class _MP, bool _IsMemberFunctionPtr, bool _IsMemberObjectPtr> 55*81ad6265SDimitry Andric struct __member_pointer_traits_imp 56*81ad6265SDimitry Andric { 57*81ad6265SDimitry Andric }; 58*81ad6265SDimitry Andric 59*81ad6265SDimitry Andric template <class _Rp, class _Class, class ..._Param> 60*81ad6265SDimitry Andric struct __member_pointer_traits_imp<_Rp (_Class::*)(_Param...), true, false> 61*81ad6265SDimitry Andric { 62*81ad6265SDimitry Andric typedef _Class _ClassType; 63*81ad6265SDimitry Andric typedef _Rp _ReturnType; 64*81ad6265SDimitry Andric typedef _Rp (_FnType) (_Param...); 65*81ad6265SDimitry Andric }; 66*81ad6265SDimitry Andric 67*81ad6265SDimitry Andric template <class _Rp, class _Class, class ..._Param> 68*81ad6265SDimitry Andric struct __member_pointer_traits_imp<_Rp (_Class::*)(_Param..., ...), true, false> 69*81ad6265SDimitry Andric { 70*81ad6265SDimitry Andric typedef _Class _ClassType; 71*81ad6265SDimitry Andric typedef _Rp _ReturnType; 72*81ad6265SDimitry Andric typedef _Rp (_FnType) (_Param..., ...); 73*81ad6265SDimitry Andric }; 74*81ad6265SDimitry Andric 75*81ad6265SDimitry Andric template <class _Rp, class _Class, class ..._Param> 76*81ad6265SDimitry Andric struct __member_pointer_traits_imp<_Rp (_Class::*)(_Param...) const, true, false> 77*81ad6265SDimitry Andric { 78*81ad6265SDimitry Andric typedef _Class const _ClassType; 79*81ad6265SDimitry Andric typedef _Rp _ReturnType; 80*81ad6265SDimitry Andric typedef _Rp (_FnType) (_Param...); 81*81ad6265SDimitry Andric }; 82*81ad6265SDimitry Andric 83*81ad6265SDimitry Andric template <class _Rp, class _Class, class ..._Param> 84*81ad6265SDimitry Andric struct __member_pointer_traits_imp<_Rp (_Class::*)(_Param..., ...) const, true, false> 85*81ad6265SDimitry Andric { 86*81ad6265SDimitry Andric typedef _Class const _ClassType; 87*81ad6265SDimitry Andric typedef _Rp _ReturnType; 88*81ad6265SDimitry Andric typedef _Rp (_FnType) (_Param..., ...); 89*81ad6265SDimitry Andric }; 90*81ad6265SDimitry Andric 91*81ad6265SDimitry Andric template <class _Rp, class _Class, class ..._Param> 92*81ad6265SDimitry Andric struct __member_pointer_traits_imp<_Rp (_Class::*)(_Param...) volatile, true, false> 93*81ad6265SDimitry Andric { 94*81ad6265SDimitry Andric typedef _Class volatile _ClassType; 95*81ad6265SDimitry Andric typedef _Rp _ReturnType; 96*81ad6265SDimitry Andric typedef _Rp (_FnType) (_Param...); 97*81ad6265SDimitry Andric }; 98*81ad6265SDimitry Andric 99*81ad6265SDimitry Andric template <class _Rp, class _Class, class ..._Param> 100*81ad6265SDimitry Andric struct __member_pointer_traits_imp<_Rp (_Class::*)(_Param..., ...) volatile, true, false> 101*81ad6265SDimitry Andric { 102*81ad6265SDimitry Andric typedef _Class volatile _ClassType; 103*81ad6265SDimitry Andric typedef _Rp _ReturnType; 104*81ad6265SDimitry Andric typedef _Rp (_FnType) (_Param..., ...); 105*81ad6265SDimitry Andric }; 106*81ad6265SDimitry Andric 107*81ad6265SDimitry Andric template <class _Rp, class _Class, class ..._Param> 108*81ad6265SDimitry Andric struct __member_pointer_traits_imp<_Rp (_Class::*)(_Param...) const volatile, true, false> 109*81ad6265SDimitry Andric { 110*81ad6265SDimitry Andric typedef _Class const volatile _ClassType; 111*81ad6265SDimitry Andric typedef _Rp _ReturnType; 112*81ad6265SDimitry Andric typedef _Rp (_FnType) (_Param...); 113*81ad6265SDimitry Andric }; 114*81ad6265SDimitry Andric 115*81ad6265SDimitry Andric template <class _Rp, class _Class, class ..._Param> 116*81ad6265SDimitry Andric struct __member_pointer_traits_imp<_Rp (_Class::*)(_Param..., ...) const volatile, true, false> 117*81ad6265SDimitry Andric { 118*81ad6265SDimitry Andric typedef _Class const volatile _ClassType; 119*81ad6265SDimitry Andric typedef _Rp _ReturnType; 120*81ad6265SDimitry Andric typedef _Rp (_FnType) (_Param..., ...); 121*81ad6265SDimitry Andric }; 122*81ad6265SDimitry Andric 123*81ad6265SDimitry Andric template <class _Rp, class _Class, class ..._Param> 124*81ad6265SDimitry Andric struct __member_pointer_traits_imp<_Rp (_Class::*)(_Param...) &, true, false> 125*81ad6265SDimitry Andric { 126*81ad6265SDimitry Andric typedef _Class& _ClassType; 127*81ad6265SDimitry Andric typedef _Rp _ReturnType; 128*81ad6265SDimitry Andric typedef _Rp (_FnType) (_Param...); 129*81ad6265SDimitry Andric }; 130*81ad6265SDimitry Andric 131*81ad6265SDimitry Andric template <class _Rp, class _Class, class ..._Param> 132*81ad6265SDimitry Andric struct __member_pointer_traits_imp<_Rp (_Class::*)(_Param..., ...) &, true, false> 133*81ad6265SDimitry Andric { 134*81ad6265SDimitry Andric typedef _Class& _ClassType; 135*81ad6265SDimitry Andric typedef _Rp _ReturnType; 136*81ad6265SDimitry Andric typedef _Rp (_FnType) (_Param..., ...); 137*81ad6265SDimitry Andric }; 138*81ad6265SDimitry Andric 139*81ad6265SDimitry Andric template <class _Rp, class _Class, class ..._Param> 140*81ad6265SDimitry Andric struct __member_pointer_traits_imp<_Rp (_Class::*)(_Param...) const&, true, false> 141*81ad6265SDimitry Andric { 142*81ad6265SDimitry Andric typedef _Class const& _ClassType; 143*81ad6265SDimitry Andric typedef _Rp _ReturnType; 144*81ad6265SDimitry Andric typedef _Rp (_FnType) (_Param...); 145*81ad6265SDimitry Andric }; 146*81ad6265SDimitry Andric 147*81ad6265SDimitry Andric template <class _Rp, class _Class, class ..._Param> 148*81ad6265SDimitry Andric struct __member_pointer_traits_imp<_Rp (_Class::*)(_Param..., ...) const&, true, false> 149*81ad6265SDimitry Andric { 150*81ad6265SDimitry Andric typedef _Class const& _ClassType; 151*81ad6265SDimitry Andric typedef _Rp _ReturnType; 152*81ad6265SDimitry Andric typedef _Rp (_FnType) (_Param..., ...); 153*81ad6265SDimitry Andric }; 154*81ad6265SDimitry Andric 155*81ad6265SDimitry Andric template <class _Rp, class _Class, class ..._Param> 156*81ad6265SDimitry Andric struct __member_pointer_traits_imp<_Rp (_Class::*)(_Param...) volatile&, true, false> 157*81ad6265SDimitry Andric { 158*81ad6265SDimitry Andric typedef _Class volatile& _ClassType; 159*81ad6265SDimitry Andric typedef _Rp _ReturnType; 160*81ad6265SDimitry Andric typedef _Rp (_FnType) (_Param...); 161*81ad6265SDimitry Andric }; 162*81ad6265SDimitry Andric 163*81ad6265SDimitry Andric template <class _Rp, class _Class, class ..._Param> 164*81ad6265SDimitry Andric struct __member_pointer_traits_imp<_Rp (_Class::*)(_Param..., ...) volatile&, true, false> 165*81ad6265SDimitry Andric { 166*81ad6265SDimitry Andric typedef _Class volatile& _ClassType; 167*81ad6265SDimitry Andric typedef _Rp _ReturnType; 168*81ad6265SDimitry Andric typedef _Rp (_FnType) (_Param..., ...); 169*81ad6265SDimitry Andric }; 170*81ad6265SDimitry Andric 171*81ad6265SDimitry Andric template <class _Rp, class _Class, class ..._Param> 172*81ad6265SDimitry Andric struct __member_pointer_traits_imp<_Rp (_Class::*)(_Param...) const volatile&, true, false> 173*81ad6265SDimitry Andric { 174*81ad6265SDimitry Andric typedef _Class const volatile& _ClassType; 175*81ad6265SDimitry Andric typedef _Rp _ReturnType; 176*81ad6265SDimitry Andric typedef _Rp (_FnType) (_Param...); 177*81ad6265SDimitry Andric }; 178*81ad6265SDimitry Andric 179*81ad6265SDimitry Andric template <class _Rp, class _Class, class ..._Param> 180*81ad6265SDimitry Andric struct __member_pointer_traits_imp<_Rp (_Class::*)(_Param..., ...) const volatile&, true, false> 181*81ad6265SDimitry Andric { 182*81ad6265SDimitry Andric typedef _Class const volatile& _ClassType; 183*81ad6265SDimitry Andric typedef _Rp _ReturnType; 184*81ad6265SDimitry Andric typedef _Rp (_FnType) (_Param..., ...); 185*81ad6265SDimitry Andric }; 186*81ad6265SDimitry Andric 187*81ad6265SDimitry Andric template <class _Rp, class _Class, class ..._Param> 188*81ad6265SDimitry Andric struct __member_pointer_traits_imp<_Rp (_Class::*)(_Param...) &&, true, false> 189*81ad6265SDimitry Andric { 190*81ad6265SDimitry Andric typedef _Class&& _ClassType; 191*81ad6265SDimitry Andric typedef _Rp _ReturnType; 192*81ad6265SDimitry Andric typedef _Rp (_FnType) (_Param...); 193*81ad6265SDimitry Andric }; 194*81ad6265SDimitry Andric 195*81ad6265SDimitry Andric template <class _Rp, class _Class, class ..._Param> 196*81ad6265SDimitry Andric struct __member_pointer_traits_imp<_Rp (_Class::*)(_Param..., ...) &&, true, false> 197*81ad6265SDimitry Andric { 198*81ad6265SDimitry Andric typedef _Class&& _ClassType; 199*81ad6265SDimitry Andric typedef _Rp _ReturnType; 200*81ad6265SDimitry Andric typedef _Rp (_FnType) (_Param..., ...); 201*81ad6265SDimitry Andric }; 202*81ad6265SDimitry Andric 203*81ad6265SDimitry Andric template <class _Rp, class _Class, class ..._Param> 204*81ad6265SDimitry Andric struct __member_pointer_traits_imp<_Rp (_Class::*)(_Param...) const&&, true, false> 205*81ad6265SDimitry Andric { 206*81ad6265SDimitry Andric typedef _Class const&& _ClassType; 207*81ad6265SDimitry Andric typedef _Rp _ReturnType; 208*81ad6265SDimitry Andric typedef _Rp (_FnType) (_Param...); 209*81ad6265SDimitry Andric }; 210*81ad6265SDimitry Andric 211*81ad6265SDimitry Andric template <class _Rp, class _Class, class ..._Param> 212*81ad6265SDimitry Andric struct __member_pointer_traits_imp<_Rp (_Class::*)(_Param..., ...) const&&, true, false> 213*81ad6265SDimitry Andric { 214*81ad6265SDimitry Andric typedef _Class const&& _ClassType; 215*81ad6265SDimitry Andric typedef _Rp _ReturnType; 216*81ad6265SDimitry Andric typedef _Rp (_FnType) (_Param..., ...); 217*81ad6265SDimitry Andric }; 218*81ad6265SDimitry Andric 219*81ad6265SDimitry Andric template <class _Rp, class _Class, class ..._Param> 220*81ad6265SDimitry Andric struct __member_pointer_traits_imp<_Rp (_Class::*)(_Param...) volatile&&, true, false> 221*81ad6265SDimitry Andric { 222*81ad6265SDimitry Andric typedef _Class volatile&& _ClassType; 223*81ad6265SDimitry Andric typedef _Rp _ReturnType; 224*81ad6265SDimitry Andric typedef _Rp (_FnType) (_Param...); 225*81ad6265SDimitry Andric }; 226*81ad6265SDimitry Andric 227*81ad6265SDimitry Andric template <class _Rp, class _Class, class ..._Param> 228*81ad6265SDimitry Andric struct __member_pointer_traits_imp<_Rp (_Class::*)(_Param..., ...) volatile&&, true, false> 229*81ad6265SDimitry Andric { 230*81ad6265SDimitry Andric typedef _Class volatile&& _ClassType; 231*81ad6265SDimitry Andric typedef _Rp _ReturnType; 232*81ad6265SDimitry Andric typedef _Rp (_FnType) (_Param..., ...); 233*81ad6265SDimitry Andric }; 234*81ad6265SDimitry Andric 235*81ad6265SDimitry Andric template <class _Rp, class _Class, class ..._Param> 236*81ad6265SDimitry Andric struct __member_pointer_traits_imp<_Rp (_Class::*)(_Param...) const volatile&&, true, false> 237*81ad6265SDimitry Andric { 238*81ad6265SDimitry Andric typedef _Class const volatile&& _ClassType; 239*81ad6265SDimitry Andric typedef _Rp _ReturnType; 240*81ad6265SDimitry Andric typedef _Rp (_FnType) (_Param...); 241*81ad6265SDimitry Andric }; 242*81ad6265SDimitry Andric 243*81ad6265SDimitry Andric template <class _Rp, class _Class, class ..._Param> 244*81ad6265SDimitry Andric struct __member_pointer_traits_imp<_Rp (_Class::*)(_Param..., ...) const volatile&&, true, false> 245*81ad6265SDimitry Andric { 246*81ad6265SDimitry Andric typedef _Class const volatile&& _ClassType; 247*81ad6265SDimitry Andric typedef _Rp _ReturnType; 248*81ad6265SDimitry Andric typedef _Rp (_FnType) (_Param..., ...); 249*81ad6265SDimitry Andric }; 250*81ad6265SDimitry Andric 251*81ad6265SDimitry Andric template <class _Rp, class _Class> 252*81ad6265SDimitry Andric struct __member_pointer_traits_imp<_Rp _Class::*, false, true> 253*81ad6265SDimitry Andric { 254*81ad6265SDimitry Andric typedef _Class _ClassType; 255*81ad6265SDimitry Andric typedef _Rp _ReturnType; 256*81ad6265SDimitry Andric }; 257*81ad6265SDimitry Andric 258*81ad6265SDimitry Andric template <class _MP> 259*81ad6265SDimitry Andric struct __member_pointer_traits 260*81ad6265SDimitry Andric : public __member_pointer_traits_imp<typename remove_cv<_MP>::type, 261*81ad6265SDimitry Andric is_member_function_pointer<_MP>::value, 262*81ad6265SDimitry Andric is_member_object_pointer<_MP>::value> 263*81ad6265SDimitry Andric { 264*81ad6265SDimitry Andric // typedef ... _ClassType; 265*81ad6265SDimitry Andric // typedef ... _ReturnType; 266*81ad6265SDimitry Andric // typedef ... _FnType; 267*81ad6265SDimitry Andric }; 268*81ad6265SDimitry Andric 269*81ad6265SDimitry Andric template <class _DecayedFp> 270*81ad6265SDimitry Andric struct __member_pointer_class_type {}; 271*81ad6265SDimitry Andric 272*81ad6265SDimitry Andric template <class _Ret, class _ClassType> 273*81ad6265SDimitry Andric struct __member_pointer_class_type<_Ret _ClassType::*> { 274*81ad6265SDimitry Andric typedef _ClassType type; 275*81ad6265SDimitry Andric }; 276*81ad6265SDimitry Andric 277*81ad6265SDimitry Andric template <class _Fp, class _A0, 278*81ad6265SDimitry Andric class _DecayFp = typename decay<_Fp>::type, 279*81ad6265SDimitry Andric class _DecayA0 = typename decay<_A0>::type, 280*81ad6265SDimitry Andric class _ClassT = typename __member_pointer_class_type<_DecayFp>::type> 281*81ad6265SDimitry Andric using __enable_if_bullet1 = typename enable_if 282*81ad6265SDimitry Andric < 283*81ad6265SDimitry Andric is_member_function_pointer<_DecayFp>::value 284*81ad6265SDimitry Andric && is_base_of<_ClassT, _DecayA0>::value 285*81ad6265SDimitry Andric >::type; 286*81ad6265SDimitry Andric 287*81ad6265SDimitry Andric template <class _Fp, class _A0, 288*81ad6265SDimitry Andric class _DecayFp = typename decay<_Fp>::type, 289*81ad6265SDimitry Andric class _DecayA0 = typename decay<_A0>::type> 290*81ad6265SDimitry Andric using __enable_if_bullet2 = typename enable_if 291*81ad6265SDimitry Andric < 292*81ad6265SDimitry Andric is_member_function_pointer<_DecayFp>::value 293*81ad6265SDimitry Andric && __is_reference_wrapper<_DecayA0>::value 294*81ad6265SDimitry Andric >::type; 295*81ad6265SDimitry Andric 296*81ad6265SDimitry Andric template <class _Fp, class _A0, 297*81ad6265SDimitry Andric class _DecayFp = typename decay<_Fp>::type, 298*81ad6265SDimitry Andric class _DecayA0 = typename decay<_A0>::type, 299*81ad6265SDimitry Andric class _ClassT = typename __member_pointer_class_type<_DecayFp>::type> 300*81ad6265SDimitry Andric using __enable_if_bullet3 = typename enable_if 301*81ad6265SDimitry Andric < 302*81ad6265SDimitry Andric is_member_function_pointer<_DecayFp>::value 303*81ad6265SDimitry Andric && !is_base_of<_ClassT, _DecayA0>::value 304*81ad6265SDimitry Andric && !__is_reference_wrapper<_DecayA0>::value 305*81ad6265SDimitry Andric >::type; 306*81ad6265SDimitry Andric 307*81ad6265SDimitry Andric template <class _Fp, class _A0, 308*81ad6265SDimitry Andric class _DecayFp = typename decay<_Fp>::type, 309*81ad6265SDimitry Andric class _DecayA0 = typename decay<_A0>::type, 310*81ad6265SDimitry Andric class _ClassT = typename __member_pointer_class_type<_DecayFp>::type> 311*81ad6265SDimitry Andric using __enable_if_bullet4 = typename enable_if 312*81ad6265SDimitry Andric < 313*81ad6265SDimitry Andric is_member_object_pointer<_DecayFp>::value 314*81ad6265SDimitry Andric && is_base_of<_ClassT, _DecayA0>::value 315*81ad6265SDimitry Andric >::type; 316*81ad6265SDimitry Andric 317*81ad6265SDimitry Andric template <class _Fp, class _A0, 318*81ad6265SDimitry Andric class _DecayFp = typename decay<_Fp>::type, 319*81ad6265SDimitry Andric class _DecayA0 = typename decay<_A0>::type> 320*81ad6265SDimitry Andric using __enable_if_bullet5 = typename enable_if 321*81ad6265SDimitry Andric < 322*81ad6265SDimitry Andric is_member_object_pointer<_DecayFp>::value 323*81ad6265SDimitry Andric && __is_reference_wrapper<_DecayA0>::value 324*81ad6265SDimitry Andric >::type; 325*81ad6265SDimitry Andric 326*81ad6265SDimitry Andric template <class _Fp, class _A0, 327*81ad6265SDimitry Andric class _DecayFp = typename decay<_Fp>::type, 328*81ad6265SDimitry Andric class _DecayA0 = typename decay<_A0>::type, 329*81ad6265SDimitry Andric class _ClassT = typename __member_pointer_class_type<_DecayFp>::type> 330*81ad6265SDimitry Andric using __enable_if_bullet6 = typename enable_if 331*81ad6265SDimitry Andric < 332*81ad6265SDimitry Andric is_member_object_pointer<_DecayFp>::value 333*81ad6265SDimitry Andric && !is_base_of<_ClassT, _DecayA0>::value 334*81ad6265SDimitry Andric && !__is_reference_wrapper<_DecayA0>::value 335*81ad6265SDimitry Andric >::type; 336*81ad6265SDimitry Andric 337*81ad6265SDimitry Andric // __invoke forward declarations 338*81ad6265SDimitry Andric 339*81ad6265SDimitry Andric // fall back - none of the bullets 340*81ad6265SDimitry Andric 341*81ad6265SDimitry Andric template <class ..._Args> 342*81ad6265SDimitry Andric __nat __invoke(__any, _Args&& ...__args); 343*81ad6265SDimitry Andric 344*81ad6265SDimitry Andric // bullets 1, 2 and 3 345*81ad6265SDimitry Andric 346*81ad6265SDimitry Andric template <class _Fp, class _A0, class ..._Args, 347*81ad6265SDimitry Andric class = __enable_if_bullet1<_Fp, _A0> > 348*81ad6265SDimitry Andric inline _LIBCPP_INLINE_VISIBILITY 349*81ad6265SDimitry Andric _LIBCPP_CONSTEXPR decltype((std::declval<_A0>().*std::declval<_Fp>())(std::declval<_Args>()...)) 350*81ad6265SDimitry Andric __invoke(_Fp&& __f, _A0&& __a0, _Args&& ...__args) 351*81ad6265SDimitry Andric _NOEXCEPT_(noexcept((static_cast<_A0&&>(__a0).*__f)(static_cast<_Args&&>(__args)...))) 352*81ad6265SDimitry Andric { return (static_cast<_A0&&>(__a0).*__f)(static_cast<_Args&&>(__args)...); } 353*81ad6265SDimitry Andric 354*81ad6265SDimitry Andric template <class _Fp, class _A0, class ..._Args, 355*81ad6265SDimitry Andric class = __enable_if_bullet2<_Fp, _A0> > 356*81ad6265SDimitry Andric inline _LIBCPP_INLINE_VISIBILITY 357*81ad6265SDimitry Andric _LIBCPP_CONSTEXPR decltype((std::declval<_A0>().get().*std::declval<_Fp>())(std::declval<_Args>()...)) 358*81ad6265SDimitry Andric __invoke(_Fp&& __f, _A0&& __a0, _Args&& ...__args) 359*81ad6265SDimitry Andric _NOEXCEPT_(noexcept((__a0.get().*__f)(static_cast<_Args&&>(__args)...))) 360*81ad6265SDimitry Andric { return (__a0.get().*__f)(static_cast<_Args&&>(__args)...); } 361*81ad6265SDimitry Andric 362*81ad6265SDimitry Andric template <class _Fp, class _A0, class ..._Args, 363*81ad6265SDimitry Andric class = __enable_if_bullet3<_Fp, _A0> > 364*81ad6265SDimitry Andric inline _LIBCPP_INLINE_VISIBILITY 365*81ad6265SDimitry Andric _LIBCPP_CONSTEXPR decltype(((*std::declval<_A0>()).*std::declval<_Fp>())(std::declval<_Args>()...)) 366*81ad6265SDimitry Andric __invoke(_Fp&& __f, _A0&& __a0, _Args&& ...__args) 367*81ad6265SDimitry Andric _NOEXCEPT_(noexcept(((*static_cast<_A0&&>(__a0)).*__f)(static_cast<_Args&&>(__args)...))) 368*81ad6265SDimitry Andric { return ((*static_cast<_A0&&>(__a0)).*__f)(static_cast<_Args&&>(__args)...); } 369*81ad6265SDimitry Andric 370*81ad6265SDimitry Andric // bullets 4, 5 and 6 371*81ad6265SDimitry Andric 372*81ad6265SDimitry Andric template <class _Fp, class _A0, 373*81ad6265SDimitry Andric class = __enable_if_bullet4<_Fp, _A0> > 374*81ad6265SDimitry Andric inline _LIBCPP_INLINE_VISIBILITY 375*81ad6265SDimitry Andric _LIBCPP_CONSTEXPR decltype(std::declval<_A0>().*std::declval<_Fp>()) 376*81ad6265SDimitry Andric __invoke(_Fp&& __f, _A0&& __a0) 377*81ad6265SDimitry Andric _NOEXCEPT_(noexcept(static_cast<_A0&&>(__a0).*__f)) 378*81ad6265SDimitry Andric { return static_cast<_A0&&>(__a0).*__f; } 379*81ad6265SDimitry Andric 380*81ad6265SDimitry Andric template <class _Fp, class _A0, 381*81ad6265SDimitry Andric class = __enable_if_bullet5<_Fp, _A0> > 382*81ad6265SDimitry Andric inline _LIBCPP_INLINE_VISIBILITY 383*81ad6265SDimitry Andric _LIBCPP_CONSTEXPR decltype(std::declval<_A0>().get().*std::declval<_Fp>()) 384*81ad6265SDimitry Andric __invoke(_Fp&& __f, _A0&& __a0) 385*81ad6265SDimitry Andric _NOEXCEPT_(noexcept(__a0.get().*__f)) 386*81ad6265SDimitry Andric { return __a0.get().*__f; } 387*81ad6265SDimitry Andric 388*81ad6265SDimitry Andric template <class _Fp, class _A0, 389*81ad6265SDimitry Andric class = __enable_if_bullet6<_Fp, _A0> > 390*81ad6265SDimitry Andric inline _LIBCPP_INLINE_VISIBILITY 391*81ad6265SDimitry Andric _LIBCPP_CONSTEXPR decltype((*std::declval<_A0>()).*std::declval<_Fp>()) 392*81ad6265SDimitry Andric __invoke(_Fp&& __f, _A0&& __a0) 393*81ad6265SDimitry Andric _NOEXCEPT_(noexcept((*static_cast<_A0&&>(__a0)).*__f)) 394*81ad6265SDimitry Andric { return (*static_cast<_A0&&>(__a0)).*__f; } 395*81ad6265SDimitry Andric 396*81ad6265SDimitry Andric // bullet 7 397*81ad6265SDimitry Andric 398*81ad6265SDimitry Andric template <class _Fp, class ..._Args> 399*81ad6265SDimitry Andric inline _LIBCPP_INLINE_VISIBILITY 400*81ad6265SDimitry Andric _LIBCPP_CONSTEXPR decltype(std::declval<_Fp>()(std::declval<_Args>()...)) 401*81ad6265SDimitry Andric __invoke(_Fp&& __f, _Args&& ...__args) 402*81ad6265SDimitry Andric _NOEXCEPT_(noexcept(static_cast<_Fp&&>(__f)(static_cast<_Args&&>(__args)...))) 403*81ad6265SDimitry Andric { return static_cast<_Fp&&>(__f)(static_cast<_Args&&>(__args)...); } 404*81ad6265SDimitry Andric 405*81ad6265SDimitry Andric // __invokable 406*81ad6265SDimitry Andric template <class _Ret, class _Fp, class ..._Args> 407*81ad6265SDimitry Andric struct __invokable_r 408*81ad6265SDimitry Andric { 409*81ad6265SDimitry Andric template <class _XFp, class ..._XArgs> 410*81ad6265SDimitry Andric static decltype(std::__invoke(declval<_XFp>(), declval<_XArgs>()...)) __try_call(int); 411*81ad6265SDimitry Andric template <class _XFp, class ..._XArgs> 412*81ad6265SDimitry Andric static __nat __try_call(...); 413*81ad6265SDimitry Andric 414*81ad6265SDimitry Andric // FIXME: Check that _Ret, _Fp, and _Args... are all complete types, cv void, 415*81ad6265SDimitry Andric // or incomplete array types as required by the standard. 416*81ad6265SDimitry Andric using _Result = decltype(__try_call<_Fp, _Args...>(0)); 417*81ad6265SDimitry Andric 418*81ad6265SDimitry Andric using type = typename conditional< 419*81ad6265SDimitry Andric _IsNotSame<_Result, __nat>::value, 420*81ad6265SDimitry Andric typename conditional< is_void<_Ret>::value, true_type, __is_core_convertible<_Result, _Ret> >::type, 421*81ad6265SDimitry Andric false_type >::type; 422*81ad6265SDimitry Andric static const bool value = type::value; 423*81ad6265SDimitry Andric }; 424*81ad6265SDimitry Andric template <class _Fp, class ..._Args> 425*81ad6265SDimitry Andric using __invokable = __invokable_r<void, _Fp, _Args...>; 426*81ad6265SDimitry Andric 427*81ad6265SDimitry Andric template <bool _IsInvokable, bool _IsCVVoid, class _Ret, class _Fp, class ..._Args> 428*81ad6265SDimitry Andric struct __nothrow_invokable_r_imp { 429*81ad6265SDimitry Andric static const bool value = false; 430*81ad6265SDimitry Andric }; 431*81ad6265SDimitry Andric 432*81ad6265SDimitry Andric template <class _Ret, class _Fp, class ..._Args> 433*81ad6265SDimitry Andric struct __nothrow_invokable_r_imp<true, false, _Ret, _Fp, _Args...> 434*81ad6265SDimitry Andric { 435*81ad6265SDimitry Andric typedef __nothrow_invokable_r_imp _ThisT; 436*81ad6265SDimitry Andric 437*81ad6265SDimitry Andric template <class _Tp> 438*81ad6265SDimitry Andric static void __test_noexcept(_Tp) _NOEXCEPT; 439*81ad6265SDimitry Andric 440*81ad6265SDimitry Andric static const bool value = noexcept(_ThisT::__test_noexcept<_Ret>( 441*81ad6265SDimitry Andric _VSTD::__invoke(declval<_Fp>(), declval<_Args>()...))); 442*81ad6265SDimitry Andric }; 443*81ad6265SDimitry Andric 444*81ad6265SDimitry Andric template <class _Ret, class _Fp, class ..._Args> 445*81ad6265SDimitry Andric struct __nothrow_invokable_r_imp<true, true, _Ret, _Fp, _Args...> 446*81ad6265SDimitry Andric { 447*81ad6265SDimitry Andric static const bool value = noexcept( 448*81ad6265SDimitry Andric _VSTD::__invoke(declval<_Fp>(), declval<_Args>()...)); 449*81ad6265SDimitry Andric }; 450*81ad6265SDimitry Andric 451*81ad6265SDimitry Andric template <class _Ret, class _Fp, class ..._Args> 452*81ad6265SDimitry Andric using __nothrow_invokable_r = 453*81ad6265SDimitry Andric __nothrow_invokable_r_imp< 454*81ad6265SDimitry Andric __invokable_r<_Ret, _Fp, _Args...>::value, 455*81ad6265SDimitry Andric is_void<_Ret>::value, 456*81ad6265SDimitry Andric _Ret, _Fp, _Args... 457*81ad6265SDimitry Andric >; 458*81ad6265SDimitry Andric 459*81ad6265SDimitry Andric template <class _Fp, class ..._Args> 460*81ad6265SDimitry Andric using __nothrow_invokable = 461*81ad6265SDimitry Andric __nothrow_invokable_r_imp< 462*81ad6265SDimitry Andric __invokable<_Fp, _Args...>::value, 463*81ad6265SDimitry Andric true, void, _Fp, _Args... 464*81ad6265SDimitry Andric >; 465*81ad6265SDimitry Andric 466*81ad6265SDimitry Andric template <class _Fp, class ..._Args> 467*81ad6265SDimitry Andric struct __invoke_of 468*81ad6265SDimitry Andric : public enable_if< 469*81ad6265SDimitry Andric __invokable<_Fp, _Args...>::value, 470*81ad6265SDimitry Andric typename __invokable_r<void, _Fp, _Args...>::_Result> 471*81ad6265SDimitry Andric { 472*81ad6265SDimitry Andric }; 473*81ad6265SDimitry Andric 474fe6060f1SDimitry Andric template <class _Ret, bool = is_void<_Ret>::value> 475fe6060f1SDimitry Andric struct __invoke_void_return_wrapper 476fe6060f1SDimitry Andric { 477fe6060f1SDimitry Andric template <class ..._Args> 478fe6060f1SDimitry Andric static _Ret __call(_Args&&... __args) { 479*81ad6265SDimitry Andric return std::__invoke(std::forward<_Args>(__args)...); 480fe6060f1SDimitry Andric } 481fe6060f1SDimitry Andric }; 482fe6060f1SDimitry Andric 483fe6060f1SDimitry Andric template <class _Ret> 484fe6060f1SDimitry Andric struct __invoke_void_return_wrapper<_Ret, true> 485fe6060f1SDimitry Andric { 486fe6060f1SDimitry Andric template <class ..._Args> 487fe6060f1SDimitry Andric static void __call(_Args&&... __args) { 488*81ad6265SDimitry Andric std::__invoke(std::forward<_Args>(__args)...); 489fe6060f1SDimitry Andric } 490fe6060f1SDimitry Andric }; 491fe6060f1SDimitry Andric 492fe6060f1SDimitry Andric #if _LIBCPP_STD_VER > 14 493fe6060f1SDimitry Andric 494*81ad6265SDimitry Andric // is_invocable 495*81ad6265SDimitry Andric 496*81ad6265SDimitry Andric template <class _Fn, class ..._Args> 497*81ad6265SDimitry Andric struct _LIBCPP_TEMPLATE_VIS is_invocable 498*81ad6265SDimitry Andric : integral_constant<bool, __invokable<_Fn, _Args...>::value> {}; 499*81ad6265SDimitry Andric 500*81ad6265SDimitry Andric template <class _Ret, class _Fn, class ..._Args> 501*81ad6265SDimitry Andric struct _LIBCPP_TEMPLATE_VIS is_invocable_r 502*81ad6265SDimitry Andric : integral_constant<bool, __invokable_r<_Ret, _Fn, _Args...>::value> {}; 503*81ad6265SDimitry Andric 504*81ad6265SDimitry Andric template <class _Fn, class ..._Args> 505*81ad6265SDimitry Andric inline constexpr bool is_invocable_v = is_invocable<_Fn, _Args...>::value; 506*81ad6265SDimitry Andric 507*81ad6265SDimitry Andric template <class _Ret, class _Fn, class ..._Args> 508*81ad6265SDimitry Andric inline constexpr bool is_invocable_r_v = is_invocable_r<_Ret, _Fn, _Args...>::value; 509*81ad6265SDimitry Andric 510*81ad6265SDimitry Andric // is_nothrow_invocable 511*81ad6265SDimitry Andric 512*81ad6265SDimitry Andric template <class _Fn, class ..._Args> 513*81ad6265SDimitry Andric struct _LIBCPP_TEMPLATE_VIS is_nothrow_invocable 514*81ad6265SDimitry Andric : integral_constant<bool, __nothrow_invokable<_Fn, _Args...>::value> {}; 515*81ad6265SDimitry Andric 516*81ad6265SDimitry Andric template <class _Ret, class _Fn, class ..._Args> 517*81ad6265SDimitry Andric struct _LIBCPP_TEMPLATE_VIS is_nothrow_invocable_r 518*81ad6265SDimitry Andric : integral_constant<bool, __nothrow_invokable_r<_Ret, _Fn, _Args...>::value> {}; 519*81ad6265SDimitry Andric 520*81ad6265SDimitry Andric template <class _Fn, class ..._Args> 521*81ad6265SDimitry Andric inline constexpr bool is_nothrow_invocable_v = is_nothrow_invocable<_Fn, _Args...>::value; 522*81ad6265SDimitry Andric 523*81ad6265SDimitry Andric template <class _Ret, class _Fn, class ..._Args> 524*81ad6265SDimitry Andric inline constexpr bool is_nothrow_invocable_r_v = is_nothrow_invocable_r<_Ret, _Fn, _Args...>::value; 525*81ad6265SDimitry Andric 526*81ad6265SDimitry Andric template <class _Fn, class... _Args> 527*81ad6265SDimitry Andric struct _LIBCPP_TEMPLATE_VIS invoke_result 528*81ad6265SDimitry Andric : __invoke_of<_Fn, _Args...> 529*81ad6265SDimitry Andric { 530*81ad6265SDimitry Andric }; 531*81ad6265SDimitry Andric 532*81ad6265SDimitry Andric template <class _Fn, class... _Args> 533*81ad6265SDimitry Andric using invoke_result_t = typename invoke_result<_Fn, _Args...>::type; 534*81ad6265SDimitry Andric 535fe6060f1SDimitry Andric template <class _Fn, class ..._Args> 536fe6060f1SDimitry Andric _LIBCPP_CONSTEXPR_AFTER_CXX17 invoke_result_t<_Fn, _Args...> 537fe6060f1SDimitry Andric invoke(_Fn&& __f, _Args&&... __args) 538fe6060f1SDimitry Andric noexcept(is_nothrow_invocable_v<_Fn, _Args...>) 539fe6060f1SDimitry Andric { 540fe6060f1SDimitry Andric return _VSTD::__invoke(_VSTD::forward<_Fn>(__f), _VSTD::forward<_Args>(__args)...); 541fe6060f1SDimitry Andric } 542fe6060f1SDimitry Andric 543fe6060f1SDimitry Andric #endif // _LIBCPP_STD_VER > 14 544fe6060f1SDimitry Andric 545fe6060f1SDimitry Andric _LIBCPP_END_NAMESPACE_STD 546fe6060f1SDimitry Andric 547fe6060f1SDimitry Andric #endif // _LIBCPP___FUNCTIONAL_INVOKE_H 548