diff --git a/stl/inc/compare b/stl/inc/compare index 9d605211d8..745a89a732 100644 --- a/stl/inc/compare +++ b/stl/inc/compare @@ -641,8 +641,8 @@ inline namespace _Cpos { template concept _Can_fallback_eq_lt = requires(_Ty1& _Left, _Ty2& _Right) { - { _Left == _Right } -> _Implicitly_convertible_to; - { _Left < _Right } -> _Implicitly_convertible_to; + { _Left == _Right } -> _Boolean_testable; + { _Left < _Right } -> _Boolean_testable; }; template @@ -751,9 +751,9 @@ concept _Can_partial_order = requires(_Ty1& _Left, _Ty2& _Right) { _STD partial_ namespace _Compare_partial_order_fallback { template concept _Can_fallback_eq_lt_twice = requires(_Ty1& _Left, _Ty2& _Right) { - { _Left == _Right } -> _Implicitly_convertible_to; - { _Left < _Right } -> _Implicitly_convertible_to; - { _Right < _Left } -> _Implicitly_convertible_to; + { _Left == _Right } -> _Boolean_testable; + { _Left < _Right } -> _Boolean_testable; + { _Right < _Left } -> _Boolean_testable; }; class _Cpo { diff --git a/stl/inc/yvals_core.h b/stl/inc/yvals_core.h index ad10a9d0e8..cf75ae7f19 100644 --- a/stl/inc/yvals_core.h +++ b/stl/inc/yvals_core.h @@ -265,6 +265,7 @@ // P2102R0 Making "Implicit Expression Variations" More Explicit // P2106R0 Range Algorithm Result Types // P2116R0 Removing tuple-Like Protocol Support From Fixed-Extent span +// P2167R3 Improving boolean-testable Usage // P2210R2 Superior String Splitting // P2216R3 std::format Improvements // P2231R1 Completing constexpr In optional And variant diff --git a/tests/std/tests/P0768R1_spaceship_cpos/test.cpp b/tests/std/tests/P0768R1_spaceship_cpos/test.cpp index b681f65a26..e6e6d5ec77 100644 --- a/tests/std/tests/P0768R1_spaceship_cpos/test.cpp +++ b/tests/std/tests/P0768R1_spaceship_cpos/test.cpp @@ -326,6 +326,65 @@ namespace { static_assert(is_same_v, const F<13>>, Partial>); // [cmp.alg]/6.3 } // namespace +// Test strengthened requirements in P2167R3: compare_*_order_fallback CPOs require return types to be boolean-testable. +enum class ResultKind : bool { + Bad, + Good, +}; + +template +struct ComparisonResult { + bool value; + + constexpr operator bool() const noexcept { + return value; + } + + constexpr auto operator!() const noexcept { + if constexpr (K == ResultKind::Good) { + return ComparisonResult{!value}; + } + } +}; + +template +struct BoolTestType { + friend constexpr ComparisonResult operator==(BoolTestType, BoolTestType) noexcept { + return ComparisonResult{true}; + } + + friend constexpr ComparisonResult operator<(BoolTestType, BoolTestType) noexcept { + return ComparisonResult{false}; + } +}; + +static_assert(is_same_v>, + IllFormed>); // [cmp.alg]/4.3 +static_assert(is_same_v>, + IllFormed>); // [cmp.alg]/4.3 +static_assert(is_same_v>, + IllFormed>); // [cmp.alg]/4.3 +static_assert(is_same_v>, + strong_ordering>); // [cmp.alg]/4.3 + +static_assert(is_same_v>, + IllFormed>); // [cmp.alg]/5.3 +static_assert(is_same_v>, + IllFormed>); // [cmp.alg]/5.3 +static_assert(is_same_v>, + IllFormed>); // [cmp.alg]/5.3 +static_assert(is_same_v>, + weak_ordering>); // [cmp.alg]/5.3 + +static_assert(is_same_v>, + IllFormed>); // [cmp.alg]/6.3 +static_assert(is_same_v>, + IllFormed>); // [cmp.alg]/6.3 +static_assert(is_same_v>, + IllFormed>); // [cmp.alg]/6.3 +static_assert(is_same_v>, + partial_ordering>); // [cmp.alg]/6.3 + // Test when the type is comparable through ADL. Part B, exception specifications. static_assert(!NoexceptCpo>); // [cmp.alg]/1.2 static_assert(!NoexceptCpo>); // [cmp.alg]/2.2