From 6d9db293f16d0e5591084ee41cbda575ceb02550 Mon Sep 17 00:00:00 2001 From: Nikolas Klauser Date: Mon, 18 Nov 2024 16:06:31 +0100 Subject: [PATCH] [libc++] Define an internal API for std::invoke and friends --- libcxx/include/__algorithm/make_projected.h | 12 +-- libcxx/include/__algorithm/radix_sort.h | 8 +- libcxx/include/__functional/bind.h | 22 +++--- libcxx/include/__functional/function.h | 10 +-- libcxx/include/__functional/hash.h | 2 +- libcxx/include/__functional/mem_fn.h | 4 +- .../include/__functional/reference_wrapper.h | 2 +- libcxx/include/__hash_table | 4 +- libcxx/include/__tree | 2 +- libcxx/include/__type_traits/invoke.h | 76 +++++++++++++++---- libcxx/include/__type_traits/result_of.h | 4 +- libcxx/include/future | 6 +- libcxx/include/unordered_map | 4 +- libcxx/include/unordered_set | 4 +- .../non_const_comparator.verify.cpp | 6 +- .../unord/non_const_comparator.verify.cpp | 5 +- .../func.require/bullet_1_2_3.pass.cpp | 4 +- 17 files changed, 109 insertions(+), 66 deletions(-) diff --git a/libcxx/include/__algorithm/make_projected.h b/libcxx/include/__algorithm/make_projected.h index 4b54c504413e1..4a25822938751 100644 --- a/libcxx/include/__algorithm/make_projected.h +++ b/libcxx/include/__algorithm/make_projected.h @@ -34,16 +34,16 @@ struct _ProjectedPred { : __pred(__pred_arg), __proj(__proj_arg) {} template - typename __invoke_of<_Pred&, decltype(std::__invoke(std::declval<_Proj&>(), std::declval<_Tp>()))>::type - _LIBCPP_CONSTEXPR _LIBCPP_HIDE_FROM_ABI - operator()(_Tp&& __v) const { + __invoke_result_t<_Pred&, decltype(std::__invoke(std::declval<_Proj&>(), std::declval<_Tp>()))> _LIBCPP_CONSTEXPR + _LIBCPP_HIDE_FROM_ABI + operator()(_Tp&& __v) const { return std::__invoke(__pred, std::__invoke(__proj, std::forward<_Tp>(__v))); } template - typename __invoke_of<_Pred&, - decltype(std::__invoke(std::declval<_Proj&>(), std::declval<_T1>())), - decltype(std::__invoke(std::declval<_Proj&>(), std::declval<_T2>()))>::type _LIBCPP_CONSTEXPR + __invoke_result_t<_Pred&, + decltype(std::__invoke(std::declval<_Proj&>(), std::declval<_T1>())), + decltype(std::__invoke(std::declval<_Proj&>(), std::declval<_T2>()))> _LIBCPP_CONSTEXPR _LIBCPP_HIDE_FROM_ABI operator()(_T1&& __lhs, _T2&& __rhs) const { return std::__invoke( diff --git a/libcxx/include/__algorithm/radix_sort.h b/libcxx/include/__algorithm/radix_sort.h index 95f04a8bb31f6..de6927995e74c 100644 --- a/libcxx/include/__algorithm/radix_sort.h +++ b/libcxx/include/__algorithm/radix_sort.h @@ -88,10 +88,10 @@ __partial_sum_max(_InputIterator __first, _InputIterator __last, _OutputIterator template struct __radix_sort_traits { - using __image_type _LIBCPP_NODEBUG = decay_t::type>; + using __image_type _LIBCPP_NODEBUG = decay_t<__invoke_result_t<_Map, _Value>>; static_assert(is_unsigned<__image_type>::value); - using __radix_type _LIBCPP_NODEBUG = decay_t::type>; + using __radix_type _LIBCPP_NODEBUG = decay_t<__invoke_result_t<_Radix, __image_type>>; static_assert(is_integral<__radix_type>::value); static constexpr auto __radix_value_range = numeric_limits<__radix_type>::max() + 1; @@ -101,7 +101,7 @@ struct __radix_sort_traits { template struct __counting_sort_traits { - using __image_type _LIBCPP_NODEBUG = decay_t::type>; + using __image_type _LIBCPP_NODEBUG = decay_t<__invoke_result_t<_Map, _Value>>; static_assert(is_unsigned<__image_type>::value); static constexpr const auto __value_range = numeric_limits<__image_type>::max() + 1; @@ -158,7 +158,7 @@ _LIBCPP_HIDE_FROM_ABI bool __collect_impl( using __value_type = __iter_value_type<_ForwardIterator>; constexpr auto __radix_value_range = __radix_sort_traits<__value_type, _Map, _Radix>::__radix_value_range; - auto __previous = numeric_limits::type>::min(); + auto __previous = numeric_limits<__invoke_result_t<_Map, __value_type>>::min(); auto __is_sorted = true; std::for_each(__first, __last, [&__counters, &__map, &__radix, &__previous, &__is_sorted](const auto& __value) { auto __current = __map(__value); diff --git a/libcxx/include/__functional/bind.h b/libcxx/include/__functional/bind.h index e31ad29790355..a3c327ab40cc9 100644 --- a/libcxx/include/__functional/bind.h +++ b/libcxx/include/__functional/bind.h @@ -82,13 +82,13 @@ inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _Tp& __mu(reference_w } template -inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 typename __invoke_of<_Ti&, _Uj...>::type +inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 __invoke_result_t<_Ti&, _Uj...> __mu_expand(_Ti& __ti, tuple<_Uj...>& __uj, __tuple_indices<_Indx...>) { return __ti(std::forward<_Uj>(std::get<_Indx>(__uj))...); } template ::value, int> = 0> -inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 typename __invoke_of<_Ti&, _Uj...>::type +inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 __invoke_result_t<_Ti&, _Uj...> __mu(_Ti& __ti, tuple<_Uj...>& __uj) { typedef typename __make_tuple_indices::type __indices; return std::__mu_expand(__ti, __uj, __indices()); @@ -130,12 +130,12 @@ struct __mu_return_invokable // false template struct __mu_return_invokable { - typedef typename __invoke_of<_Ti&, _Uj...>::type type; + using type = __invoke_result_t<_Ti&, _Uj...>; }; template struct __mu_return_impl<_Ti, false, true, false, tuple<_Uj...> > - : public __mu_return_invokable<__invokable<_Ti&, _Uj...>::value, _Ti, _Uj...> {}; + : public __mu_return_invokable<__is_invocable_v<_Ti&, _Uj...>, _Ti, _Uj...> {}; template struct __mu_return_impl<_Ti, false, false, true, _TupleUj> { @@ -168,12 +168,12 @@ struct __is_valid_bind_return { template struct __is_valid_bind_return<_Fp, tuple<_BoundArgs...>, _TupleUj> { - static const bool value = __invokable<_Fp, typename __mu_return<_BoundArgs, _TupleUj>::type...>::value; + static const bool value = __is_invocable_v<_Fp, typename __mu_return<_BoundArgs, _TupleUj>::type...>; }; template struct __is_valid_bind_return<_Fp, const tuple<_BoundArgs...>, _TupleUj> { - static const bool value = __invokable<_Fp, typename __mu_return::type...>::value; + static const bool value = __is_invocable_v<_Fp, typename __mu_return::type...>; }; template ::value> @@ -181,12 +181,12 @@ struct __bind_return; template struct __bind_return<_Fp, tuple<_BoundArgs...>, _TupleUj, true> { - typedef typename __invoke_of< _Fp&, typename __mu_return< _BoundArgs, _TupleUj >::type... >::type type; + using type = __invoke_result_t< _Fp&, typename __mu_return< _BoundArgs, _TupleUj >::type... >; }; template struct __bind_return<_Fp, const tuple<_BoundArgs...>, _TupleUj, true> { - typedef typename __invoke_of< _Fp&, typename __mu_return< const _BoundArgs, _TupleUj >::type... >::type type; + using type = __invoke_result_t< _Fp&, typename __mu_return< const _BoundArgs, _TupleUj >::type... >; }; template @@ -256,8 +256,7 @@ class __bind_r : public __bind<_Fp, _BoundArgs...> { is_void<_Rp>::value, int> = 0> _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 result_type operator()(_Args&&... __args) { - typedef __invoke_void_return_wrapper<_Rp> _Invoker; - return _Invoker::__call(static_cast(*this), std::forward<_Args>(__args)...); + return std::__invoke_r<_Rp>(static_cast(*this), std::forward<_Args>(__args)...); } template { is_void<_Rp>::value, int> = 0> _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 result_type operator()(_Args&&... __args) const { - typedef __invoke_void_return_wrapper<_Rp> _Invoker; - return _Invoker::__call(static_cast(*this), std::forward<_Args>(__args)...); + return std::__invoke_r<_Rp>(static_cast(*this), std::forward<_Args>(__args)...); } }; diff --git a/libcxx/include/__functional/function.h b/libcxx/include/__functional/function.h index 08cb731be9725..2a1293cfcc26b 100644 --- a/libcxx/include/__functional/function.h +++ b/libcxx/include/__functional/function.h @@ -164,8 +164,7 @@ class __alloc_func<_Fp, _Ap, _Rp(_ArgTypes...)> { : __func_(std::move(__f)), __alloc_(std::move(__a)) {} _LIBCPP_HIDE_FROM_ABI _Rp operator()(_ArgTypes&&... __arg) { - typedef __invoke_void_return_wrapper<_Rp> _Invoker; - return _Invoker::__call(__func_, std::forward<_ArgTypes>(__arg)...); + return std::__invoke_r<_Rp>(__func_, std::forward<_ArgTypes>(__arg)...); } _LIBCPP_HIDE_FROM_ABI __alloc_func* __clone() const { @@ -213,8 +212,7 @@ class __default_alloc_func<_Fp, _Rp(_ArgTypes...)> { _LIBCPP_HIDE_FROM_ABI explicit __default_alloc_func(const _Target& __f) : __f_(__f) {} _LIBCPP_HIDE_FROM_ABI _Rp operator()(_ArgTypes&&... __arg) { - typedef __invoke_void_return_wrapper<_Rp> _Invoker; - return _Invoker::__call(__f_, std::forward<_ArgTypes>(__arg)...); + return std::__invoke_r<_Rp>(__f_, std::forward<_ArgTypes>(__arg)...); } _LIBCPP_HIDE_FROM_ABI __default_alloc_func* __clone() const { @@ -841,12 +839,12 @@ class _LIBCPP_TEMPLATE_VIS function<_Rp(_ArgTypes...)> __func __f_; template , function>, __invokable<_Fp, _ArgTypes...> >::value> + bool = _And<_IsNotSame<__remove_cvref_t<_Fp>, function>, __is_invocable<_Fp, _ArgTypes...> >::value> struct __callable; template struct __callable<_Fp, true> { static const bool value = - is_void<_Rp>::value || __is_core_convertible::type, _Rp>::value; + is_void<_Rp>::value || __is_core_convertible<__invoke_result_t<_Fp, _ArgTypes...>, _Rp>::value; }; template struct __callable<_Fp, false> { diff --git a/libcxx/include/__functional/hash.h b/libcxx/include/__functional/hash.h index 1f67b6a837766..28b2635ab1253 100644 --- a/libcxx/include/__functional/hash.h +++ b/libcxx/include/__functional/hash.h @@ -522,7 +522,7 @@ template using __check_hash_requirements _LIBCPP_NODEBUG = integral_constant::value && is_move_constructible<_Hash>::value && - __invokable_r::value >; + __is_invocable_r_v >; template > using __has_enabled_hash _LIBCPP_NODEBUG = diff --git a/libcxx/include/__functional/mem_fn.h b/libcxx/include/__functional/mem_fn.h index f246edb334bb1..690393988c5a5 100644 --- a/libcxx/include/__functional/mem_fn.h +++ b/libcxx/include/__functional/mem_fn.h @@ -36,8 +36,8 @@ class __mem_fn : public __weak_result_type<_Tp> { // invoke template - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 typename __invoke_of::type - operator()(_ArgTypes&&... __args) const _NOEXCEPT_(__nothrow_invokable::value) { + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 __invoke_result_t + operator()(_ArgTypes&&... __args) const _NOEXCEPT_(__is_nothrow_invocable_v) { return std::__invoke(__f_, std::forward<_ArgTypes>(__args)...); } }; diff --git a/libcxx/include/__functional/reference_wrapper.h b/libcxx/include/__functional/reference_wrapper.h index a4a66a50cf84c..d6cd6428f22db 100644 --- a/libcxx/include/__functional/reference_wrapper.h +++ b/libcxx/include/__functional/reference_wrapper.h @@ -57,7 +57,7 @@ class _LIBCPP_TEMPLATE_VIS reference_wrapper : public __weak_result_type<_Tp> { // invoke template - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 typename __invoke_of::type + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 __invoke_result_t operator()(_ArgTypes&&... __args) const #if _LIBCPP_STD_VER >= 17 // Since is_nothrow_invocable requires C++17 LWG3764 is not backported diff --git a/libcxx/include/__hash_table b/libcxx/include/__hash_table index 7788f687746f0..9a82ec51daee7 100644 --- a/libcxx/include/__hash_table +++ b/libcxx/include/__hash_table @@ -650,9 +650,9 @@ struct __enforce_unordered_container_requirements { template #ifndef _LIBCPP_CXX03_LANG -_LIBCPP_DIAGNOSE_WARNING(!__invokable<_Equal const&, _Key const&, _Key const&>::value, +_LIBCPP_DIAGNOSE_WARNING(!__is_invocable_v<_Equal const&, _Key const&, _Key const&>, "the specified comparator type does not provide a viable const call operator") -_LIBCPP_DIAGNOSE_WARNING(!__invokable<_Hash const&, _Key const&>::value, +_LIBCPP_DIAGNOSE_WARNING(!__is_invocable_v<_Hash const&, _Key const&>, "the specified hash functor does not provide a viable const call operator") #endif typename __enforce_unordered_container_requirements<_Key, _Hash, _Equal>::type diff --git a/libcxx/include/__tree b/libcxx/include/__tree index dfb205c51e170..acad6c33f8782 100644 --- a/libcxx/include/__tree +++ b/libcxx/include/__tree @@ -876,7 +876,7 @@ private: template #ifndef _LIBCPP_CXX03_LANG -_LIBCPP_DIAGNOSE_WARNING(!__invokable<_Compare const&, _Tp const&, _Tp const&>::value, +_LIBCPP_DIAGNOSE_WARNING(!__is_invocable_v<_Compare const&, _Tp const&, _Tp const&>, "the specified comparator type does not provide a viable const call operator") #endif int __diagnose_non_const_comparator(); diff --git a/libcxx/include/__type_traits/invoke.h b/libcxx/include/__type_traits/invoke.h index 6f641b9a81b85..7206e85766d90 100644 --- a/libcxx/include/__type_traits/invoke.h +++ b/libcxx/include/__type_traits/invoke.h @@ -29,6 +29,36 @@ # pragma GCC system_header #endif +// This file defines the following libc++-internal API (back-ported to C++03): +// +// template +// decltype(auto) __invoke(Args&&... args) noexcept(noexcept(std::invoke(std::forward(args...)))) { +// return std::invoke(std::forward(args)...); +// } +// +// template +// Ret __invoke_r(Args&&... args) { +// return std::invoke_r(std::forward(args)...); +// } +// +// template +// inline const bool __is_invocable_r_v = is_invocable_r_v; +// +// template +// struct __is_invocable : is_invocable {}; +// +// template +// inline const bool __is_invocable_v = is_invocable_v; +// +// template +// inline const bool __is_nothrow_invocable_v = is_nothrow_invocable_v; +// +// template +// struct __invoke_result : invoke_result {}; +// +// template +// using __invoke_result_t = invoke_result_t; + _LIBCPP_BEGIN_NAMESPACE_STD template @@ -167,7 +197,7 @@ struct __invokable_r { static const bool value = type::value; }; template -using __invokable _LIBCPP_NODEBUG = __invokable_r; +using __is_invocable _LIBCPP_NODEBUG = __invokable_r; template struct __nothrow_invokable_r_imp { @@ -204,11 +234,7 @@ using __nothrow_invokable_r _LIBCPP_NODEBUG = template using __nothrow_invokable _LIBCPP_NODEBUG = - __nothrow_invokable_r_imp<__invokable<_Fp, _Args...>::value, true, void, _Fp, _Args...>; - -template -struct __invoke_of - : public enable_if<__invokable<_Fp, _Args...>::value, typename __invokable_r::_Result> {}; + __nothrow_invokable_r_imp<__is_invocable<_Fp, _Args...>::value, true, void, _Fp, _Args...>; template ::value> struct __invoke_void_return_wrapper { @@ -226,31 +252,51 @@ struct __invoke_void_return_wrapper<_Ret, true> { } }; +template +inline const bool __is_invocable_v = __is_invocable<_Func, _Args...>::value; + +template +inline const bool __is_invocable_r_v = __invokable_r<_Ret, _Func, _Args...>::value; + +template +inline const bool __is_nothrow_invocable_v = __nothrow_invokable<_Func, _Args...>::value; + +template +struct __invoke_result + : enable_if<__is_invocable_v<_Func, _Args...>, typename __invokable_r::_Result> {}; + +template +using __invoke_result_t = typename __invoke_result<_Func, _Args...>::type; + +template +_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _Ret __invoke_r(_Args&&... __args) { + return __invoke_void_return_wrapper<_Ret>::__call(std::forward<_Args>(__args)...); +} + #if _LIBCPP_STD_VER >= 17 // is_invocable template -struct _LIBCPP_TEMPLATE_VIS is_invocable : integral_constant::value> {}; +struct _LIBCPP_TEMPLATE_VIS is_invocable : bool_constant<__is_invocable_v<_Fn, _Args...>> {}; template -struct _LIBCPP_TEMPLATE_VIS is_invocable_r : integral_constant::value> {}; +struct _LIBCPP_TEMPLATE_VIS is_invocable_r : bool_constant<__is_invocable_r_v<_Ret, _Fn, _Args...>> {}; template -inline constexpr bool is_invocable_v = is_invocable<_Fn, _Args...>::value; +inline constexpr bool is_invocable_v = __is_invocable_v<_Fn, _Args...>; template -inline constexpr bool is_invocable_r_v = is_invocable_r<_Ret, _Fn, _Args...>::value; +inline constexpr bool is_invocable_r_v = __is_invocable_r_v<_Ret, _Fn, _Args...>; // is_nothrow_invocable template -struct _LIBCPP_TEMPLATE_VIS is_nothrow_invocable : integral_constant::value> { -}; +struct _LIBCPP_TEMPLATE_VIS is_nothrow_invocable : bool_constant<__nothrow_invokable<_Fn, _Args...>::value> {}; template -struct _LIBCPP_TEMPLATE_VIS is_nothrow_invocable_r - : integral_constant::value> {}; +struct _LIBCPP_TEMPLATE_VIS is_nothrow_invocable_r : bool_constant<__nothrow_invokable_r<_Ret, _Fn, _Args...>::value> { +}; template inline constexpr bool is_nothrow_invocable_v = is_nothrow_invocable<_Fn, _Args...>::value; @@ -259,7 +305,7 @@ template inline constexpr bool is_nothrow_invocable_r_v = is_nothrow_invocable_r<_Ret, _Fn, _Args...>::value; template -struct _LIBCPP_TEMPLATE_VIS invoke_result : __invoke_of<_Fn, _Args...> {}; +struct _LIBCPP_TEMPLATE_VIS invoke_result : __invoke_result<_Fn, _Args...> {}; template using invoke_result_t = typename invoke_result<_Fn, _Args...>::type; diff --git a/libcxx/include/__type_traits/result_of.h b/libcxx/include/__type_traits/result_of.h index 73a1944752066..217ca70b4cd20 100644 --- a/libcxx/include/__type_traits/result_of.h +++ b/libcxx/include/__type_traits/result_of.h @@ -22,10 +22,10 @@ _LIBCPP_BEGIN_NAMESPACE_STD #if _LIBCPP_STD_VER <= 17 || defined(_LIBCPP_ENABLE_CXX20_REMOVED_TYPE_TRAITS) template -class _LIBCPP_DEPRECATED_IN_CXX17 result_of; +struct _LIBCPP_DEPRECATED_IN_CXX17 result_of; template -class _LIBCPP_TEMPLATE_VIS result_of<_Fp(_Args...)> : public __invoke_of<_Fp, _Args...> {}; +struct _LIBCPP_TEMPLATE_VIS result_of<_Fp(_Args...)> : __invoke_result<_Fp, _Args...> {}; # if _LIBCPP_STD_VER >= 14 template diff --git a/libcxx/include/future b/libcxx/include/future index 72f3ed5ca5d27..bff58faf6ff25 100644 --- a/libcxx/include/future +++ b/libcxx/include/future @@ -1840,7 +1840,7 @@ class _LIBCPP_HIDDEN __async_func { tuple<_Fp, _Args...> __f_; public: - typedef typename __invoke_of<_Fp, _Args...>::type _Rp; + using _Rp = __invoke_result_t<_Fp, _Args...>; _LIBCPP_HIDE_FROM_ABI explicit __async_func(_Fp&& __f, _Args&&... __args) : __f_(std::move(__f), std::move(__args)...) {} @@ -1864,7 +1864,7 @@ inline _LIBCPP_HIDE_FROM_ABI bool __does_policy_contain(launch __policy, launch } template -[[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI future, __decay_t<_Args>...>::type> +[[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI future<__invoke_result_t<__decay_t<_Fp>, __decay_t<_Args>...> > async(launch __policy, _Fp&& __f, _Args&&... __args) { typedef __async_func<__decay_t<_Fp>, __decay_t<_Args>...> _BF; typedef typename _BF::_Rp _Rp; @@ -1889,7 +1889,7 @@ async(launch __policy, _Fp&& __f, _Args&&... __args) { } template -[[__nodiscard__]] inline _LIBCPP_HIDE_FROM_ABI future, __decay_t<_Args>...>::type> +[[__nodiscard__]] inline _LIBCPP_HIDE_FROM_ABI future<__invoke_result_t<__decay_t<_Fp>, __decay_t<_Args>...> > async(_Fp&& __f, _Args&&... __args) { return std::async(launch::any, std::forward<_Fp>(__f), std::forward<_Args>(__args)...); } diff --git a/libcxx/include/unordered_map b/libcxx/include/unordered_map index 0ae4138491774..76623d0242752 100644 --- a/libcxx/include/unordered_map +++ b/libcxx/include/unordered_map @@ -1842,7 +1842,7 @@ struct __container_traits > { // other than the container's hash function from within an insert or emplace function // inserting a single element, the insertion has no effect. static _LIBCPP_CONSTEXPR const bool __emplacement_has_strong_exception_safety_guarantee = - __nothrow_invokable<_Hash, const _Key&>::value; + __is_nothrow_invocable_v<_Hash, const _Key&>; }; template > // other than the container's hash function from within an insert or emplace function // inserting a single element, the insertion has no effect. static _LIBCPP_CONSTEXPR const bool __emplacement_has_strong_exception_safety_guarantee = - __nothrow_invokable<_Hash, const _Key&>::value; + __is_nothrow_invocable_v<_Hash, const _Key&>; }; _LIBCPP_END_NAMESPACE_STD diff --git a/libcxx/include/unordered_set b/libcxx/include/unordered_set index 87f0a9f438eff..87d98435329f3 100644 --- a/libcxx/include/unordered_set +++ b/libcxx/include/unordered_set @@ -1195,7 +1195,7 @@ struct __container_traits > { // other than the container's hash function from within an insert or emplace function // inserting a single element, the insertion has no effect. static _LIBCPP_CONSTEXPR const bool __emplacement_has_strong_exception_safety_guarantee = - __nothrow_invokable<_Hash, const _Value&>::value; + __is_nothrow_invocable_v<_Hash, const _Value&>; }; template , class _Pred = equal_to<_Value>, class _Alloc = allocator<_Value> > @@ -1815,7 +1815,7 @@ struct __container_traits > { // other than the container's hash function from within an insert or emplace function // inserting a single element, the insertion has no effect. static _LIBCPP_CONSTEXPR const bool __emplacement_has_strong_exception_safety_guarantee = - __nothrow_invokable<_Hash, const _Value&>::value; + __is_nothrow_invocable_v<_Hash, const _Value&>; }; _LIBCPP_END_NAMESPACE_STD diff --git a/libcxx/test/libcxx/containers/associative/non_const_comparator.verify.cpp b/libcxx/test/libcxx/containers/associative/non_const_comparator.verify.cpp index 3bb59f1920f63..cb7a044abd8c0 100644 --- a/libcxx/test/libcxx/containers/associative/non_const_comparator.verify.cpp +++ b/libcxx/test/libcxx/containers/associative/non_const_comparator.verify.cpp @@ -12,9 +12,9 @@ // Test that libc++ generates a warning diagnostic when the container is // provided a non-const callable comparator. +#include <__type_traits/invoke.h> #include #include -#include // for __invokable struct BadCompare { template @@ -24,8 +24,8 @@ struct BadCompare { }; void f() { - static_assert(!std::__invokable::value, ""); - static_assert(std::__invokable::value, ""); + static_assert(!std::__is_invocable_v, ""); + static_assert(std::__is_invocable_v, ""); // expected-warning@set:* 2 {{the specified comparator type does not provide a viable const call operator}} // expected-warning@map:* 2 {{the specified comparator type does not provide a viable const call operator}} diff --git a/libcxx/test/libcxx/containers/unord/non_const_comparator.verify.cpp b/libcxx/test/libcxx/containers/unord/non_const_comparator.verify.cpp index a5d529dacef4c..c3418302d0315 100644 --- a/libcxx/test/libcxx/containers/unord/non_const_comparator.verify.cpp +++ b/libcxx/test/libcxx/containers/unord/non_const_comparator.verify.cpp @@ -12,6 +12,7 @@ // Test that libc++ generates a warning diagnostic when the container is // provided a non-const callable comparator or a non-const hasher. +#include <__type_traits/invoke.h> #include #include @@ -30,8 +31,8 @@ struct BadEqual { }; void f() { - static_assert(!std::__invokable::value, ""); - static_assert(std::__invokable::value, ""); + static_assert(!std::__is_invocable_v, ""); + static_assert(std::__is_invocable_v, ""); // expected-warning@unordered_set:* 2 {{the specified comparator type does not provide a viable const call operator}} // expected-warning@unordered_map:* 2 {{the specified comparator type does not provide a viable const call operator}} 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 index 4d1010522f2fb..48460d1488fd7 100644 --- 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 @@ -262,8 +262,8 @@ struct ReferenceWrapper { 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)...); + constexpr std::__invoke_result_t operator()(_ArgTypes&&... __args) const { + return std::__invoke(get(), std::forward<_ArgTypes>(__args)...); } };