From ab422393e77be11a6b2cf15c176ebbdf61ef6e20 Mon Sep 17 00:00:00 2001 From: Alex Guteniev Date: Sat, 20 Apr 2024 08:05:31 +0300 Subject: [PATCH 1/9] Replace `enable_if_t` in `_Debug_lt_pred`... ...with `if constexpr` and variable template --- stl/inc/xutility | 24 +++++++++++------------- 1 file changed, 11 insertions(+), 13 deletions(-) diff --git a/stl/inc/xutility b/stl/inc/xutility index f457e16014..eb8ab9294e 100644 --- a/stl/inc/xutility +++ b/stl/inc/xutility @@ -1513,26 +1513,24 @@ using _Unwrap_enum_t = typename _Unwrap_enum<_Elem>::type; #define _DEBUG_ORDER_SET_UNWRAPPED(otherIter, first, last, pred) \ _STD _Debug_order_set_unchecked(first, last, pred) -template , _Remove_cvref_t<_Ty2>>, int> = 0> +// test if _Pred(_Left, _Right) and _Pred is strict weak ordering, when the arguments are the cv-same-type +template +constexpr bool _Enable_debug_lt_pred_order_check = is_same_v<_Remove_cvref_t<_Ty1>, _Remove_cvref_t<_Ty2>>; + +template > constexpr bool _Debug_lt_pred(_Pr&& _Pred, _Ty1&& _Left, _Ty2&& _Right) noexcept( - noexcept(_Pred(_Left, _Right)) && noexcept(_Pred(_Right, _Left))) { - // test if _Pred(_Left, _Right) and _Pred is strict weak ordering, when the arguments are the cv-same-type + noexcept(_Pred(_Left, _Right)) && (!_Order_check || noexcept(_Pred(_Right, _Left)))) { const auto _Result = static_cast(_Pred(_Left, _Right)); - if (_Result) { - _STL_VERIFY(!_Pred(_Right, _Left), "invalid comparator"); + + if constexpr (_Order_check) { + if (_Result) { + _STL_VERIFY(!_Pred(_Right, _Left), "invalid comparator"); + } } return _Result; } -template , _Remove_cvref_t<_Ty2>>, int> = 0> -constexpr bool _Debug_lt_pred(_Pr&& _Pred, _Ty1&& _Left, _Ty2&& _Right) noexcept(noexcept(_Pred(_Left, _Right))) { - // test if _Pred(_Left, _Right); no debug checks as the types differ - return static_cast(_Pred(_Left, _Right)); -} - template constexpr void _Debug_order_unchecked(_InIt _First, _Sentinel _Last, _Pr&& _Pred) { // test if range is ordered by predicate From 783b666d45a897c0c1234d87f1c64f2502d3d6df Mon Sep 17 00:00:00 2001 From: Alex Guteniev Date: Sat, 20 Apr 2024 08:48:59 +0300 Subject: [PATCH 2/9] Fix up `noexcept` to use specialization --- stl/inc/xutility | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/stl/inc/xutility b/stl/inc/xutility index eb8ab9294e..9373b80b5b 100644 --- a/stl/inc/xutility +++ b/stl/inc/xutility @@ -1513,13 +1513,19 @@ using _Unwrap_enum_t = typename _Unwrap_enum<_Elem>::type; #define _DEBUG_ORDER_SET_UNWRAPPED(otherIter, first, last, pred) \ _STD _Debug_order_set_unchecked(first, last, pred) -// test if _Pred(_Left, _Right) and _Pred is strict weak ordering, when the arguments are the cv-same-type template constexpr bool _Enable_debug_lt_pred_order_check = is_same_v<_Remove_cvref_t<_Ty1>, _Remove_cvref_t<_Ty2>>; +template > +constexpr bool _Debug_lt_pred_order_check_noexcept = noexcept(declval<_Pr>()(declval<_Ty1>(), declval<_Ty2>())); + +template +constexpr bool _Debug_lt_pred_order_check_noexcept<_Pr, _Ty1, _Ty2, true> = noexcept( + declval<_Pr>()(declval<_Ty1>(), declval<_Ty2>()))&& noexcept(declval<_Pr>()(declval<_Ty2>(), declval<_Ty1>())); + template > constexpr bool _Debug_lt_pred(_Pr&& _Pred, _Ty1&& _Left, _Ty2&& _Right) noexcept( - noexcept(_Pred(_Left, _Right)) && (!_Order_check || noexcept(_Pred(_Right, _Left)))) { + _Debug_lt_pred_order_check_noexcept<_Pr, _Ty1, _Ty2>) { const auto _Result = static_cast(_Pred(_Left, _Right)); if constexpr (_Order_check) { From ace32f2552fa250bd86629d926567d40aa4e33f4 Mon Sep 17 00:00:00 2001 From: Alex Guteniev Date: Sat, 20 Apr 2024 10:54:43 +0300 Subject: [PATCH 3/9] eliminate extra template param --- stl/inc/xutility | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/stl/inc/xutility b/stl/inc/xutility index 9373b80b5b..5979555228 100644 --- a/stl/inc/xutility +++ b/stl/inc/xutility @@ -1523,12 +1523,12 @@ template constexpr bool _Debug_lt_pred_order_check_noexcept<_Pr, _Ty1, _Ty2, true> = noexcept( declval<_Pr>()(declval<_Ty1>(), declval<_Ty2>()))&& noexcept(declval<_Pr>()(declval<_Ty2>(), declval<_Ty1>())); -template > +template constexpr bool _Debug_lt_pred(_Pr&& _Pred, _Ty1&& _Left, _Ty2&& _Right) noexcept( _Debug_lt_pred_order_check_noexcept<_Pr, _Ty1, _Ty2>) { const auto _Result = static_cast(_Pred(_Left, _Right)); - if constexpr (_Order_check) { + if constexpr (_Enable_debug_lt_pred_order_check<_Pr, _Ty1, _Ty2>) { if (_Result) { _STL_VERIFY(!_Pred(_Right, _Left), "invalid comparator"); } From 31a3cdeb1067a9064a746200235c0bf9966b0d53 Mon Sep 17 00:00:00 2001 From: "Stephan T. Lavavej" Date: Sat, 20 Apr 2024 13:59:00 -0700 Subject: [PATCH 4/9] Qualify `_STD declval`. --- stl/inc/xutility | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/stl/inc/xutility b/stl/inc/xutility index 5979555228..59deb70fa0 100644 --- a/stl/inc/xutility +++ b/stl/inc/xutility @@ -1517,11 +1517,13 @@ template constexpr bool _Enable_debug_lt_pred_order_check = is_same_v<_Remove_cvref_t<_Ty1>, _Remove_cvref_t<_Ty2>>; template > -constexpr bool _Debug_lt_pred_order_check_noexcept = noexcept(declval<_Pr>()(declval<_Ty1>(), declval<_Ty2>())); +constexpr bool _Debug_lt_pred_order_check_noexcept = + noexcept(_STD declval<_Pr>()(_STD declval<_Ty1>(), _STD declval<_Ty2>())); template -constexpr bool _Debug_lt_pred_order_check_noexcept<_Pr, _Ty1, _Ty2, true> = noexcept( - declval<_Pr>()(declval<_Ty1>(), declval<_Ty2>()))&& noexcept(declval<_Pr>()(declval<_Ty2>(), declval<_Ty1>())); +constexpr bool _Debug_lt_pred_order_check_noexcept<_Pr, _Ty1, _Ty2, true> = + noexcept(_STD declval<_Pr>()(_STD declval<_Ty1>(), _STD declval<_Ty2>()))&& noexcept( + _STD declval<_Pr>()(_STD declval<_Ty2>(), _STD declval<_Ty1>())); template constexpr bool _Debug_lt_pred(_Pr&& _Pred, _Ty1&& _Left, _Ty2&& _Right) noexcept( From c6784ab635c5c3a73b1ec2c3b5d742bb51dffe72 Mon Sep 17 00:00:00 2001 From: "Stephan T. Lavavej" Date: Sat, 20 Apr 2024 13:59:58 -0700 Subject: [PATCH 5/9] Use the primary template for the `true` branch. --- stl/inc/xutility | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/stl/inc/xutility b/stl/inc/xutility index 59deb70fa0..4686ba30c4 100644 --- a/stl/inc/xutility +++ b/stl/inc/xutility @@ -1517,13 +1517,12 @@ template constexpr bool _Enable_debug_lt_pred_order_check = is_same_v<_Remove_cvref_t<_Ty1>, _Remove_cvref_t<_Ty2>>; template > -constexpr bool _Debug_lt_pred_order_check_noexcept = - noexcept(_STD declval<_Pr>()(_STD declval<_Ty1>(), _STD declval<_Ty2>())); +constexpr bool _Debug_lt_pred_order_check_noexcept = noexcept(_STD declval<_Pr>()(_STD declval<_Ty1>(), + _STD declval<_Ty2>()))&& noexcept(_STD declval<_Pr>()(_STD declval<_Ty2>(), _STD declval<_Ty1>())); template -constexpr bool _Debug_lt_pred_order_check_noexcept<_Pr, _Ty1, _Ty2, true> = - noexcept(_STD declval<_Pr>()(_STD declval<_Ty1>(), _STD declval<_Ty2>()))&& noexcept( - _STD declval<_Pr>()(_STD declval<_Ty2>(), _STD declval<_Ty1>())); +constexpr bool _Debug_lt_pred_order_check_noexcept<_Pr, _Ty1, _Ty2, false> = + noexcept(_STD declval<_Pr>()(_STD declval<_Ty1>(), _STD declval<_Ty2>())); template constexpr bool _Debug_lt_pred(_Pr&& _Pred, _Ty1&& _Left, _Ty2&& _Right) noexcept( From d76cfe9f505cd247362453e1c925a29a971945fc Mon Sep 17 00:00:00 2001 From: "Stephan T. Lavavej" Date: Sat, 20 Apr 2024 14:01:26 -0700 Subject: [PATCH 6/9] Use empty comments to improve clang-formatting. --- stl/inc/xutility | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/stl/inc/xutility b/stl/inc/xutility index 4686ba30c4..7f113566b7 100644 --- a/stl/inc/xutility +++ b/stl/inc/xutility @@ -1517,8 +1517,9 @@ template constexpr bool _Enable_debug_lt_pred_order_check = is_same_v<_Remove_cvref_t<_Ty1>, _Remove_cvref_t<_Ty2>>; template > -constexpr bool _Debug_lt_pred_order_check_noexcept = noexcept(_STD declval<_Pr>()(_STD declval<_Ty1>(), - _STD declval<_Ty2>()))&& noexcept(_STD declval<_Pr>()(_STD declval<_Ty2>(), _STD declval<_Ty1>())); +constexpr bool _Debug_lt_pred_order_check_noexcept = // + noexcept(_STD declval<_Pr>()(_STD declval<_Ty1>(), _STD declval<_Ty2>())) // + && noexcept(_STD declval<_Pr>()(_STD declval<_Ty2>(), _STD declval<_Ty1>())); template constexpr bool _Debug_lt_pred_order_check_noexcept<_Pr, _Ty1, _Ty2, false> = From ab21ace03e319f83afa8dd31032dfd2bf7066937 Mon Sep 17 00:00:00 2001 From: "Stephan T. Lavavej" Date: Sat, 20 Apr 2024 14:07:43 -0700 Subject: [PATCH 7/9] Use `declval` to match the lvalue invocations. --- stl/inc/xutility | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/stl/inc/xutility b/stl/inc/xutility index 7f113566b7..d42a23f48e 100644 --- a/stl/inc/xutility +++ b/stl/inc/xutility @@ -1518,12 +1518,12 @@ constexpr bool _Enable_debug_lt_pred_order_check = is_same_v<_Remove_cvref_t<_Ty template > constexpr bool _Debug_lt_pred_order_check_noexcept = // - noexcept(_STD declval<_Pr>()(_STD declval<_Ty1>(), _STD declval<_Ty2>())) // - && noexcept(_STD declval<_Pr>()(_STD declval<_Ty2>(), _STD declval<_Ty1>())); + noexcept(_STD declval<_Pr&>()(_STD declval<_Ty1&>(), _STD declval<_Ty2&>())) // + && noexcept(_STD declval<_Pr&>()(_STD declval<_Ty2&>(), _STD declval<_Ty1&>())); template constexpr bool _Debug_lt_pred_order_check_noexcept<_Pr, _Ty1, _Ty2, false> = - noexcept(_STD declval<_Pr>()(_STD declval<_Ty1>(), _STD declval<_Ty2>())); + noexcept(_STD declval<_Pr&>()(_STD declval<_Ty1&>(), _STD declval<_Ty2&>())); template constexpr bool _Debug_lt_pred(_Pr&& _Pred, _Ty1&& _Left, _Ty2&& _Right) noexcept( From bd80ce5ad692c7a6add493a4e89087f023642672 Mon Sep 17 00:00:00 2001 From: "Stephan T. Lavavej" Date: Sat, 20 Apr 2024 14:11:25 -0700 Subject: [PATCH 8/9] Pre-existing: Mark `_Debug_lt_pred` as `_NODISCARD`. --- stl/inc/xutility | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/stl/inc/xutility b/stl/inc/xutility index d42a23f48e..c6675fb276 100644 --- a/stl/inc/xutility +++ b/stl/inc/xutility @@ -1526,7 +1526,7 @@ constexpr bool _Debug_lt_pred_order_check_noexcept<_Pr, _Ty1, _Ty2, false> = noexcept(_STD declval<_Pr&>()(_STD declval<_Ty1&>(), _STD declval<_Ty2&>())); template -constexpr bool _Debug_lt_pred(_Pr&& _Pred, _Ty1&& _Left, _Ty2&& _Right) noexcept( +_NODISCARD constexpr bool _Debug_lt_pred(_Pr&& _Pred, _Ty1&& _Left, _Ty2&& _Right) noexcept( _Debug_lt_pred_order_check_noexcept<_Pr, _Ty1, _Ty2>) { const auto _Result = static_cast(_Pred(_Left, _Right)); From 1425f222d8090199173e3713706f439f32d4bac5 Mon Sep 17 00:00:00 2001 From: "Stephan T. Lavavej" Date: Sat, 20 Apr 2024 14:34:21 -0700 Subject: [PATCH 9/9] Extract repetition: We can always say `noexcept(_Pred(_Left, _Right))` --- stl/inc/xutility | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/stl/inc/xutility b/stl/inc/xutility index c6675fb276..c8bd9d91da 100644 --- a/stl/inc/xutility +++ b/stl/inc/xutility @@ -1517,17 +1517,15 @@ template constexpr bool _Enable_debug_lt_pred_order_check = is_same_v<_Remove_cvref_t<_Ty1>, _Remove_cvref_t<_Ty2>>; template > -constexpr bool _Debug_lt_pred_order_check_noexcept = // - noexcept(_STD declval<_Pr&>()(_STD declval<_Ty1&>(), _STD declval<_Ty2&>())) // - && noexcept(_STD declval<_Pr&>()(_STD declval<_Ty2&>(), _STD declval<_Ty1&>())); +constexpr bool _Debug_lt_pred_order_check_noexcept = + noexcept(_STD declval<_Pr&>()(_STD declval<_Ty2&>(), _STD declval<_Ty1&>())); template -constexpr bool _Debug_lt_pred_order_check_noexcept<_Pr, _Ty1, _Ty2, false> = - noexcept(_STD declval<_Pr&>()(_STD declval<_Ty1&>(), _STD declval<_Ty2&>())); +constexpr bool _Debug_lt_pred_order_check_noexcept<_Pr, _Ty1, _Ty2, false> = true; template _NODISCARD constexpr bool _Debug_lt_pred(_Pr&& _Pred, _Ty1&& _Left, _Ty2&& _Right) noexcept( - _Debug_lt_pred_order_check_noexcept<_Pr, _Ty1, _Ty2>) { + noexcept(_Pred(_Left, _Right)) && _Debug_lt_pred_order_check_noexcept<_Pr, _Ty1, _Ty2>) { const auto _Result = static_cast(_Pred(_Left, _Right)); if constexpr (_Enable_debug_lt_pred_order_check<_Pr, _Ty1, _Ty2>) {