diff --git a/stl/inc/xutility b/stl/inc/xutility index f457e16014c..c8bd9d91daf 100644 --- a/stl/inc/xutility +++ b/stl/inc/xutility @@ -1513,26 +1513,30 @@ 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> -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 +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<_Ty2&>(), _STD declval<_Ty1&>())); + +template +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( + noexcept(_Pred(_Left, _Right)) && _Debug_lt_pred_order_check_noexcept<_Pr, _Ty1, _Ty2>) { const auto _Result = static_cast(_Pred(_Left, _Right)); - if (_Result) { - _STL_VERIFY(!_Pred(_Right, _Left), "invalid comparator"); + + if constexpr (_Enable_debug_lt_pred_order_check<_Pr, _Ty1, _Ty2>) { + 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