aboutsummaryrefslogtreecommitdiff
path: root/include/type_traits
diff options
context:
space:
mode:
Diffstat (limited to 'include/type_traits')
-rw-r--r--include/type_traits113
1 files changed, 81 insertions, 32 deletions
diff --git a/include/type_traits b/include/type_traits
index 6c111abfd1e8..60b5dec5b839 100644
--- a/include/type_traits
+++ b/include/type_traits
@@ -137,25 +137,25 @@ namespace std
template <class Base, class Derived> struct is_base_of;
template <class From, class To> struct is_convertible;
- template <class, class R = void> struct is_callable; // not defined
- template <class Fn, class... ArgTypes, class R>
- struct is_callable<Fn(ArgTypes...), R>;
+ template <class Fn, class... ArgTypes> struct is_invocable;
+ template <class R, class Fn, class... ArgTypes> struct is_invocable_r;
- template <class, class R = void> struct is_nothrow_callable; // not defined
- template <class Fn, class... ArgTypes, class R>
- struct is_nothrow_callable<Fn(ArgTypes...), R>;
+ template <class Fn, class... ArgTypes> struct is_nothrow_invocable;
+ template <class R, class Fn, class... ArgTypes> struct is_nothrow_invocable_r;
// Alignment properties and transformations:
template <class T> struct alignment_of;
template <size_t Len, size_t Align = most_stringent_alignment_requirement>
struct aligned_storage;
template <size_t Len, class... Types> struct aligned_union;
+ template <class T> struct remove_cvref; // C++20
template <class T> struct decay;
template <class... T> struct common_type;
template <class T> struct underlying_type;
template <class> class result_of; // undefined
template <class Fn, class... ArgTypes> class result_of<Fn(ArgTypes...)>;
+ template <class Fn, class... ArgTypes> struct invoke_result; // C++17
// const-volatile modifications:
template <class T>
@@ -203,6 +203,8 @@ namespace std
template <std::size_t Len, class... Types>
using aligned_union_t = typename aligned_union<Len,Types...>::type; // C++14
template <class T>
+ using remove_cvref_t = typename remove_cvref<T>::type; // C++20
+ template <class T>
using decay_t = typename decay<T>::type; // C++14
template <bool b, class T=void>
using enable_if_t = typename enable_if<b,T>::type; // C++14
@@ -212,8 +214,10 @@ namespace std
using common_type_t = typename common_type<T...>::type; // C++14
template <class T>
using underlying_type_t = typename underlying_type<T>::type; // C++14
- template <class F, class... ArgTypes>
- using result_of_t = typename result_of<F(ArgTypes...)>::type; // C++14
+ template <class T>
+ using result_of_t = typename result_of<T>::type; // C++14
+ template <class Fn, class... ArgTypes>
+ using invoke_result_t = typename invoke_result<Fn, ArgTypes...>::type; // C++17
template <class...>
using void_t = void; // C++17
@@ -367,10 +371,14 @@ namespace std
= is_base_of<Base, Derived>::value; // C++17
template <class From, class To> constexpr bool is_convertible_v
= is_convertible<From, To>::value; // C++17
- template <class T, class R = void> constexpr bool is_callable_v
- = is_callable<T, R>::value; // C++17
- template <class T, class R = void> constexpr bool is_nothrow_callable_v
- = is_nothrow_callable<T, R>::value; // C++17
+ template <class Fn, class... ArgTypes> constexpr bool is_invocable_v
+ = is_invocable<Fn, ArgTypes...>::value; // C++17
+ template <class R, class Fn, class... ArgTypes> constexpr bool is_invocable_r_v
+ = is_invocable_r<R, Fn, ArgTypes...>::value; // C++17
+ template <class Fn, class... ArgTypes> constexpr bool is_nothrow_invocable_v
+ = is_nothrow_invocable<Fn, ArgTypes...>::value; // C++17
+ template <class R, class Fn, class... ArgTypes> constexpr bool is_nothrow_invocable_r_v
+ = is_nothrow_invocable_r<R, Fn, ArgTypes...>::value; // C++17
// [meta.logical], logical operator traits:
template<class... B> struct conjunction; // C++17
@@ -1141,6 +1149,17 @@ template <class _Tp, class _Up>
struct __is_same_uncvref : is_same<typename __uncvref<_Tp>::type,
typename __uncvref<_Up>::type> {};
+#if _LIBCPP_STD_VER > 17
+// aligned_union - same as __uncvref
+template <class _Tp>
+struct remove_cvref {
+ using type = remove_cv_t<remove_reference_t<_Tp>>;
+};
+
+template <class _Tp> using remove_cvref_t = typename remove_cvref<_Tp>::type;
+#endif
+
+
struct __any
{
__any(...);
@@ -4388,6 +4407,13 @@ using __nothrow_invokable_r =
>;
template <class _Fp, class ..._Args>
+using __nothrow_invokable =
+ __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,
@@ -4409,30 +4435,48 @@ template <class _Tp> using result_of_t = typename result_of<_Tp>::type;
#if _LIBCPP_STD_VER > 14
-// is_callable
+// invoke_result
+
+template <class _Fn, class... _Args>
+struct _LIBCPP_TEMPLATE_VIS invoke_result
+ : __invoke_of<_Fn, _Args...>
+{
+};
+
+template <class _Fn, class... _Args>
+using invoke_result_t = typename invoke_result<_Fn, _Args...>::type;
+
+// is_invocable
-template <class _Fn, class _Ret = void>
-struct _LIBCPP_TEMPLATE_VIS is_callable;
+template <class _Fn, class ..._Args>
+struct _LIBCPP_TEMPLATE_VIS is_invocable
+ : integral_constant<bool, __invokable<_Fn, _Args...>::value> {};
-template <class _Fn, class ..._Args, class _Ret>
-struct _LIBCPP_TEMPLATE_VIS is_callable<_Fn(_Args...), _Ret>
+template <class _Ret, class _Fn, class ..._Args>
+struct _LIBCPP_TEMPLATE_VIS is_invocable_r
: integral_constant<bool, __invokable_r<_Ret, _Fn, _Args...>::value> {};
-template <class _Fn, class _Ret = void>
-constexpr bool is_callable_v = is_callable<_Fn, _Ret>::value;
+template <class _Fn, class ..._Args>
+constexpr bool is_invocable_v = is_invocable<_Fn, _Args...>::value;
+
+template <class _Ret, class _Fn, class ..._Args>
+constexpr bool is_invocable_r_v = is_invocable_r<_Ret, _Fn, _Args...>::value;
// is_nothrow_callable
-template <class _Fn, class _Ret = void>
-struct _LIBCPP_TEMPLATE_VIS is_nothrow_callable;
+template <class _Fn, class ..._Args>
+struct _LIBCPP_TEMPLATE_VIS is_nothrow_invocable
+ : integral_constant<bool, __nothrow_invokable<_Fn, _Args...>::value> {};
-template <class _Fn, class ..._Args, class _Ret>
-struct _LIBCPP_TEMPLATE_VIS is_nothrow_callable<_Fn(_Args...), _Ret>
- : integral_constant<bool, __nothrow_invokable_r<_Ret, _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> {};
+
+template <class _Fn, class ..._Args>
+constexpr bool is_nothrow_invocable_v = is_nothrow_invocable<_Fn, _Args...>::value;
-template <class _Fn, class _Ret = void>
-constexpr bool is_nothrow_callable_v = is_nothrow_callable<_Fn, _Ret>::value;
+template <class _Ret, class _Fn, class ..._Args>
+constexpr bool is_nothrow_invocable_r_v = is_nothrow_invocable_r<_Ret, _Fn, _Args...>::value;
#endif // _LIBCPP_STD_VER > 14
@@ -4638,6 +4682,11 @@ long long __convert_to_integral(long long __val) { return __val; }
inline _LIBCPP_INLINE_VISIBILITY
unsigned long long __convert_to_integral(unsigned long long __val) {return __val; }
+template<typename _Fp>
+inline _LIBCPP_INLINE_VISIBILITY
+typename enable_if<is_floating_point<_Fp>::value, long long>::type
+ __convert_to_integral(_Fp __val) { return __val; }
+
#ifndef _LIBCPP_HAS_NO_INT128
inline _LIBCPP_INLINE_VISIBILITY
__int128_t __convert_to_integral(__int128_t __val) { return __val; }
@@ -4747,26 +4796,26 @@ namespace std // purposefully not versioned
template <class _Integer>
constexpr typename enable_if<is_integral_v<_Integer>, byte>::type &
operator<<=(byte& __lhs, _Integer __shift) noexcept
- { return __lhs = byte(static_cast<unsigned char>(__lhs) << __shift); }
+ { return __lhs = __lhs << __shift; }
template <class _Integer>
constexpr typename enable_if<is_integral_v<_Integer>, byte>::type
operator<< (byte __lhs, _Integer __shift) noexcept
- { return byte(static_cast<unsigned char>(__lhs) << __shift); }
+ { return static_cast<byte>(static_cast<unsigned char>(static_cast<unsigned int>(__lhs) << __shift)); }
template <class _Integer>
constexpr typename enable_if<is_integral_v<_Integer>, byte>::type &
operator>>=(byte& __lhs, _Integer __shift) noexcept
- { return __lhs = byte(static_cast<unsigned char>(__lhs) >> __shift); }
+ { return __lhs = __lhs >> __shift; }
template <class _Integer>
constexpr typename enable_if<is_integral_v<_Integer>, byte>::type
operator>> (byte __lhs, _Integer __shift) noexcept
- { return byte(static_cast<unsigned char>(__lhs) >> __shift); }
+ { return static_cast<byte>(static_cast<unsigned char>(static_cast<unsigned int>(__lhs) >> __shift)); }
template <class _Integer>
constexpr typename enable_if<is_integral_v<_Integer>, _Integer>::type
- to_integer(byte __b) noexcept { return _Integer(__b); }
+ to_integer(byte __b) noexcept { return static_cast<_Integer>(__b); }
}
#endif