Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
44 changes: 44 additions & 0 deletions stl/inc/memory
Original file line number Diff line number Diff line change
Expand Up @@ -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 <class _Ty1, class _Ty2>
_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 <class _Ty1, class _Ty2>
_NODISCARD bool operator!=(const shared_ptr<_Ty1>& _Left, const shared_ptr<_Ty2>& _Right) noexcept {
return _Left.get() != _Right.get();
Expand All @@ -1815,12 +1822,20 @@ template <class _Ty1, class _Ty2>
_NODISCARD bool operator<=(const shared_ptr<_Ty1>& _Left, const shared_ptr<_Ty2>& _Right) noexcept {
return _Left.get() <= _Right.get();
}
#endif // ^^^ !_HAS_CXX20 ^^^

template <class _Ty>
_NODISCARD bool operator==(const shared_ptr<_Ty>& _Left, nullptr_t) noexcept {
return _Left.get() == nullptr;
}

#if _HAS_CXX20
template <class _Ty>
_NODISCARD strong_ordering operator<=>(const shared_ptr<_Ty>& _Left, nullptr_t) noexcept {
return _Left.get() <=> static_cast<typename shared_ptr<_Ty>::element_type*>(nullptr);
}

#else // ^^^ _HAS_CXX20 / !_HAS_CXX20 vvv
template <class _Ty>
_NODISCARD bool operator==(nullptr_t, const shared_ptr<_Ty>& _Right) noexcept {
return nullptr == _Right.get();
Expand Down Expand Up @@ -1875,6 +1890,7 @@ template <class _Ty>
_NODISCARD bool operator<=(nullptr_t, const shared_ptr<_Ty>& _Right) noexcept {
return static_cast<typename shared_ptr<_Ty>::element_type*>(nullptr) <= _Right.get();
}
#endif // ^^^ !_HAS_CXX20 ^^^

template <class _Elem, class _Traits, class _Ty>
basic_ostream<_Elem, _Traits>& operator<<(basic_ostream<_Elem, _Traits>& _Out, const shared_ptr<_Ty>& _Px) {
Expand Down Expand Up @@ -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 <class _Ty1, class _Dx1, class _Ty2, class _Dx2>
_NODISCARD bool operator!=(const unique_ptr<_Ty1, _Dx1>& _Left, const unique_ptr<_Ty2, _Dx2>& _Right) {
return !(_Left == _Right);
}
#endif // !_HAS_CXX20

template <class _Ty1, class _Dx1, class _Ty2, class _Dx2>
_NODISCARD bool operator<(const unique_ptr<_Ty1, _Dx1>& _Left, const unique_ptr<_Ty2, _Dx2>& _Right) {
Expand All @@ -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 <class _Ty1, class _Dx1, class _Ty2, class _Dx2>
requires three_way_comparable_with<typename unique_ptr<_Ty1, _Dx1>::pointer,
typename unique_ptr<_Ty2, _Dx2>::pointer>
_NODISCARD compare_three_way_result_t<typename unique_ptr<_Ty1, _Dx1>::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 <class _Ty, class _Dx>
_NODISCARD bool operator==(const unique_ptr<_Ty, _Dx>& _Left, nullptr_t) noexcept {
return !_Left;
}

#if !_HAS_CXX20
template <class _Ty, class _Dx>
_NODISCARD bool operator==(nullptr_t, const unique_ptr<_Ty, _Dx>& _Right) noexcept {
return !_Right;
Expand All @@ -3462,6 +3494,7 @@ template <class _Ty, class _Dx>
_NODISCARD bool operator!=(nullptr_t _Left, const unique_ptr<_Ty, _Dx>& _Right) noexcept {
return !(_Left == _Right);
}
#endif // !_HAS_CXX20

template <class _Ty, class _Dx>
_NODISCARD bool operator<(const unique_ptr<_Ty, _Dx>& _Left, nullptr_t _Right) {
Expand Down Expand Up @@ -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 <class _Ty, class _Dx>
requires three_way_comparable<typename unique_ptr<_Ty, _Dx>::pointer>
_NODISCARD compare_three_way_result_t<typename unique_ptr<_Ty, _Dx>::pointer> operator<=>(
const unique_ptr<_Ty, _Dx>& _Left, nullptr_t) {
// clang-format on
return _Left.get() <=> static_cast<typename unique_ptr<_Ty, _Dx>::pointer>(nullptr);
}
#endif // __cpp_lib_concepts

template <class _OutTy, class _PxTy, class = void>
struct _Can_stream_unique_ptr : false_type {};
template <class _OutTy, class _PxTy>
Expand Down
20 changes: 20 additions & 0 deletions tests/std/tests/P1614R2_spaceship/test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -864,6 +864,26 @@ void ordering_test_cases() {
assert((m1 <=> m2) == 0);
static_assert((m1 <=> m2) == 0);
}
{ // unique_ptr
std::unique_ptr<int> p1{nullptr};
std::unique_ptr<int>& p2 = p1;
std::unique_ptr<int> p3{new int};

spaceship_test<std::strong_ordering>(p1, p2, p3);
spaceship_test<std::strong_ordering>(p1, nullptr, p3);
}
{ // shared_ptr
std::shared_ptr<int> p1{nullptr};
std::shared_ptr<int>& p2 = p1; // same managed ptr
std::shared_ptr<int> p3 = p2; // same stored ptr

std::shared_ptr<int> p4{new int};
std::shared_ptr<int> p5 = p4; // same stored ptr

spaceship_test<std::strong_ordering>(p1, p2, p4);
spaceship_test<std::strong_ordering>(p1, p3, p5);
spaceship_test<std::strong_ordering>(p1, nullptr, p4);
}
{ // slice
std::slice a1(2, 3, 4);
std::slice a2(2, 3, 4);
Expand Down
3 changes: 3 additions & 0 deletions tests/tr1/tests/memory1/test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,9 @@
#include <sstream>
#include <string>

// 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
STD bad_weak_ptr ptr;
STD exception* eptr = &ptr;
Expand Down