From 97e51bdeb8341e40e0cac12c995db5ed405ac98d Mon Sep 17 00:00:00 2001 From: Daniel Winsor Date: Fri, 19 Feb 2021 15:23:14 -0800 Subject: [PATCH 1/6] Spaceship changes to smart_ptrs --- stl/inc/memory | 44 ++++++++++++++++++++++ tests/std/tests/P1614R2_spaceship/test.cpp | 20 ++++++++++ tests/tr1/tests/memory1/test.cpp | 3 ++ 3 files changed, 67 insertions(+) diff --git a/stl/inc/memory b/stl/inc/memory index 279effbcc6b..cdf13e83566 100644 --- a/stl/inc/memory +++ b/stl/inc/memory @@ -1791,6 +1791,13 @@ _NODISCARD bool operator==(const shared_ptr<_Ty1>& _Left, const shared_ptr<_Ty2> return _Left.get() == _Right.get(); } +#if _HAS_CXX20 +template +_NODISCARD strong_ordering operator<=>(const shared_ptr<_Ty1>& _Left, const shared_ptr<_Ty2>& _Right) noexcept { + return _Left.get() <=> _Right.get(); +} + +#else // ^^^ _HAS_CXX20 / !_HAS_CXX20 VVV template _NODISCARD bool operator!=(const shared_ptr<_Ty1>& _Left, const shared_ptr<_Ty2>& _Right) noexcept { return _Left.get() != _Right.get(); @@ -1815,12 +1822,20 @@ template _NODISCARD bool operator<=(const shared_ptr<_Ty1>& _Left, const shared_ptr<_Ty2>& _Right) noexcept { return _Left.get() <= _Right.get(); } +#endif // ^^^ !_HAS_CXX20 ^^^ template _NODISCARD bool operator==(const shared_ptr<_Ty>& _Left, nullptr_t) noexcept { return _Left.get() == nullptr; } +#ifdef __cpp_lib_concepts +template +_NODISCARD strong_ordering operator<=>(const shared_ptr<_Ty>& _Left, nullptr_t) noexcept { + return compare_three_way()(_Left.get(), static_cast::element_type*>(nullptr)); +} + +#else // ^^^ __cpp_lib_concepts / !__cpp_lib_concepts VVV template _NODISCARD bool operator==(nullptr_t, const shared_ptr<_Ty>& _Right) noexcept { return nullptr == _Right.get(); @@ -1875,6 +1890,7 @@ template _NODISCARD bool operator<=(nullptr_t, const shared_ptr<_Ty>& _Right) noexcept { return static_cast::element_type*>(nullptr) <= _Right.get(); } +#endif // ^^^ !__cpp_lib_concepts ^^^ template basic_ostream<_Elem, _Traits>& operator<<(basic_ostream<_Elem, _Traits>& _Out, const shared_ptr<_Ty>& _Px) { @@ -3415,10 +3431,12 @@ _NODISCARD bool operator==(const unique_ptr<_Ty1, _Dx1>& _Left, const unique_ptr return _Left.get() == _Right.get(); } +#if !_HAS_CXX20 template _NODISCARD bool operator!=(const unique_ptr<_Ty1, _Dx1>& _Left, const unique_ptr<_Ty2, _Dx2>& _Right) { return !(_Left == _Right); } +#endif // !_HAS_CXX20 template _NODISCARD bool operator<(const unique_ptr<_Ty1, _Dx1>& _Left, const unique_ptr<_Ty2, _Dx2>& _Right) { @@ -3443,11 +3461,25 @@ _NODISCARD bool operator<=(const unique_ptr<_Ty1, _Dx1>& _Left, const unique_ptr return !(_Right < _Left); } +#ifdef __cpp_lib_concepts +// clang-format off +template + requires three_way_comparable_with::pointer, + typename unique_ptr<_Ty2, _Dx2>::pointer> +_NODISCARD compare_three_way_result_t::pointer, + typename unique_ptr<_Ty2, _Dx2>::pointer> + operator<=>(const unique_ptr<_Ty1, _Dx1>& _Left, const unique_ptr<_Ty2, _Dx2>& _Right) { + // clang-format on + return _Left.get() <=> _Right.get(); +} +#endif // __cpp_lib_concepts + template _NODISCARD bool operator==(const unique_ptr<_Ty, _Dx>& _Left, nullptr_t) noexcept { return !_Left; } +#if !_HAS_CXX20 template _NODISCARD bool operator==(nullptr_t, const unique_ptr<_Ty, _Dx>& _Right) noexcept { return !_Right; @@ -3462,6 +3494,7 @@ template _NODISCARD bool operator!=(nullptr_t _Left, const unique_ptr<_Ty, _Dx>& _Right) noexcept { return !(_Left == _Right); } +#endif // !_HAS_CXX20 template _NODISCARD bool operator<(const unique_ptr<_Ty, _Dx>& _Left, nullptr_t _Right) { @@ -3505,6 +3538,17 @@ _NODISCARD bool operator<=(nullptr_t _Left, const unique_ptr<_Ty, _Dx>& _Right) return !(_Right < _Left); } +#ifdef __cpp_lib_concepts +// clang-format off +template + requires three_way_comparable::pointer> +_NODISCARD compare_three_way_result_t::pointer> operator<=>( + const unique_ptr<_Ty, _Dx>& _Left, nullptr_t) { + // clang-format on + return compare_three_way()(_Left.get(), static_cast::pointer>(nullptr)); +} +#endif // __cpp_lib_concepts + template struct _Can_stream_unique_ptr : false_type {}; template diff --git a/tests/std/tests/P1614R2_spaceship/test.cpp b/tests/std/tests/P1614R2_spaceship/test.cpp index 2bd59ee057b..3bff58da83c 100644 --- a/tests/std/tests/P1614R2_spaceship/test.cpp +++ b/tests/std/tests/P1614R2_spaceship/test.cpp @@ -731,6 +731,26 @@ void ordering_test_cases() { assert((m1 <=> m2) == 0); static_assert((m1 <=> m2) == 0); } + { // unique_ptr + std::unique_ptr p1{nullptr}; + std::unique_ptr& p2 = p1; + std::unique_ptr p3{new int}; + + spaceship_test(p1, p2, p3); + spaceship_test(p1, nullptr, p3); + } + { // shared_ptr + std::shared_ptr p1{nullptr}; + std::shared_ptr& p2 = p1; // same managed ptr + std::shared_ptr p3 = p2; // same stored ptr + + std::shared_ptr p4{new int}; + std::shared_ptr p5 = p4; // same stored ptr + + spaceship_test(p1, p2, p4); + spaceship_test(p1, p3, p5); + spaceship_test(p1, nullptr, p4); + } { // slice std::slice a1(2, 3, 4); std::slice a2(2, 3, 4); diff --git a/tests/tr1/tests/memory1/test.cpp b/tests/tr1/tests/memory1/test.cpp index c27161919eb..b4efd826836 100644 --- a/tests/tr1/tests/memory1/test.cpp +++ b/tests/tr1/tests/memory1/test.cpp @@ -13,6 +13,9 @@ #include #include +// DevDiv 1281038: False C6287 for C++20 synthesized operators +#pragma warning(disable : 6287) // Redundant code: the left and right sub-expressions are identical. + static void t_bad_weak_ptr() { // test bad_weak_ptr STD bad_weak_ptr ptr; STD exception* eptr = &ptr; From 69491ce347b66e64e82cb147a98a74d4c079c126 Mon Sep 17 00:00:00 2001 From: "Stephan T. Lavavej" Date: Sun, 21 Feb 2021 17:45:47 -0800 Subject: [PATCH 2/6] Use lowercase 'v' for arrows/chevrons. --- stl/inc/memory | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/stl/inc/memory b/stl/inc/memory index cdf13e83566..bee0fc8c248 100644 --- a/stl/inc/memory +++ b/stl/inc/memory @@ -1797,7 +1797,7 @@ _NODISCARD strong_ordering operator<=>(const shared_ptr<_Ty1>& _Left, const shar return _Left.get() <=> _Right.get(); } -#else // ^^^ _HAS_CXX20 / !_HAS_CXX20 VVV +#else // ^^^ _HAS_CXX20 / !_HAS_CXX20 vvv template _NODISCARD bool operator!=(const shared_ptr<_Ty1>& _Left, const shared_ptr<_Ty2>& _Right) noexcept { return _Left.get() != _Right.get(); @@ -1835,7 +1835,7 @@ _NODISCARD strong_ordering operator<=>(const shared_ptr<_Ty>& _Left, nullptr_t) return compare_three_way()(_Left.get(), static_cast::element_type*>(nullptr)); } -#else // ^^^ __cpp_lib_concepts / !__cpp_lib_concepts VVV +#else // ^^^ __cpp_lib_concepts / !__cpp_lib_concepts vvv template _NODISCARD bool operator==(nullptr_t, const shared_ptr<_Ty>& _Right) noexcept { return nullptr == _Right.get(); From 2dcc4dfe2a7126ff3ade5bed717f1ef0eea56d49 Mon Sep 17 00:00:00 2001 From: "Stephan T. Lavavej" Date: Sun, 21 Feb 2021 17:56:55 -0800 Subject: [PATCH 3/6] In shared_ptr <=> nullptr_t, directly use <=> for _HAS_CXX20. --- stl/inc/memory | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/stl/inc/memory b/stl/inc/memory index bee0fc8c248..b4ee906c8dd 100644 --- a/stl/inc/memory +++ b/stl/inc/memory @@ -1829,13 +1829,13 @@ _NODISCARD bool operator==(const shared_ptr<_Ty>& _Left, nullptr_t) noexcept { return _Left.get() == nullptr; } -#ifdef __cpp_lib_concepts +#if _HAS_CXX20 template _NODISCARD strong_ordering operator<=>(const shared_ptr<_Ty>& _Left, nullptr_t) noexcept { - return compare_three_way()(_Left.get(), static_cast::element_type*>(nullptr)); + return _Left.get() <=> static_cast::element_type*>(nullptr); } -#else // ^^^ __cpp_lib_concepts / !__cpp_lib_concepts vvv +#else // ^^^ _HAS_CXX20 / !_HAS_CXX20 vvv template _NODISCARD bool operator==(nullptr_t, const shared_ptr<_Ty>& _Right) noexcept { return nullptr == _Right.get(); @@ -1890,7 +1890,7 @@ template _NODISCARD bool operator<=(nullptr_t, const shared_ptr<_Ty>& _Right) noexcept { return static_cast::element_type*>(nullptr) <= _Right.get(); } -#endif // ^^^ !__cpp_lib_concepts ^^^ +#endif // ^^^ !_HAS_CXX20 ^^^ template basic_ostream<_Elem, _Traits>& operator<<(basic_ostream<_Elem, _Traits>& _Out, const shared_ptr<_Ty>& _Px) { From cc5c91ae837cc718bc7fa2368a747349fed0a8b1 Mon Sep 17 00:00:00 2001 From: "Stephan T. Lavavej" Date: Sun, 21 Feb 2021 18:11:04 -0800 Subject: [PATCH 4/6] In unique_ptr <=> nullptr_t, directly use <=>. --- stl/inc/memory | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/stl/inc/memory b/stl/inc/memory index b4ee906c8dd..1e2d864a9be 100644 --- a/stl/inc/memory +++ b/stl/inc/memory @@ -3545,7 +3545,7 @@ template _NODISCARD compare_three_way_result_t::pointer> operator<=>( const unique_ptr<_Ty, _Dx>& _Left, nullptr_t) { // clang-format on - return compare_three_way()(_Left.get(), static_cast::pointer>(nullptr)); + return _Left.get() <=> static_cast::pointer>(nullptr); } #endif // __cpp_lib_concepts From 971b930a60a37a66d3e319310541c993a2009554 Mon Sep 17 00:00:00 2001 From: "Stephan T. Lavavej" Date: Sun, 21 Feb 2021 18:12:36 -0800 Subject: [PATCH 5/6] Cite TRANSITION, VSO-1281038. --- tests/tr1/tests/memory1/test.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/tr1/tests/memory1/test.cpp b/tests/tr1/tests/memory1/test.cpp index b4efd826836..695d941c98a 100644 --- a/tests/tr1/tests/memory1/test.cpp +++ b/tests/tr1/tests/memory1/test.cpp @@ -13,7 +13,7 @@ #include #include -// DevDiv 1281038: False C6287 for C++20 synthesized operators +// TRANSITION, VSO-1281038: False C6287 for C++20 synthesized operators #pragma warning(disable : 6287) // Redundant code: the left and right sub-expressions are identical. static void t_bad_weak_ptr() { // test bad_weak_ptr From 2db05f0d9958f27b10a19649a03a1188f7e673b2 Mon Sep 17 00:00:00 2001 From: "Stephan T. Lavavej" Date: Sun, 21 Feb 2021 18:14:54 -0800 Subject: [PATCH 6/6] Include . --- tests/std/tests/P1614R2_spaceship/test.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/std/tests/P1614R2_spaceship/test.cpp b/tests/std/tests/P1614R2_spaceship/test.cpp index 3bff58da83c..f9ccf223963 100644 --- a/tests/std/tests/P1614R2_spaceship/test.cpp +++ b/tests/std/tests/P1614R2_spaceship/test.cpp @@ -13,6 +13,7 @@ #include #include #include +#include #include #include #include