diff --git a/libcxx/include/tuple b/libcxx/include/tuple --- a/libcxx/include/tuple +++ b/libcxx/include/tuple @@ -1609,7 +1609,7 @@ constexpr decltype(auto) __apply_tuple_impl(_Fn && __f, _Tuple && __t, __tuple_indices<_Id...>) _LIBCPP_NOEXCEPT_RETURN( - _VSTD::__invoke_constexpr( + _VSTD::__invoke( _VSTD::forward<_Fn>(__f), _VSTD::get<_Id>(_VSTD::forward<_Tuple>(__t))...) ) diff --git a/libcxx/include/type_traits b/libcxx/include/type_traits --- a/libcxx/include/type_traits +++ b/libcxx/include/type_traits @@ -3460,139 +3460,74 @@ template auto __invoke(__any, _Args&& ...__args) -> __nat; -template -auto __invoke_constexpr(__any, _Args&& ...__args) -> __nat; - // bullets 1, 2 and 3 template > inline _LIBCPP_INLINE_VISIBILITY -_LIBCPP_CONSTEXPR_AFTER_CXX17 auto +constexpr auto __invoke(_Fp&& __f, _A0&& __a0, _Args&& ...__args) noexcept(noexcept((static_cast<_A0&&>(__a0).*__f)(static_cast<_Args&&>(__args)...))) -> decltype( (static_cast<_A0&&>(__a0).*__f)(static_cast<_Args&&>(__args)...)) { return (static_cast<_A0&&>(__a0).*__f)(static_cast<_Args&&>(__args)...); } -template > -inline _LIBCPP_INLINE_VISIBILITY -_LIBCPP_CONSTEXPR auto -__invoke_constexpr(_Fp&& __f, _A0&& __a0, _Args&& ...__args) - noexcept(noexcept((static_cast<_A0&&>(__a0).*__f)(static_cast<_Args&&>(__args)...))) - -> decltype( (static_cast<_A0&&>(__a0).*__f)(static_cast<_Args&&>(__args)...)) - { return (static_cast<_A0&&>(__a0).*__f)(static_cast<_Args&&>(__args)...); } - template > inline _LIBCPP_INLINE_VISIBILITY -_LIBCPP_CONSTEXPR_AFTER_CXX17 auto +constexpr auto __invoke(_Fp&& __f, _A0&& __a0, _Args&& ...__args) noexcept(noexcept((__a0.get().*__f)(static_cast<_Args&&>(__args)...))) -> decltype( (__a0.get().*__f)(static_cast<_Args&&>(__args)...)) { return (__a0.get().*__f)(static_cast<_Args&&>(__args)...); } -template > -inline _LIBCPP_INLINE_VISIBILITY -_LIBCPP_CONSTEXPR auto -__invoke_constexpr(_Fp&& __f, _A0&& __a0, _Args&& ...__args) - noexcept(noexcept((__a0.get().*__f)(static_cast<_Args&&>(__args)...))) - -> decltype( (__a0.get().*__f)(static_cast<_Args&&>(__args)...)) - { return (__a0.get().*__f)(static_cast<_Args&&>(__args)...); } - template > inline _LIBCPP_INLINE_VISIBILITY -_LIBCPP_CONSTEXPR_AFTER_CXX17 auto +constexpr auto __invoke(_Fp&& __f, _A0&& __a0, _Args&& ...__args) noexcept(noexcept(((*static_cast<_A0&&>(__a0)).*__f)(static_cast<_Args&&>(__args)...))) -> decltype( ((*static_cast<_A0&&>(__a0)).*__f)(static_cast<_Args&&>(__args)...)) { return ((*static_cast<_A0&&>(__a0)).*__f)(static_cast<_Args&&>(__args)...); } -template > -inline _LIBCPP_INLINE_VISIBILITY -_LIBCPP_CONSTEXPR auto -__invoke_constexpr(_Fp&& __f, _A0&& __a0, _Args&& ...__args) - noexcept(noexcept(((*static_cast<_A0&&>(__a0)).*__f)(static_cast<_Args&&>(__args)...))) - -> decltype( ((*static_cast<_A0&&>(__a0)).*__f)(static_cast<_Args&&>(__args)...)) - { return ((*static_cast<_A0&&>(__a0)).*__f)(static_cast<_Args&&>(__args)...); } - // bullets 4, 5 and 6 template > inline _LIBCPP_INLINE_VISIBILITY -_LIBCPP_CONSTEXPR_AFTER_CXX17 auto +constexpr auto __invoke(_Fp&& __f, _A0&& __a0) noexcept(noexcept(static_cast<_A0&&>(__a0).*__f)) -> decltype( static_cast<_A0&&>(__a0).*__f) { return static_cast<_A0&&>(__a0).*__f; } -template > -inline _LIBCPP_INLINE_VISIBILITY -_LIBCPP_CONSTEXPR auto -__invoke_constexpr(_Fp&& __f, _A0&& __a0) - noexcept(noexcept(static_cast<_A0&&>(__a0).*__f)) - -> decltype( static_cast<_A0&&>(__a0).*__f) - { return static_cast<_A0&&>(__a0).*__f; } - template > inline _LIBCPP_INLINE_VISIBILITY -_LIBCPP_CONSTEXPR_AFTER_CXX17 auto +constexpr auto __invoke(_Fp&& __f, _A0&& __a0) noexcept(noexcept(__a0.get().*__f)) -> decltype( __a0.get().*__f) { return __a0.get().*__f; } -template > -inline _LIBCPP_INLINE_VISIBILITY -_LIBCPP_CONSTEXPR auto -__invoke_constexpr(_Fp&& __f, _A0&& __a0) - noexcept(noexcept(__a0.get().*__f)) - -> decltype( __a0.get().*__f) - { return __a0.get().*__f; } - template > inline _LIBCPP_INLINE_VISIBILITY -_LIBCPP_CONSTEXPR_AFTER_CXX17 auto +constexpr auto __invoke(_Fp&& __f, _A0&& __a0) noexcept(noexcept((*static_cast<_A0&&>(__a0)).*__f)) -> decltype( (*static_cast<_A0&&>(__a0)).*__f) { return (*static_cast<_A0&&>(__a0)).*__f; } -template > -inline _LIBCPP_INLINE_VISIBILITY -_LIBCPP_CONSTEXPR auto -__invoke_constexpr(_Fp&& __f, _A0&& __a0) - noexcept(noexcept((*static_cast<_A0&&>(__a0)).*__f)) - -> decltype( (*static_cast<_A0&&>(__a0)).*__f) - { return (*static_cast<_A0&&>(__a0)).*__f; } - // bullet 7 template inline _LIBCPP_INLINE_VISIBILITY -_LIBCPP_CONSTEXPR_AFTER_CXX17 auto +constexpr auto __invoke(_Fp&& __f, _Args&& ...__args) noexcept(noexcept(static_cast<_Fp&&>(__f)(static_cast<_Args&&>(__args)...))) -> decltype( static_cast<_Fp&&>(__f)(static_cast<_Args&&>(__args)...)) { return static_cast<_Fp&&>(__f)(static_cast<_Args&&>(__args)...); } -template -inline _LIBCPP_INLINE_VISIBILITY -_LIBCPP_CONSTEXPR auto -__invoke_constexpr(_Fp&& __f, _Args&& ...__args) - noexcept(noexcept(static_cast<_Fp&&>(__f)(static_cast<_Args&&>(__args)...))) - -> decltype( static_cast<_Fp&&>(__f)(static_cast<_Args&&>(__args)...)) - { return static_cast<_Fp&&>(__f)(static_cast<_Args&&>(__args)...); } - // __invokable template struct __invokable_r diff --git a/libcxx/include/variant b/libcxx/include/variant --- a/libcxx/include/variant +++ b/libcxx/include/variant @@ -547,7 +547,7 @@ template inline _LIBCPP_INLINE_VISIBILITY static constexpr decltype(auto) __dispatch(_Fp __f, _Vs... __vs) { - return _VSTD::__invoke_constexpr( + return _VSTD::__invoke( static_cast<_Fp>(__f), __access::__base::__get_alt<_Is>(static_cast<_Vs>(__vs))...); } @@ -667,8 +667,8 @@ __std_visit_exhaustive_visitor_check< _Visitor, decltype((_VSTD::forward<_Alts>(__alts).__value))...>(); - return _VSTD::__invoke_constexpr(_VSTD::forward<_Visitor>(__visitor), - _VSTD::forward<_Alts>(__alts).__value...); + return _VSTD::__invoke(_VSTD::forward<_Visitor>(__visitor), + _VSTD::forward<_Alts>(__alts).__value...); } _Visitor&& __visitor; }; @@ -683,12 +683,12 @@ _Visitor, decltype((_VSTD::forward<_Alts>(__alts).__value))...>(); if constexpr (is_void_v<_Rp>) { - _VSTD::__invoke_constexpr(_VSTD::forward<_Visitor>(__visitor), - _VSTD::forward<_Alts>(__alts).__value...); + _VSTD::__invoke(_VSTD::forward<_Visitor>(__visitor), + _VSTD::forward<_Alts>(__alts).__value...); } else { - return _VSTD::__invoke_constexpr(_VSTD::forward<_Visitor>(__visitor), - _VSTD::forward<_Alts>(__alts).__value...); + return _VSTD::__invoke(_VSTD::forward<_Visitor>(__visitor), + _VSTD::forward<_Alts>(__alts).__value...); } } diff --git a/libcxx/test/libcxx/utilities/function.objects/func.require/bullet_1_2_3.pass.cpp b/libcxx/test/libcxx/utilities/function.objects/func.require/bullet_1_2_3.pass.cpp --- a/libcxx/test/libcxx/utilities/function.objects/func.require/bullet_1_2_3.pass.cpp +++ b/libcxx/test/libcxx/utilities/function.objects/func.require/bullet_1_2_3.pass.cpp @@ -244,30 +244,55 @@ #if TEST_STD_VER >= 11 template struct TestCase11 : public TestCaseImp {}; -#endif + +template +struct ReferenceWrapper { + using type = Type; + Type* ptr; + + static void fun(Type&) noexcept; + static void fun(Type&&) = delete; + + template ::value>::type> + constexpr ReferenceWrapper(Type2&& t) noexcept : ptr(&t) {} + + constexpr Type& get() const noexcept { return *ptr; } + constexpr operator Type&() const noexcept { return *ptr; } + + template + constexpr typename std::__invoke_of::type operator() (_ArgTypes&&... __args) const { + return std::__invoke(get(), std::forward<_ArgTypes>(__args)...); + } +}; template -struct DerivedFromRefWrap : public std::reference_wrapper { - DerivedFromRefWrap(Tp& tp) : std::reference_wrapper(tp) {} +struct DerivedFromRefWrap : public ReferenceWrapper { + constexpr DerivedFromRefWrap(Tp& tp) : ReferenceWrapper(tp) {} }; -#if TEST_STD_VER >= 11 -void test_derived_from_ref_wrap() { +TEST_CONSTEXPR_CXX14 bool test_derived_from_ref_wrap() { int x = 42; - std::reference_wrapper r(x); - std::reference_wrapper> r2(r); + ReferenceWrapper r(x); DerivedFromRefWrap d(x); - auto get_fn = &std::reference_wrapper::get; + auto get_fn = &ReferenceWrapper::get; auto& ret = std::__invoke(get_fn, r); - auto& cret = std::__invoke_constexpr(get_fn, r); assert(&ret == &x); - assert(&cret == &x); auto& ret2 = std::__invoke(get_fn, d); - auto& cret2 = std::__invoke_constexpr(get_fn, d); assert(&ret2 == &x); - assert(&cret2 == &x); + + return true; +} + +TEST_CONSTEXPR_CXX20 bool test_reference_wrapper_reference_wrapper() { + int x = 42; + auto get_fn = &std::reference_wrapper::get; + std::reference_wrapper r(x); + std::reference_wrapper> r2(r); auto& ret3 = std::__invoke(get_fn, r2); assert(&ret3 == &x); + + return true; } #endif @@ -366,7 +391,14 @@ TestCase11::run(); test_derived_from_ref_wrap(); + test_reference_wrapper_reference_wrapper(); +#if TEST_STD_VER > 11 + static_assert(test_derived_from_ref_wrap(), ""); #endif +#if TEST_STD_VER > 17 + static_assert(test_reference_wrapper_reference_wrapper(), ""); +#endif +#endif // TEST_STD_VER >= 11 return 0; } diff --git a/libcxx/test/libcxx/utilities/function.objects/func.require/bullet_4_5_6.pass.cpp b/libcxx/test/libcxx/utilities/function.objects/func.require/bullet_4_5_6.pass.cpp --- a/libcxx/test/libcxx/utilities/function.objects/func.require/bullet_4_5_6.pass.cpp +++ b/libcxx/test/libcxx/utilities/function.objects/func.require/bullet_4_5_6.pass.cpp @@ -195,21 +195,9 @@ Expect e = std::__invoke(M, std::forward(obj)); assert(&e == expect); } -#if TEST_STD_VER >= 11 - { - static_assert((std::is_same< - decltype(std::__invoke_constexpr(M, std::forward(obj))), Expect - >::value), ""); - Expect e = std::__invoke_constexpr(M, std::forward(obj)); - assert(&e == expect); - } -#endif } }; - - - int main(int, char**) { TestCase::run(); TestCase::run(); diff --git a/libcxx/test/libcxx/utilities/function.objects/func.require/invoke_helpers.h b/libcxx/test/libcxx/utilities/function.objects/func.require/invoke_helpers.h --- a/libcxx/test/libcxx/utilities/function.objects/func.require/invoke_helpers.h +++ b/libcxx/test/libcxx/utilities/function.objects/func.require/invoke_helpers.h @@ -282,16 +282,6 @@ CallRet ret = std::__invoke(ptr, object_cast(object)); assert(ID::checkCalled(ret)); } -#if TEST_STD_VER >= 11 - { - static_assert((std::is_same< - decltype(std::__invoke_constexpr(ptr, object_cast(object))) - , CallRet>::value), ""); - assert(ID::unchecked_call == false); - CallRet ret = std::__invoke_constexpr(ptr, object_cast(object)); - assert(ID::checkCalled(ret)); - } -#endif } template @@ -304,16 +294,6 @@ CallRet ret = std::__invoke(ptr, object_cast(object), arg_cast(a0)); assert(ID::checkCalled(ret)); } -#if TEST_STD_VER >= 11 - { - static_assert((std::is_same< - decltype(std::__invoke_constexpr(ptr, object_cast(object), arg_cast(a0))) - , CallRet>::value), ""); - assert(ID::unchecked_call == false); - CallRet ret = std::__invoke_constexpr(ptr, object_cast(object), arg_cast(a0)); - assert(ID::checkCalled(ret)); - } -#endif } template @@ -326,16 +306,6 @@ CallRet ret = std::__invoke(ptr, object_cast(object), arg_cast(a0), arg_cast(a1)); assert(ID::checkCalled(ret)); } -#if TEST_STD_VER >= 11 - { - static_assert((std::is_same< - decltype(std::__invoke_constexpr(ptr, object_cast(object), arg_cast(a0), arg_cast(a1))) - , CallRet>::value), ""); - assert(ID::unchecked_call == false); - CallRet ret = std::__invoke_constexpr(ptr, object_cast(object), arg_cast(a0), arg_cast(a1)); - assert(ID::checkCalled(ret)); - } -#endif } template @@ -348,16 +318,6 @@ CallRet ret = std::__invoke(ptr, object_cast(object), arg_cast(a0), arg_cast(a1), arg_cast(a2)); assert(ID::checkCalled(ret)); } -#if TEST_STD_VER >= 11 - { - static_assert((std::is_same< - decltype(std::__invoke_constexpr(ptr, object_cast(object), arg_cast(a0), arg_cast(a1), arg_cast(a2))) - , CallRet>::value), ""); - assert(ID::unchecked_call == false); - CallRet ret = std::__invoke_constexpr(ptr, object_cast(object), arg_cast(a0), arg_cast(a1), arg_cast(a2)); - assert(ID::checkCalled(ret)); - } -#endif } //========================================================================== @@ -373,16 +333,6 @@ CallRet ret = std::__invoke(object_cast(object)); assert(ID::checkCalled(ret)); } -#if TEST_STD_VER >= 11 - { - static_assert((std::is_same< - decltype(std::__invoke_constexpr(object_cast(object))) - , CallRet>::value), ""); - assert(ID::unchecked_call == false); - CallRet ret = std::__invoke_constexpr(object_cast(object)); - assert(ID::checkCalled(ret)); - } -#endif } template @@ -395,16 +345,6 @@ CallRet ret = std::__invoke(object_cast(object), arg_cast(a0)); assert(ID::checkCalled(ret)); } -#if TEST_STD_VER >= 11 - { - static_assert((std::is_same< - decltype(std::__invoke_constexpr(object_cast(object), arg_cast(a0))) - , CallRet>::value), ""); - assert(ID::unchecked_call == false); - CallRet ret = std::__invoke_constexpr(object_cast(object), arg_cast(a0)); - assert(ID::checkCalled(ret)); - } -#endif } template @@ -417,16 +357,6 @@ CallRet ret = std::__invoke(object_cast(object), arg_cast(a0), arg_cast(a1)); assert(ID::checkCalled(ret)); } -#if TEST_STD_VER >= 11 - { - static_assert((std::is_same< - decltype(std::__invoke_constexpr(object_cast(object), arg_cast(a0), arg_cast(a1))) - , CallRet>::value), ""); - assert(ID::unchecked_call == false); - CallRet ret = std::__invoke_constexpr(object_cast(object), arg_cast(a0), arg_cast(a1)); - assert(ID::checkCalled(ret)); - } -#endif } template @@ -439,16 +369,6 @@ CallRet ret = std::__invoke(object_cast(object), arg_cast(a0), arg_cast(a1), arg_cast(a2)); assert(ID::checkCalled(ret)); } -#if TEST_STD_VER >= 11 - { - static_assert((std::is_same< - decltype(std::__invoke_constexpr(object_cast(object), arg_cast(a0), arg_cast(a1), arg_cast(a2))) - , CallRet>::value), ""); - assert(ID::unchecked_call == false); - CallRet ret = std::__invoke_constexpr(object_cast(object), arg_cast(a0), arg_cast(a1), arg_cast(a2)); - assert(ID::checkCalled(ret)); - } -#endif } };