[libcxx-commits] [libcxx] 0fa0545 - [libc++] Define an internal API for std::invoke and friends (#116637)
via libcxx-commits
libcxx-commits at lists.llvm.org
Mon Jan 20 09:00:19 PST 2025
Author: Nikolas Klauser
Date: 2025-01-20T18:00:15+01:00
New Revision: 0fa05456a8dc468961c33bd8149b157194672c71
URL: https://github.com/llvm/llvm-project/commit/0fa05456a8dc468961c33bd8149b157194672c71
DIFF: https://github.com/llvm/llvm-project/commit/0fa05456a8dc468961c33bd8149b157194672c71.diff
LOG: [libc++] Define an internal API for std::invoke and friends (#116637)
Currently we're using quite different internal names for the
`std::invoke` family of type traits. This adds a layer around the
current implementation to make it easier to understand when it is used
and makes it easier to define multiple implementations of it.
Added:
Modified:
libcxx/include/__algorithm/make_projected.h
libcxx/include/__algorithm/radix_sort.h
libcxx/include/__functional/bind.h
libcxx/include/__functional/function.h
libcxx/include/__functional/hash.h
libcxx/include/__functional/mem_fn.h
libcxx/include/__functional/reference_wrapper.h
libcxx/include/__hash_table
libcxx/include/__tree
libcxx/include/__type_traits/invoke.h
libcxx/include/__type_traits/result_of.h
libcxx/include/future
libcxx/include/unordered_map
libcxx/include/unordered_set
libcxx/test/libcxx/containers/associative/non_const_comparator.verify.cpp
libcxx/test/libcxx/containers/unord/non_const_comparator.verify.cpp
libcxx/test/libcxx/utilities/function.objects/func.require/bullet_1_2_3.pass.cpp
Removed:
################################################################################
diff --git a/libcxx/include/__algorithm/make_projected.h b/libcxx/include/__algorithm/make_projected.h
index 4b54c504413e12..4a258229387518 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 <class _Tp>
- 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 <class _T1, class _T2>
- 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 95f04a8bb31f65..de6927995e74c8 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 <class _Value, class _Map, class _Radix>
struct __radix_sort_traits {
- using __image_type _LIBCPP_NODEBUG = decay_t<typename __invoke_of<_Map, _Value>::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<typename __invoke_of<_Radix, __image_type>::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 <class _Value, class _Map>
struct __counting_sort_traits {
- using __image_type _LIBCPP_NODEBUG = decay_t<typename __invoke_of<_Map, _Value>::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<typename __invoke_of<_Map, __value_type>::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 e31ad297903557..a3c327ab40cc97 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 <class _Ti, class... _Uj, size_t... _Indx>
-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 <class _Ti, class... _Uj, __enable_if_t<is_bind_expression<_Ti>::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<sizeof...(_Uj)>::type __indices;
return std::__mu_expand(__ti, __uj, __indices());
@@ -130,12 +130,12 @@ struct __mu_return_invokable // false
template <class _Ti, class... _Uj>
struct __mu_return_invokable<true, _Ti, _Uj...> {
- typedef typename __invoke_of<_Ti&, _Uj...>::type type;
+ using type = __invoke_result_t<_Ti&, _Uj...>;
};
template <class _Ti, class... _Uj>
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 <class _Ti, class _TupleUj>
struct __mu_return_impl<_Ti, false, false, true, _TupleUj> {
@@ -168,12 +168,12 @@ struct __is_valid_bind_return {
template <class _Fp, class... _BoundArgs, class _TupleUj>
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 <class _Fp, class... _BoundArgs, class _TupleUj>
struct __is_valid_bind_return<_Fp, const tuple<_BoundArgs...>, _TupleUj> {
- static const bool value = __invokable<_Fp, typename __mu_return<const _BoundArgs, _TupleUj>::type...>::value;
+ static const bool value = __is_invocable_v<_Fp, typename __mu_return<const _BoundArgs, _TupleUj>::type...>;
};
template <class _Fp, class _BoundArgs, class _TupleUj, bool = __is_valid_bind_return<_Fp, _BoundArgs, _TupleUj>::value>
@@ -181,12 +181,12 @@ struct __bind_return;
template <class _Fp, class... _BoundArgs, class _TupleUj>
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 <class _Fp, class... _BoundArgs, class _TupleUj>
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 <class _Fp, class _BoundArgs, size_t... _Indx, class _Args>
@@ -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<base&>(*this), std::forward<_Args>(__args)...);
+ return std::__invoke_r<_Rp>(static_cast<base&>(*this), std::forward<_Args>(__args)...);
}
template <class... _Args,
@@ -266,8 +265,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) const {
- typedef __invoke_void_return_wrapper<_Rp> _Invoker;
- return _Invoker::__call(static_cast<base const&>(*this), std::forward<_Args>(__args)...);
+ return std::__invoke_r<_Rp>(static_cast<base const&>(*this), std::forward<_Args>(__args)...);
}
};
diff --git a/libcxx/include/__functional/function.h b/libcxx/include/__functional/function.h
index 08cb731be97256..2a1293cfcc26ba 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 <class _Fp,
- bool = _And< _IsNotSame<__remove_cvref_t<_Fp>, function>, __invokable<_Fp, _ArgTypes...> >::value>
+ bool = _And<_IsNotSame<__remove_cvref_t<_Fp>, function>, __is_invocable<_Fp, _ArgTypes...> >::value>
struct __callable;
template <class _Fp>
struct __callable<_Fp, true> {
static const bool value =
- is_void<_Rp>::value || __is_core_convertible<typename __invoke_of<_Fp, _ArgTypes...>::type, _Rp>::value;
+ is_void<_Rp>::value || __is_core_convertible<__invoke_result_t<_Fp, _ArgTypes...>, _Rp>::value;
};
template <class _Fp>
struct __callable<_Fp, false> {
diff --git a/libcxx/include/__functional/hash.h b/libcxx/include/__functional/hash.h
index 1f67b6a8377660..28b2635ab12537 100644
--- a/libcxx/include/__functional/hash.h
+++ b/libcxx/include/__functional/hash.h
@@ -522,7 +522,7 @@ template <class _Key, class _Hash>
using __check_hash_requirements _LIBCPP_NODEBUG =
integral_constant<bool,
is_copy_constructible<_Hash>::value && is_move_constructible<_Hash>::value &&
- __invokable_r<size_t, _Hash, _Key const&>::value >;
+ __is_invocable_r_v<size_t, _Hash, _Key const&> >;
template <class _Key, class _Hash = hash<_Key> >
using __has_enabled_hash _LIBCPP_NODEBUG =
diff --git a/libcxx/include/__functional/mem_fn.h b/libcxx/include/__functional/mem_fn.h
index f246edb334bb14..690393988c5a56 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 <class... _ArgTypes>
- _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 typename __invoke_of<const _Tp&, _ArgTypes...>::type
- operator()(_ArgTypes&&... __args) const _NOEXCEPT_(__nothrow_invokable<const _Tp&, _ArgTypes...>::value) {
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 __invoke_result_t<const _Tp&, _ArgTypes...>
+ operator()(_ArgTypes&&... __args) const _NOEXCEPT_(__is_nothrow_invocable_v<const _Tp&, _ArgTypes...>) {
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 a4a66a50cf84ca..d6cd6428f22db2 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 <class... _ArgTypes>
- _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 typename __invoke_of<type&, _ArgTypes...>::type
+ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 __invoke_result_t<type&, _ArgTypes...>
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 7788f687746f0c..9a82ec51daee78 100644
--- a/libcxx/include/__hash_table
+++ b/libcxx/include/__hash_table
@@ -650,9 +650,9 @@ struct __enforce_unordered_container_requirements {
template <class _Key, class _Hash, class _Equal>
#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 dfb205c51e1708..acad6c33f8782a 100644
--- a/libcxx/include/__tree
+++ b/libcxx/include/__tree
@@ -876,7 +876,7 @@ private:
template <class _Tp, class _Compare>
#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 6f641b9a81b853..7206e85766d908 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 <class... Args>
+// decltype(auto) __invoke(Args&&... args) noexcept(noexcept(std::invoke(std::forward<Args>(args...)))) {
+// return std::invoke(std::forward<Args>(args)...);
+// }
+//
+// template <class Ret, class... Args>
+// Ret __invoke_r(Args&&... args) {
+// return std::invoke_r(std::forward<Args>(args)...);
+// }
+//
+// template <class Ret, class Func, class... Args>
+// inline const bool __is_invocable_r_v = is_invocable_r_v<Ret, Func, Args...>;
+//
+// template <class Func, class... Args>
+// struct __is_invocable : is_invocable<Func, Args...> {};
+//
+// template <class Func, class... Args>
+// inline const bool __is_invocable_v = is_invocable_v<Func, Args...>;
+//
+// template <class Func, class... Args>
+// inline const bool __is_nothrow_invocable_v = is_nothrow_invocable_v<Func, Args...>;
+//
+// template <class Func, class... Args>
+// struct __invoke_result : invoke_result {};
+//
+// template <class Func, class... Args>
+// using __invoke_result_t = invoke_result_t<Func, Args...>;
+
_LIBCPP_BEGIN_NAMESPACE_STD
template <class _DecayedFp>
@@ -167,7 +197,7 @@ struct __invokable_r {
static const bool value = type::value;
};
template <class _Fp, class... _Args>
-using __invokable _LIBCPP_NODEBUG = __invokable_r<void, _Fp, _Args...>;
+using __is_invocable _LIBCPP_NODEBUG = __invokable_r<void, _Fp, _Args...>;
template <bool _IsInvokable, bool _IsCVVoid, class _Ret, class _Fp, class... _Args>
struct __nothrow_invokable_r_imp {
@@ -204,11 +234,7 @@ using __nothrow_invokable_r _LIBCPP_NODEBUG =
template <class _Fp, class... _Args>
using __nothrow_invokable _LIBCPP_NODEBUG =
- __nothrow_invokable_r_imp<__invokable<_Fp, _Args...>::value, true, void, _Fp, _Args...>;
-
-template <class _Fp, class... _Args>
-struct __invoke_of
- : public enable_if<__invokable<_Fp, _Args...>::value, typename __invokable_r<void, _Fp, _Args...>::_Result> {};
+ __nothrow_invokable_r_imp<__is_invocable<_Fp, _Args...>::value, true, void, _Fp, _Args...>;
template <class _Ret, bool = is_void<_Ret>::value>
struct __invoke_void_return_wrapper {
@@ -226,31 +252,51 @@ struct __invoke_void_return_wrapper<_Ret, true> {
}
};
+template <class _Func, class... _Args>
+inline const bool __is_invocable_v = __is_invocable<_Func, _Args...>::value;
+
+template <class _Ret, class _Func, class... _Args>
+inline const bool __is_invocable_r_v = __invokable_r<_Ret, _Func, _Args...>::value;
+
+template <class _Func, class... _Args>
+inline const bool __is_nothrow_invocable_v = __nothrow_invokable<_Func, _Args...>::value;
+
+template <class _Func, class... _Args>
+struct __invoke_result
+ : enable_if<__is_invocable_v<_Func, _Args...>, typename __invokable_r<void, _Func, _Args...>::_Result> {};
+
+template <class _Func, class... _Args>
+using __invoke_result_t = typename __invoke_result<_Func, _Args...>::type;
+
+template <class _Ret, class... _Args>
+_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 <class _Fn, class... _Args>
-struct _LIBCPP_TEMPLATE_VIS is_invocable : integral_constant<bool, __invokable<_Fn, _Args...>::value> {};
+struct _LIBCPP_TEMPLATE_VIS is_invocable : bool_constant<__is_invocable_v<_Fn, _Args...>> {};
template <class _Ret, class _Fn, class... _Args>
-struct _LIBCPP_TEMPLATE_VIS is_invocable_r : integral_constant<bool, __invokable_r<_Ret, _Fn, _Args...>::value> {};
+struct _LIBCPP_TEMPLATE_VIS is_invocable_r : bool_constant<__is_invocable_r_v<_Ret, _Fn, _Args...>> {};
template <class _Fn, class... _Args>
-inline constexpr bool is_invocable_v = is_invocable<_Fn, _Args...>::value;
+inline constexpr bool is_invocable_v = __is_invocable_v<_Fn, _Args...>;
template <class _Ret, class _Fn, class... _Args>
-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 <class _Fn, class... _Args>
-struct _LIBCPP_TEMPLATE_VIS is_nothrow_invocable : integral_constant<bool, __nothrow_invokable<_Fn, _Args...>::value> {
-};
+struct _LIBCPP_TEMPLATE_VIS is_nothrow_invocable : bool_constant<__nothrow_invokable<_Fn, _Args...>::value> {};
template <class _Ret, class _Fn, class... _Args>
-struct _LIBCPP_TEMPLATE_VIS is_nothrow_invocable_r
- : integral_constant<bool, __nothrow_invokable_r<_Ret, _Fn, _Args...>::value> {};
+struct _LIBCPP_TEMPLATE_VIS is_nothrow_invocable_r : bool_constant<__nothrow_invokable_r<_Ret, _Fn, _Args...>::value> {
+};
template <class _Fn, class... _Args>
inline constexpr bool is_nothrow_invocable_v = is_nothrow_invocable<_Fn, _Args...>::value;
@@ -259,7 +305,7 @@ template <class _Ret, class _Fn, class... _Args>
inline constexpr bool is_nothrow_invocable_r_v = is_nothrow_invocable_r<_Ret, _Fn, _Args...>::value;
template <class _Fn, class... _Args>
-struct _LIBCPP_TEMPLATE_VIS invoke_result : __invoke_of<_Fn, _Args...> {};
+struct _LIBCPP_TEMPLATE_VIS invoke_result : __invoke_result<_Fn, _Args...> {};
template <class _Fn, class... _Args>
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 73a19447520663..217ca70b4cd207 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 _Callable>
-class _LIBCPP_DEPRECATED_IN_CXX17 result_of;
+struct _LIBCPP_DEPRECATED_IN_CXX17 result_of;
template <class _Fp, class... _Args>
-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 <class _Tp>
diff --git a/libcxx/include/future b/libcxx/include/future
index 72f3ed5ca5d270..bff58faf6ff257 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 <class _Fp, class... _Args>
-[[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI future<typename __invoke_of<__decay_t<_Fp>, __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 <class _Fp, class... _Args>
-[[__nodiscard__]] inline _LIBCPP_HIDE_FROM_ABI future<typename __invoke_of<__decay_t<_Fp>, __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 0ae41384917749..76623d02427525 100644
--- a/libcxx/include/unordered_map
+++ b/libcxx/include/unordered_map
@@ -1842,7 +1842,7 @@ struct __container_traits<unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc> > {
// 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 <class _Key,
@@ -2542,7 +2542,7 @@ struct __container_traits<unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc> >
// 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 87f0a9f438eff2..87d98435329f36 100644
--- a/libcxx/include/unordered_set
+++ b/libcxx/include/unordered_set
@@ -1195,7 +1195,7 @@ struct __container_traits<unordered_set<_Value, _Hash, _Pred, _Alloc> > {
// 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 _Value, class _Hash = hash<_Value>, class _Pred = equal_to<_Value>, class _Alloc = allocator<_Value> >
@@ -1815,7 +1815,7 @@ struct __container_traits<unordered_multiset<_Value, _Hash, _Pred, _Alloc> > {
// 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 3bb59f1920f634..cb7a044abd8c07 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 <map>
#include <set>
-#include <type_traits> // for __invokable
struct BadCompare {
template <class T, class U>
@@ -24,8 +24,8 @@ struct BadCompare {
};
void f() {
- static_assert(!std::__invokable<BadCompare const&, int const&, int const&>::value, "");
- static_assert(std::__invokable<BadCompare&, int const&, int const&>::value, "");
+ static_assert(!std::__is_invocable_v<BadCompare const&, int const&, int const&>, "");
+ static_assert(std::__is_invocable_v<BadCompare&, int const&, int const&>, "");
// expected-warning at set:* 2 {{the specified comparator type does not provide a viable const call operator}}
// expected-warning at 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 a5d529dacef4c4..c3418302d0315b 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 <unordered_set>
#include <unordered_map>
@@ -30,8 +31,8 @@ struct BadEqual {
};
void f() {
- static_assert(!std::__invokable<BadEqual const&, int const&, int const&>::value, "");
- static_assert(std::__invokable<BadEqual&, int const&, int const&>::value, "");
+ static_assert(!std::__is_invocable_v<BadEqual const&, int const&, int const&>, "");
+ static_assert(std::__is_invocable_v<BadEqual&, int const&, int const&>, "");
// expected-warning at unordered_set:* 2 {{the specified comparator type does not provide a viable const call operator}}
// expected-warning at 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 4d1010522f2fb9..48460d1488fd78 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 <class... _ArgTypes>
- constexpr typename std::__invoke_of<Type&, _ArgTypes...>::type operator() (_ArgTypes&&... __args) const {
- return std::__invoke(get(), std::forward<_ArgTypes>(__args)...);
+ constexpr std::__invoke_result_t<Type&, _ArgTypes...> operator()(_ArgTypes&&... __args) const {
+ return std::__invoke(get(), std::forward<_ArgTypes>(__args)...);
}
};
More information about the libcxx-commits
mailing list