diff --git a/include/__functional_base b/include/__functional_base index 518c9b7a..caf0093e 100644 --- a/include/__functional_base +++ b/include/__functional_base @@ -281,169 +281,55 @@ struct __weak_result_type<_R (_C::*)(_A1, _A2, _A3...) const volatile> // __invoke -// first bullet +// bullets 1 and 2 -template +template inline _LIBCPP_INLINE_VISIBILITY -typename enable_if -< - sizeof...(_Param) == sizeof...(_Arg) && - is_base_of<_T, typename remove_reference<_T1>::type>::value, - _R ->::type -__invoke(_R (_T::*__f)(_Param...), _T1&& __t1, _Arg&& ...__arg) +auto +__invoke(_F&& __f, _A0&& __a0, _Args&& ...__args) + -> decltype((_STD::forward<_A0>(__a0).*__f)(_STD::forward<_Args>(__args)...)) { - return (_STD::forward<_T>(__t1).*__f)(_STD::forward<_Arg>(__arg)...); + return (_STD::forward<_A0>(__a0).*__f)(_STD::forward<_Args>(__args)...); } -template +template inline _LIBCPP_INLINE_VISIBILITY -typename enable_if -< - sizeof...(_Param) == sizeof...(_Arg) && - is_base_of<_T, typename remove_reference<_T1>::type>::value, - _R ->::type -__invoke(_R (_T::*__f)(_Param...) const, _T1&& __t1, _Arg&& ...__arg) +auto +__invoke(_F&& __f, _A0&& __a0, _Args&& ...__args) + -> decltype(((*_STD::forward<_A0>(__a0)).*__f)(_STD::forward<_Args>(__args)...)) { - return (_STD::forward(__t1).*__f)(_STD::forward<_Arg>(__arg)...); + return ((*_STD::forward<_A0>(__a0)).*__f)(_STD::forward<_Args>(__args)...); } -template +// bullets 3 and 4 + +template inline _LIBCPP_INLINE_VISIBILITY -typename enable_if -< - sizeof...(_Param) == sizeof...(_Arg) && - is_base_of<_T, typename remove_reference<_T1>::type>::value, - _R ->::type -__invoke(_R (_T::*__f)(_Param...) volatile, _T1&& __t1, _Arg&& ...__arg) +auto +__invoke(_F&& __f, _A0&& __a0) + -> decltype(_STD::forward<_A0>(__a0).*__f) { - return (_STD::forward(__t1).*__f)(_STD::forward<_Arg>(__arg)...); + return _STD::forward<_A0>(__a0).*__f; } -template +template inline _LIBCPP_INLINE_VISIBILITY -typename enable_if -< - sizeof...(_Param) == sizeof...(_Arg) && - is_base_of<_T, typename remove_reference<_T1>::type>::value, - _R ->::type -__invoke(_R (_T::*__f)(_Param...) const volatile, _T1&& __t1, _Arg&& ...__arg) +auto +__invoke(_F&& __f, _A0&& __a0) + -> decltype((*_STD::forward<_A0>(__a0)).*__f) { - return (_STD::forward(__t1).*__f)(_STD::forward<_Arg>(__arg)...); + return (*_STD::forward<_A0>(__a0)).*__f; } -// second bullet +// bullet 5 -template +template inline _LIBCPP_INLINE_VISIBILITY -typename enable_if -< - sizeof...(_Param) == sizeof...(_Arg) && - !is_base_of<_T, typename remove_reference<_T1>::type>::value, - _R ->::type -__invoke(_R (_T::*__f)(_Param...), _T1&& __t1, _Arg&& ...__arg) +auto +__invoke(_F&& __f, _Args&& ...__args) + -> decltype(_STD::forward<_F>(__f)(_STD::forward<_Args>(__args)...)) { - return ((*_STD::forward<_T1>(__t1)).*__f)(_STD::forward<_Arg>(__arg)...); -} - -template -inline _LIBCPP_INLINE_VISIBILITY -typename enable_if -< - sizeof...(_Param) == sizeof...(_Arg) && - !is_base_of<_T, typename remove_reference<_T1>::type>::value, - _R ->::type -__invoke(_R (_T::*__f)(_Param...) const, _T1&& __t1, _Arg&& ...__arg) -{ - return ((*_STD::forward<_T1>(__t1)).*__f)(_STD::forward<_Arg>(__arg)...); -} - -template -inline _LIBCPP_INLINE_VISIBILITY -typename enable_if -< - sizeof...(_Param) == sizeof...(_Arg) && - !is_base_of<_T, typename remove_reference<_T1>::type>::value, - _R ->::type -__invoke(_R (_T::*__f)(_Param...) volatile, _T1&& __t1, _Arg&& ...__arg) -{ - return ((*_STD::forward<_T1>(__t1)).*__f)(_STD::forward<_Arg>(__arg)...); -} - -template -inline _LIBCPP_INLINE_VISIBILITY -typename enable_if -< - sizeof...(_Param) == sizeof...(_Arg) && - !is_base_of<_T, typename remove_reference<_T1>::type>::value, - _R ->::type -__invoke(_R (_T::*__f)(_Param...) const volatile, _T1&& __t1, _Arg&& ...__arg) -{ - return ((*_STD::forward<_T1>(__t1)).*__f)(_STD::forward<_Arg>(__arg)...); -} - -// third bullet - -template -inline _LIBCPP_INLINE_VISIBILITY -typename enable_if -< - is_base_of<_T, typename remove_reference<_T1>::type>::value, - typename __apply_cv<_T1, _R>::type&& ->::type -__invoke(_R _T::* __f, _T1&& __t1) -{ - return _STD::forward<_T1>(__t1).*__f; -} - -// forth bullet - -template -struct __4th_helper -{ -}; - -template -struct __4th_helper<_T1, _R, true> -{ - typedef typename __apply_cv()), _R>::type type; -}; - -template -inline _LIBCPP_INLINE_VISIBILITY -typename __4th_helper<_T1, _R, - !is_base_of<_T, - typename remove_reference<_T1>::type - >::value - >::type&& -__invoke(_R _T::* __f, _T1&& __t1) -{ - return (*_STD::forward<_T1>(__t1)).*__f; -} - -// fifth bullet - -template -inline _LIBCPP_INLINE_VISIBILITY -_R -__invoke(_R (*__f)(_Param...), _Args&& ...__args) -{ - return __f(_STD::forward<_Args>(__args)...); -} - -template -inline _LIBCPP_INLINE_VISIBILITY -typename __invoke_of<_F, _T...>::type -__invoke(_F&& __f, _T&& ...__t) -{ - return _STD::forward<_F>(__f)(_STD::forward<_T>(__t)...); + return _STD::forward<_F>(__f)(_STD::forward<_Args>(__args)...); } template diff --git a/include/type_traits b/include/type_traits index e4e96fe1..12d10222 100644 --- a/include/type_traits +++ b/include/type_traits @@ -2775,105 +2775,61 @@ template struct _LIBCPP_VISIBLE is_trivial #ifndef _LIBCPP_HAS_NO_VARIADICS -// __invokable +// __invoke forward declarations -template -struct __invokable_imp - : false_type -{ -}; - -// __invokable member function pointer - -template -auto -__invokable_mfp_test(_A0&& __a0, _F __f, _Args&& ...__args) - -> decltype((_STD::forward<_A0>(__a0).*__f)(_STD::forward<_Args>(__args)...)); - -template -auto -__invokable_mfp_test(_A0&& __a0, _F __f, _Args&& ...__args) - -> decltype(((*_STD::forward<_A0>(__a0)).*__f)(_STD::forward<_Args>(__args)...)); - -template -auto -__invokable_mfp_test(__any, _F __f, _Args&& ...__args) - -> __nat; - -template -struct __invokable_imp<2, _F, _A0, _Args...> -{ - typedef decltype( - __invokable_mfp_test(_STD::declval<_A0>(), _STD::declval<_F>(), - _STD::declval<_Args>()...) - ) type; - static const bool value = !is_same::value; -}; - -// __invokable member object pointer - -template -auto -__invokable_mop_test(_A0&& __a0, _F __f) - -> decltype(_STD::forward<_A0>(__a0).*__f); - -template -auto -__invokable_mop_test(_A0&& __a0, _F __f) - -> decltype((*_STD::forward<_A0>(__a0)).*__f); - -template -auto -__invokable_mop_test(__any, _F __f) - -> __nat; - -template -struct __invokable_imp<1, _F, _A0> -{ - typedef decltype( - __invokable_mop_test(_STD::declval<_A0>(), _STD::declval<_F>()) - ) type; - static const bool value = !is_same::value; -}; - -// __invokable other - -template -auto -__invokable_other_test(_F&& __f, _Args&& ...__args) - -> decltype(_STD::forward<_F>(__f)(_STD::forward<_Args>(__args)...)); +// fall back - none of the bullets template auto -__invokable_other_test(__any, _Args&& ...__args) +__invoke(__any, _Args&& ...__args) -> __nat; +// bullets 1 and 2 + +template +auto +__invoke(_F&& __f, _A0&& __a0, _Args&& ...__args) + -> decltype((_STD::forward<_A0>(__a0).*__f)(_STD::forward<_Args>(__args)...)); + +template +auto +__invoke(_F&& __f, _A0&& __a0, _Args&& ...__args) + -> decltype(((*_STD::forward<_A0>(__a0)).*__f)(_STD::forward<_Args>(__args)...)); + +// bullets 3 and 4 + +template +auto +__invoke(_F&& __f, _A0&& __a0) + -> decltype(_STD::forward<_A0>(__a0).*__f); + +template +auto +__invoke(_F&& __f, _A0&& __a0) + -> decltype((*_STD::forward<_A0>(__a0)).*__f); + +// bullet 5 + template -struct __invokable_imp<0, _F, _Args...> +auto +__invoke(_F&& __f, _Args&& ...__args) + -> decltype(_STD::forward<_F>(__f)(_STD::forward<_Args>(__args)...)); + +// __invokable + +template +struct __invokable_imp { typedef decltype( - __invokable_other_test(_STD::declval<_F>(), _STD::declval<_Args>()...) + __invoke(_STD::declval<_F>(), _STD::declval<_Args>()...) ) type; static const bool value = !is_same::value; }; -// __invokable_classify - -template -struct __invokable_classify -{ - typedef typename remove_reference<_F>::type _FR; - static const unsigned value = is_member_function_pointer<_FR>::value ? - 2 : - is_member_object_pointer<_FR>::value ? - 1 : - 0; -}; - template struct __invokable : public integral_constant::value, _F, _Args...>::value> + __invokable_imp<_F, _Args...>::value> { }; @@ -2887,7 +2843,7 @@ struct __invoke_of_imp // false template struct __invoke_of_imp { - typedef typename __invokable_imp<__invokable_classify<_F>::value, _F, _Args...>::type type; + typedef typename __invokable_imp<_F, _Args...>::type type; }; template