Index: include/__functional_base =================================================================== --- include/__functional_base +++ include/__functional_base @@ -360,60 +360,19 @@ // __invoke -// bullets 1 and 2 +#define _LIBCPP_INVOKE_CONSTEXPR +#define _LIBCPP_INVOKE_NAME __invoke +#define _LIBCPP_DEFINE_INVOKE +#include <__invoke> -template -inline _LIBCPP_INLINE_VISIBILITY -auto -__invoke(_Fp&& __f, _A0&& __a0, _Args&& ...__args) - -> decltype((_VSTD::forward<_A0>(__a0).*__f)(_VSTD::forward<_Args>(__args)...)) -{ - return (_VSTD::forward<_A0>(__a0).*__f)(_VSTD::forward<_Args>(__args)...); -} - -template -inline _LIBCPP_INLINE_VISIBILITY -auto -__invoke(_Fp&& __f, _A0&& __a0, _Args&& ...__args) - -> decltype(((*_VSTD::forward<_A0>(__a0)).*__f)(_VSTD::forward<_Args>(__args)...)) -{ - return ((*_VSTD::forward<_A0>(__a0)).*__f)(_VSTD::forward<_Args>(__args)...); -} -// bullets 3 and 4 +// __invoke_constexpr -template -inline _LIBCPP_INLINE_VISIBILITY -auto -__invoke(_Fp&& __f, _A0&& __a0) - -> decltype(_VSTD::forward<_A0>(__a0).*__f) -{ - return _VSTD::forward<_A0>(__a0).*__f; -} - -template -inline _LIBCPP_INLINE_VISIBILITY -auto -__invoke(_Fp&& __f, _A0&& __a0) - -> decltype((*_VSTD::forward<_A0>(__a0)).*__f) -{ - return (*_VSTD::forward<_A0>(__a0)).*__f; -} - -// bullet 5 - -template -inline _LIBCPP_INLINE_VISIBILITY -auto -__invoke(_Fp&& __f, _Args&& ...__args) - -> decltype(_VSTD::forward<_Fp>(__f)(_VSTD::forward<_Args>(__args)...)) -{ - return _VSTD::forward<_Fp>(__f)(_VSTD::forward<_Args>(__args)...); -} +#define _LIBCPP_INVOKE_CONSTEXPR _LIBCPP_CONSTEXPR +#define _LIBCPP_INVOKE_NAME __invoke_constexpr +#define _LIBCPP_DECLARE_INVOKE +#define _LIBCPP_DEFINE_INVOKE +#include <__invoke> template struct __invoke_return Index: include/__invoke =================================================================== --- /dev/null +++ include/__invoke @@ -0,0 +1,164 @@ +// -*- C++ -*- +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP_INVOKE_CONSTEXPR +#error _LIBCPP_INVOKE_CONSTEXPR must be defined +#endif + +#ifndef _LIBCPP_INVOKE_NAME +#error _LIBCPP_INVOKE_NAME must be defined +#endif + +#if !defined(_LIBCPP_DECLARE_INVOKE) && !defined(_LIBCPP_DEFINE_INVOKE) +#error _LIBCPP_DECLARE_INVOKE or _LIBCPP_DEFINE_INVOKE must be defined \ + before <__invoke> is included. +#endif + +#ifdef _LIBCPP_DECLARE_INVOKE + +// __invoke forward declarations + +// fall back - none of the bullets + +template +auto +_LIBCPP_INVOKE_NAME (__any, _Args&& ...__args) + -> __nat; + +// bullets 1 and 2 + +template ::type>::value && + is_base_of::type>::_ClassType>::type, + typename remove_reference<_A0>::type>::value + >::type + > +_LIBCPP_INLINE_VISIBILITY _LIBCPP_INVOKE_CONSTEXPR +auto +_LIBCPP_INVOKE_NAME (_Fp&& __f, _A0&& __a0, _Args&& ...__args) + -> decltype((_VSTD::forward<_A0>(__a0).*__f)(_VSTD::forward<_Args>(__args)...)); + +template ::type>::value && + !is_base_of::type>::_ClassType>::type, + typename remove_reference<_A0>::type>::value + >::type + > +_LIBCPP_INLINE_VISIBILITY _LIBCPP_INVOKE_CONSTEXPR +auto +_LIBCPP_INVOKE_NAME (_Fp&& __f, _A0&& __a0, _Args&& ...__args) + -> decltype(((*_VSTD::forward<_A0>(__a0)).*__f)(_VSTD::forward<_Args>(__args)...)); + +// bullets 3 and 4 + +template ::type>::value && + is_base_of::type>::_ClassType, + typename remove_reference<_A0>::type>::value + >::type + > +_LIBCPP_INLINE_VISIBILITY _LIBCPP_INVOKE_CONSTEXPR +auto +_LIBCPP_INVOKE_NAME (_Fp&& __f, _A0&& __a0) + -> decltype(_VSTD::forward<_A0>(__a0).*__f); + +template ::type>::value && + !is_base_of::type>::_ClassType, + typename remove_reference<_A0>::type>::value + >::type + > +_LIBCPP_INLINE_VISIBILITY _LIBCPP_INVOKE_CONSTEXPR +auto +_LIBCPP_INVOKE_NAME (_Fp&& __f, _A0&& __a0) + -> decltype((*_VSTD::forward<_A0>(__a0)).*__f); + +// bullet 5 + +template +_LIBCPP_INLINE_VISIBILITY _LIBCPP_INVOKE_CONSTEXPR +auto +_LIBCPP_INVOKE_NAME (_Fp&& __f, _Args&& ...__args) + -> decltype(_VSTD::forward<_Fp>(__f)(_VSTD::forward<_Args>(__args)...)); + + +#endif // _LIBCPP_DECLARE_INVOKE + +#ifdef _LIBCPP_DEFINE_INVOKE + +// bullets 1 and 2 + +template +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_INVOKE_CONSTEXPR +auto +_LIBCPP_INVOKE_NAME (_Fp&& __f, _A0&& __a0, _Args&& ...__args) + -> decltype((_VSTD::forward<_A0>(__a0).*__f)(_VSTD::forward<_Args>(__args)...)) +{ + return (_VSTD::forward<_A0>(__a0).*__f)(_VSTD::forward<_Args>(__args)...); +} + +template +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_INVOKE_CONSTEXPR +auto +_LIBCPP_INVOKE_NAME (_Fp&& __f, _A0&& __a0, _Args&& ...__args) + -> decltype(((*_VSTD::forward<_A0>(__a0)).*__f)(_VSTD::forward<_Args>(__args)...)) +{ + return ((*_VSTD::forward<_A0>(__a0)).*__f)(_VSTD::forward<_Args>(__args)...); +} + +// bullets 3 and 4 + +template +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_INVOKE_CONSTEXPR +auto +_LIBCPP_INVOKE_NAME (_Fp&& __f, _A0&& __a0) + -> decltype(_VSTD::forward<_A0>(__a0).*__f) +{ + return _VSTD::forward<_A0>(__a0).*__f; +} + +template +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_INVOKE_CONSTEXPR +auto +_LIBCPP_INVOKE_NAME (_Fp&& __f, _A0&& __a0) + -> decltype((*_VSTD::forward<_A0>(__a0)).*__f) +{ + return (*_VSTD::forward<_A0>(__a0)).*__f; +} + +// bullet 5 + +template +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_INVOKE_CONSTEXPR +auto +_LIBCPP_INVOKE_NAME (_Fp&& __f, _Args&& ...__args) + -> decltype(_VSTD::forward<_Fp>(__f)(_VSTD::forward<_Args>(__args)...)) +{ + return _VSTD::forward<_Fp>(__f)(_VSTD::forward<_Args>(__args)...); +} + +#endif // _LIBCPP_DEFINE_INVOKE + +#undef _LIBCPP_INVOKE_CONSTEXPR +#undef _LIBCPP_INVOKE_NAME +#undef _LIBCPP_DECLARE_INVOKE +#undef _LIBCPP_DEFINE_INVOKE Index: include/experimental/tuple =================================================================== --- include/experimental/tuple +++ include/experimental/tuple @@ -56,17 +56,17 @@ #endif template -inline _LIBCPP_INLINE_VISIBILITY +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR decltype(auto) __apply_tuple_impl(_Fn && __f, _Tuple && __t, integer_sequence) { - return _VSTD::__invoke( + return _VSTD::__invoke_constexpr( _VSTD::forward<_Fn>(__f), _VSTD::get<_Id>(_VSTD::forward<_Tuple>(__t))... ); } template -inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR decltype(auto) apply(_Fn && __f, _Tuple && __t) { return _VSTD_LFTS::__apply_tuple_impl( _VSTD::forward<_Fn>(__f), _VSTD::forward<_Tuple>(__t), Index: include/type_traits =================================================================== --- include/type_traits +++ include/type_traits @@ -3429,78 +3429,10 @@ { }; -// __invoke forward declarations - -// fall back - none of the bullets - -template -auto -__invoke(__any, _Args&& ...__args) - -> __nat; - -// bullets 1 and 2 - -template ::type>::value && - is_base_of::type>::_ClassType>::type, - typename remove_reference<_A0>::type>::value - >::type - > -_LIBCPP_INLINE_VISIBILITY -auto -__invoke(_Fp&& __f, _A0&& __a0, _Args&& ...__args) - -> decltype((_VSTD::forward<_A0>(__a0).*__f)(_VSTD::forward<_Args>(__args)...)); - -template ::type>::value && - !is_base_of::type>::_ClassType>::type, - typename remove_reference<_A0>::type>::value - >::type - > -_LIBCPP_INLINE_VISIBILITY -auto -__invoke(_Fp&& __f, _A0&& __a0, _Args&& ...__args) - -> decltype(((*_VSTD::forward<_A0>(__a0)).*__f)(_VSTD::forward<_Args>(__args)...)); - -// bullets 3 and 4 - -template ::type>::value && - is_base_of::type>::_ClassType, - typename remove_reference<_A0>::type>::value - >::type - > -_LIBCPP_INLINE_VISIBILITY -auto -__invoke(_Fp&& __f, _A0&& __a0) - -> decltype(_VSTD::forward<_A0>(__a0).*__f); - -template ::type>::value && - !is_base_of::type>::_ClassType, - typename remove_reference<_A0>::type>::value - >::type - > -_LIBCPP_INLINE_VISIBILITY -auto -__invoke(_Fp&& __f, _A0&& __a0) - -> decltype((*_VSTD::forward<_A0>(__a0)).*__f); - -// bullet 5 - -template -_LIBCPP_INLINE_VISIBILITY -auto -__invoke(_Fp&& __f, _Args&& ...__args) - -> decltype(_VSTD::forward<_Fp>(__f)(_VSTD::forward<_Args>(__args)...)); +#define _LIBCPP_INVOKE_CONSTEXPR +#define _LIBCPP_INVOKE_NAME __invoke +#define _LIBCPP_DECLARE_INVOKE +#include <__invoke> // __invokable Index: test/std/experimental/utilities/tuple/tuple.apply/constexpr_types.pass.cpp =================================================================== --- test/std/experimental/utilities/tuple/tuple.apply/constexpr_types.pass.cpp +++ test/std/experimental/utilities/tuple/tuple.apply/constexpr_types.pass.cpp @@ -9,11 +9,6 @@ // UNSUPPORTED: c++98, c++03, c++11 -// TODO(ericwf) -// constexpr support temporarily reverted due to bug: -// https://llvm.org/bugs/show_bug.cgi?id=23141 -// XFAIL: * - // // template constexpr decltype(auto) apply(F &&, T &&) Index: test/std/experimental/utilities/tuple/tuple.apply/ref_qualifiers.pass.cpp =================================================================== --- test/std/experimental/utilities/tuple/tuple.apply/ref_qualifiers.pass.cpp +++ test/std/experimental/utilities/tuple/tuple.apply/ref_qualifiers.pass.cpp @@ -32,8 +32,6 @@ int main() { -// TODO(ericwf): Re-enable constexpr support -/* { constexpr func_obj f; constexpr std::tuple<> tp; @@ -41,7 +39,6 @@ static_assert(1 == ex::apply(static_cast(f), tp), ""); static_assert(2 == ex::apply(static_cast(f), tp), ""); } -*/ { func_obj f; std::tuple<> tp;