From ecbc1efa09936f4ef5af529e770a95a29a4290d3 Mon Sep 17 00:00:00 2001 From: "A. Jiang" Date: Fri, 12 Jul 2024 06:25:56 +0800 Subject: [PATCH] Use `requires`-clauses for `pair` and `tuple` since C++20 (#4819) --- stl/inc/expected | 12 ++---------- stl/inc/tuple | 38 ++++++++++++++++++-------------------- stl/inc/utility | 41 ++++++++++++++++++----------------------- 3 files changed, 38 insertions(+), 53 deletions(-) diff --git a/stl/inc/expected b/stl/inc/expected index 28e74e7118..aad81b7007 100644 --- a/stl/inc/expected +++ b/stl/inc/expected @@ -87,11 +87,7 @@ public: } friend constexpr void swap(unexpected& _Left, unexpected& _Right) noexcept(is_nothrow_swappable_v<_Err>) -#if defined(__clang__) || defined(__EDG__) // TRANSITION, /permissive - requires is_swappable_v<_Err> -#else // ^^^ no workaround / workaround vvv - requires is_swappable<_Err>::value -#endif // ^^^ workaround ^^^ + requires is_swappable<_Err>::value // TRANSITION, /permissive needs ::value { _Left.swap(_Right); } @@ -612,11 +608,7 @@ public: friend constexpr void swap(expected& _Lhs, expected& _Rhs) noexcept( is_nothrow_move_constructible_v<_Ty> && is_nothrow_swappable_v<_Ty> && is_nothrow_move_constructible_v<_Err> && is_nothrow_swappable_v<_Err>) -#if defined(__clang__) || defined(__EDG__) // TRANSITION, /permissive - requires is_swappable_v<_Ty> && is_swappable_v<_Err> -#else // ^^^ no workaround / workaround vvv - requires is_swappable<_Ty>::value && is_swappable<_Err>::value -#endif // ^^^ workaround ^^^ + requires is_swappable<_Ty>::value && is_swappable<_Err>::value // TRANSITION, /permissive needs ::value && is_move_constructible_v<_Ty> && is_move_constructible_v<_Err> && (is_nothrow_move_constructible_v<_Ty> || is_nothrow_move_constructible_v<_Err>) { diff --git a/stl/inc/tuple b/stl/inc/tuple index 79315abf56..0f79be7872 100644 --- a/stl/inc/tuple +++ b/stl/inc/tuple @@ -553,12 +553,11 @@ public: } #if _HAS_CXX23 - template , - _STD _Is_copy_assignable_no_precondition_check...>, - int> = 0> + template + requires conjunction_v<_STD _Is_copy_assignable_no_precondition_check, + _STD _Is_copy_assignable_no_precondition_check...> constexpr const tuple& operator=(_Identity_t _Right) const - noexcept(conjunction_v, + noexcept(conjunction_v, is_nothrow_copy_assignable...>) /* strengthened */ { _Myfirst._Val = _Right._Myfirst._Val; _Get_rest() = _Right._Get_rest(); @@ -578,12 +577,11 @@ public: } #if _HAS_CXX23 - template , - _STD _Is_assignable_no_precondition_check...>, - int> = 0> + template + requires conjunction_v<_STD _Is_assignable_no_precondition_check, + _STD _Is_assignable_no_precondition_check...> constexpr const tuple& operator=(_Identity_t<_Myself&&> _Right) const - noexcept(conjunction_v, + noexcept(conjunction_v, is_nothrow_assignable...>) /* strengthened */ { _Myfirst._Val = _STD forward<_This>(_Right._Myfirst._Val); _Get_rest() = _STD forward<_Mybase>(_Right._Get_rest()); @@ -602,9 +600,8 @@ public: } #if _HAS_CXX23 - template >>, - _STD _Tuple_assignable_val>, - int> = 0> + template + requires (!is_same_v>) && _Tuple_assignable_v constexpr const tuple& operator=(const tuple<_Other...>& _Right) const noexcept(_Tuple_nothrow_assignable_v) /* strengthened */ { _Myfirst._Val = _Right._Myfirst._Val; @@ -624,9 +621,8 @@ public: } #if _HAS_CXX23 - template >>, - _STD _Tuple_assignable_val>, - int> = 0> + template + requires (!is_same_v>) && _Tuple_assignable_v constexpr const tuple& operator=(tuple<_Other...>&& _Right) const noexcept(_Tuple_nothrow_assignable_v) /* strengthened */ { _Myfirst._Val = _STD forward::_This_type>(_Right._Myfirst._Val); @@ -645,8 +641,8 @@ public: } #if _HAS_CXX23 - template , int> = 0> + template + requires _Tuple_assignable_v constexpr const tuple& operator=(const pair<_First, _Second>& _Right) const noexcept(_Tuple_nothrow_assignable_v) /* strengthened */ { _Myfirst._Val = _Right.first; @@ -664,7 +660,8 @@ public: } #if _HAS_CXX23 - template , int> = 0> + template + requires _Tuple_assignable_v constexpr const tuple& operator=(pair<_First, _Second>&& _Right) const noexcept(_Tuple_nothrow_assignable_v) /* strengthened */ { _Myfirst._Val = _STD forward<_First>(_Right.first); @@ -896,7 +893,8 @@ _CONSTEXPR20 void swap(tuple<_Types...>& _Left, tuple<_Types...>& _Right) noexce } #if _HAS_CXX23 -_EXPORT_STD template ...>, int> = 0> +_EXPORT_STD template + requires conjunction_v...> constexpr void swap(const tuple<_Types...>& _Left, const tuple<_Types...>& _Right) noexcept( noexcept(_Left.swap(_Right))) { _Left.swap(_Right); diff --git a/stl/inc/utility b/stl/inc/utility index 0a5ea0e810..df825320fd 100644 --- a/stl/inc/utility +++ b/stl/inc/utility @@ -261,8 +261,8 @@ struct pair { // store a pair of values pair(pair&&) = default; #if _HAS_CXX23 - template , is_constructible<_Ty2, _Other2&>>, int> = 0> + template + requires is_constructible_v<_Ty1, _Other1&> && is_constructible_v<_Ty2, _Other2&> constexpr explicit(!conjunction_v, is_convertible<_Other2&, _Ty2>>) pair(pair<_Other1, _Other2>& _Right) noexcept( is_nothrow_constructible_v<_Ty1, _Other1&> && is_nothrow_constructible_v<_Ty2, _Other2&>) // strengthened @@ -286,9 +286,8 @@ struct pair { // store a pair of values : first(_STD forward<_Other1>(_Right.first)), second(_STD forward<_Other2>(_Right.second)) {} #if _HAS_CXX23 - template , is_constructible<_Ty2, const _Other2>>, int> = - 0> + template + requires is_constructible_v<_Ty1, const _Other1> && is_constructible_v<_Ty2, const _Other2> constexpr explicit(!conjunction_v, is_convertible>) pair(const pair<_Other1, _Other2>&& _Right) noexcept( is_nothrow_constructible_v<_Ty1, const _Other1> @@ -335,10 +334,9 @@ struct pair { // store a pair of values } #if _HAS_CXX23 - template , - _Is_copy_assignable_no_precondition_check>, - int> = 0> + template + requires _Is_copy_assignable_unchecked_v + && _Is_copy_assignable_unchecked_v constexpr const pair& operator=(_Identity_t _Right) const noexcept(conjunction_v, is_nothrow_copy_assignable>) /* strengthened */ { @@ -360,10 +358,9 @@ struct pair { // store a pair of values } #if _HAS_CXX23 - template , - _Is_assignable_no_precondition_check>, - int> = 0> + template + requires _Is_assignable_no_precondition_check::value + && _Is_assignable_no_precondition_check::value constexpr const pair& operator=(_Identity_t<_Myself&&> _Right) const noexcept(conjunction_v, is_nothrow_assignable>) /* strengthened */ { @@ -386,10 +383,9 @@ struct pair { // store a pair of values } #if _HAS_CXX23 - template >>, - is_assignable, is_assignable>, - int> = 0> + template + requires (!is_same_v>) + && is_assignable_v && is_assignable_v constexpr const pair& operator=(const pair<_Other1, _Other2>& _Right) const noexcept(is_nothrow_assignable_v && is_nothrow_assignable_v) /* strengthened */ { @@ -411,10 +407,9 @@ struct pair { // store a pair of values } #if _HAS_CXX23 - template >>, is_assignable, - is_assignable>, - int> = 0> + template + requires (!is_same_v>) + && is_assignable_v && is_assignable_v constexpr const pair& operator=(pair<_Other1, _Other2>&& _Right) const noexcept(is_nothrow_assignable_v && is_nothrow_assignable_v) /* strengthened */ { @@ -481,8 +476,8 @@ _CONSTEXPR20 void swap(pair<_Ty1, _Ty2>& _Left, pair<_Ty1, _Ty2>& _Right) noexce } #if _HAS_CXX23 -_EXPORT_STD template && is_swappable_v, int> = 0> +_EXPORT_STD template + requires is_swappable::value && is_swappable::value // TRANSITION, /permissive needs ::value constexpr void swap(const pair<_Ty1, _Ty2>& _Left, const pair<_Ty1, _Ty2>& _Right) noexcept( noexcept(_Left.swap(_Right))) { _Left.swap(_Right);