[libcxx-commits] [libcxx] 735240b - [libc++] Implement `operator<=>` for `unique_ptr`

Mark de Wever via libcxx-commits libcxx-commits at lists.llvm.org
Sat Aug 6 06:09:21 PDT 2022


Author: Adrian Vogelsgesang
Date: 2022-08-06T15:09:16+02:00
New Revision: 735240b38fd7a249474a66f96cb98587658010af

URL: https://github.com/llvm/llvm-project/commit/735240b38fd7a249474a66f96cb98587658010af
DIFF: https://github.com/llvm/llvm-project/commit/735240b38fd7a249474a66f96cb98587658010af.diff

LOG: [libc++] Implement `operator<=>` for `unique_ptr`

Implements part of:

  - P1614R2 The Mothership has Landed

Fixes LWG3426

Reviewed By: #libc, Mordante

Differential Revision: https://reviews.llvm.org/D130838

Added: 
    libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.special/cmp.pass.cpp

Modified: 
    libcxx/docs/Status/Cxx20Papers.csv
    libcxx/docs/Status/Cxx2bIssues.csv
    libcxx/docs/Status/SpaceshipProjects.csv
    libcxx/include/__memory/unique_ptr.h
    libcxx/include/memory
    libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.special/cmp_nullptr.pass.cpp

Removed: 
    libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.special/eq.pass.cpp
    libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.special/rel.pass.cpp


################################################################################
diff  --git a/libcxx/docs/Status/Cxx20Papers.csv b/libcxx/docs/Status/Cxx20Papers.csv
index 7d39424a6e6ef..a3b044080da26 100644
--- a/libcxx/docs/Status/Cxx20Papers.csv
+++ b/libcxx/docs/Status/Cxx20Papers.csv
@@ -158,7 +158,7 @@
 "`P1878R1 <https://wg21.link/P1878R1>`__","LWG","Constraining Readable Types","Belfast","|Complete|","15.0"
 "`P1892R1 <https://wg21.link/P1892R1>`__","LWG","Extended locale-specific presentation specifiers for std::format","Belfast","|Complete|","14.0"
 "`P1902R1 <https://wg21.link/P1902R1>`__","LWG","Missing feature-test macros 2018-2019","Belfast","* *",""
-"`P1959R0 <https://wg21.link/P1959R0>`__","LWG","Remove std::weak_equality and std::strong_equality","Belfast","* *",""
+"`P1959R0 <https://wg21.link/P1959R0>`__","LWG","Remove std::weak_equality and std::strong_equality","Belfast","|Nothing To Do|",""
 "`P1960R0 <https://wg21.link/P1960R0>`__","LWG","NB Comment Changes Reviewed by SG1","Belfast","* *",""
 "`P1961R0 <https://wg21.link/P1961R0>`__","LWG","Harmonizing the definitions of total order for pointers","Belfast","* *",""
 "`P1965R0 <https://wg21.link/P1965R0>`__","LWG","Blanket Wording for Specifying ""Hidden Friends""","Belfast","* *",""

diff  --git a/libcxx/docs/Status/Cxx2bIssues.csv b/libcxx/docs/Status/Cxx2bIssues.csv
index d0eaf86796ffe..ab3c680e8a8dd 100644
--- a/libcxx/docs/Status/Cxx2bIssues.csv
+++ b/libcxx/docs/Status/Cxx2bIssues.csv
@@ -27,7 +27,7 @@
 "`3420 <https://wg21.link/LWG3420>`__","cpp17-iterator should check that the type looks like an iterator first","November 2020","|Complete|","14.0","|ranges|"
 "`3421 <https://wg21.link/LWG3421>`__","Imperfect ADL emulation for boolean-testable","November 2020","|Nothing To Do|","","|ranges|"
 "`3425 <https://wg21.link/LWG3425>`__","``condition_variable_any`` fails to constrain its Lock parameters","November 2020","|Nothing To Do|",""
-"`3426 <https://wg21.link/LWG3426>`__","``operator<=>(const unique_ptr<T, D>&, nullptr_t)`` can't get no satisfaction","November 2020","","","|spaceship|"
+"`3426 <https://wg21.link/LWG3426>`__","``operator<=>(const unique_ptr<T, D>&, nullptr_t)`` can't get no satisfaction","November 2020","|Complete|","16.0","|spaceship|"
 "`3427 <https://wg21.link/LWG3427>`__","``operator<=>(const shared_ptr<T>&, nullptr_t)`` definition ill-formed","November 2020","|Complete|","16.0","|spaceship|"
 "`3428 <https://wg21.link/LWG3428>`__","``single_view``'s in place constructor should be explicit","November 2020","|Complete|","14.0","|ranges|"
 "`3434 <https://wg21.link/LWG3434>`__","``ios_base`` never reclaims memory for iarray and parray","November 2020","|Nothing To Do|",""

diff  --git a/libcxx/docs/Status/SpaceshipProjects.csv b/libcxx/docs/Status/SpaceshipProjects.csv
index e0f5e6fab8b24..87e0c60373e6d 100644
--- a/libcxx/docs/Status/SpaceshipProjects.csv
+++ b/libcxx/docs/Status/SpaceshipProjects.csv
@@ -25,7 +25,7 @@ Section,Description,Dependencies,Assignee,Complete
 "| `[variant.relops] <https://wg21.link/variant.relops>`_
 | `[variant.monostate.relops] <https://wg21.link/variant.monostate.relops>`_","| monostate
 | variant",None,Kent Ross,|In Progress|
-| `[unique.ptr.special] <https://wg21.link/unique.ptr.special>`_,| `unique_ptr <https://reviews.llvm.org/D130838>`_,[comparisons.three.way],Adrian Vogelsgesang,|In Progress|
+| `[unique.ptr.special] <https://wg21.link/unique.ptr.special>`_,| `unique_ptr <https://reviews.llvm.org/D130838>`_,[comparisons.three.way],Adrian Vogelsgesang,|Complete|
 | `[util.smartptr.shared.cmp] <https://wg21.link/util.smartptr.shared.cmp>`_,| `shared_ptr <https://reviews.llvm.org/D130852>`_,[comparisons.three.way],Adrian Vogelsgesang,|Complete|
 | `[type.index.members] <https://wg21.link/type.index.members>`_,| type_index,None,Unassigned,|Not Started|
 | `[charconv.syn] <https://wg21.link/charconv.syn>`_,| to_chars_result,None,Mark de Wever,|Complete|

diff  --git a/libcxx/include/__memory/unique_ptr.h b/libcxx/include/__memory/unique_ptr.h
index 1de64de30b232..739966ab96592 100644
--- a/libcxx/include/__memory/unique_ptr.h
+++ b/libcxx/include/__memory/unique_ptr.h
@@ -10,6 +10,9 @@
 #ifndef _LIBCPP___MEMORY_UNIQUE_PTR_H
 #define _LIBCPP___MEMORY_UNIQUE_PTR_H
 
+#include <__compare/compare_three_way.h>
+#include <__compare/compare_three_way_result.h>
+#include <__compare/three_way_comparable.h>
 #include <__config>
 #include <__functional/hash.h>
 #include <__functional/operations.h>
@@ -557,10 +560,12 @@ inline _LIBCPP_INLINE_VISIBILITY
 bool
 operator==(const unique_ptr<_T1, _D1>& __x, const unique_ptr<_T2, _D2>& __y) {return __x.get() == __y.get();}
 
+#if _LIBCPP_STD_VER <= 17
 template <class _T1, class _D1, class _T2, class _D2>
 inline _LIBCPP_INLINE_VISIBILITY
 bool
 operator!=(const unique_ptr<_T1, _D1>& __x, const unique_ptr<_T2, _D2>& __y) {return !(__x == __y);}
+#endif
 
 template <class _T1, class _D1, class _T2, class _D2>
 inline _LIBCPP_INLINE_VISIBILITY
@@ -588,6 +593,19 @@ inline _LIBCPP_INLINE_VISIBILITY
 bool
 operator>=(const unique_ptr<_T1, _D1>& __x, const unique_ptr<_T2, _D2>& __y) {return !(__x < __y);}
 
+
+#if _LIBCPP_STD_VER > 17
+template <class _T1, class _D1, class _T2, class _D2>
+requires three_way_comparable_with<typename unique_ptr<_T1, _D1>::pointer,
+                                   typename unique_ptr<_T2, _D2>::pointer>
+_LIBCPP_HIDE_FROM_ABI
+compare_three_way_result_t<typename unique_ptr<_T1, _D1>::pointer,
+                           typename unique_ptr<_T2, _D2>::pointer>
+operator<=>(const unique_ptr<_T1, _D1>& __x, const unique_ptr<_T2, _D2>& __y) {
+   return compare_three_way()(__x.get(), __y.get());
+}
+#endif
+
 template <class _T1, class _D1>
 inline _LIBCPP_INLINE_VISIBILITY
 bool
@@ -596,6 +614,7 @@ operator==(const unique_ptr<_T1, _D1>& __x, nullptr_t) _NOEXCEPT
     return !__x;
 }
 
+#if _LIBCPP_STD_VER <= 17
 template <class _T1, class _D1>
 inline _LIBCPP_INLINE_VISIBILITY
 bool
@@ -619,6 +638,7 @@ operator!=(nullptr_t, const unique_ptr<_T1, _D1>& __x) _NOEXCEPT
 {
     return static_cast<bool>(__x);
 }
+#endif // _LIBCPP_STD_VER <= 17
 
 template <class _T1, class _D1>
 inline _LIBCPP_INLINE_VISIBILITY
@@ -686,6 +706,16 @@ operator>=(nullptr_t, const unique_ptr<_T1, _D1>& __x)
     return !(nullptr < __x);
 }
 
+#if _LIBCPP_STD_VER > 17
+template <class _T1, class _D1>
+requires three_way_comparable<typename unique_ptr<_T1, _D1>::pointer>
+_LIBCPP_HIDE_FROM_ABI
+compare_three_way_result_t<typename unique_ptr<_T1, _D1>::pointer>
+operator<=>(const unique_ptr<_T1, _D1>& __x, nullptr_t) {
+   return compare_three_way()(__x.get(), static_cast<typename unique_ptr<_T1, _D1>::pointer>(nullptr));
+}
+#endif
+
 #if _LIBCPP_STD_VER > 11
 
 template<class _Tp>

diff  --git a/libcxx/include/memory b/libcxx/include/memory
index a5d2bfbdf330d..2ecd4fe485e73 100644
--- a/libcxx/include/memory
+++ b/libcxx/include/memory
@@ -505,7 +505,7 @@ template <class T, class D>
 template <class T1, class D1, class T2, class D2>
     bool operator==(const unique_ptr<T1, D1>& x, const unique_ptr<T2, D2>& y);
 template <class T1, class D1, class T2, class D2>
-    bool operator!=(const unique_ptr<T1, D1>& x, const unique_ptr<T2, D2>& y);
+    bool operator!=(const unique_ptr<T1, D1>& x, const unique_ptr<T2, D2>& y);    // removed in C++20
 template <class T1, class D1, class T2, class D2>
     bool operator<(const unique_ptr<T1, D1>& x, const unique_ptr<T2, D2>& y);
 template <class T1, class D1, class T2, class D2>
@@ -514,15 +514,21 @@ template <class T1, class D1, class T2, class D2>
     bool operator>(const unique_ptr<T1, D1>& x, const unique_ptr<T2, D2>& y);
 template <class T1, class D1, class T2, class D2>
     bool operator>=(const unique_ptr<T1, D1>& x, const unique_ptr<T2, D2>& y);
+template<class T1, class D1, class T2, class D2>
+  requires three_way_comparable_with<typename unique_ptr<T1, D1>::pointer,
+                                     typename unique_ptr<T2, D2>::pointer>
+  compare_three_way_result_t<typename unique_ptr<T1, D1>::pointer,
+                             typename unique_ptr<T2, D2>::pointer>
+    operator<=>(const unique_ptr<T1, D1>& x, const unique_ptr<T2, D2>& y);      // C++20
 
 template <class T, class D>
     bool operator==(const unique_ptr<T, D>& x, nullptr_t) noexcept;
 template <class T, class D>
-    bool operator==(nullptr_t, const unique_ptr<T, D>& y) noexcept;
+    bool operator==(nullptr_t, const unique_ptr<T, D>& y) noexcept;     // removed in C++20
 template <class T, class D>
-    bool operator!=(const unique_ptr<T, D>& x, nullptr_t) noexcept;
+    bool operator!=(const unique_ptr<T, D>& x, nullptr_t) noexcept;     // removed in C++20
 template <class T, class D>
-    bool operator!=(nullptr_t, const unique_ptr<T, D>& y) noexcept;
+    bool operator!=(nullptr_t, const unique_ptr<T, D>& y) noexcept;     // removed in C++20
 
 template <class T, class D>
     bool operator<(const unique_ptr<T, D>& x, nullptr_t);
@@ -540,6 +546,10 @@ template <class T, class D>
     bool operator>=(const unique_ptr<T, D>& x, nullptr_t);
 template <class T, class D>
     bool operator>=(nullptr_t, const unique_ptr<T, D>& y);
+template<class T, class D>
+  requires three_way_comparable<typename unique_ptr<T, D>::pointer>
+  compare_three_way_result_t<typename unique_ptr<T, D>::pointer>
+    operator<=>(const unique_ptr<T, D>& x, nullptr_t);                          // C++20
 
 class bad_weak_ptr
     : public std::exception

diff  --git a/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.special/cmp.pass.cpp b/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.special/cmp.pass.cpp
new file mode 100644
index 0000000000000..68f69ea99b1cc
--- /dev/null
+++ b/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.special/cmp.pass.cpp
@@ -0,0 +1,164 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// <memory>
+
+// unique_ptr
+
+// template <class T1, class D1, class T2, class D2>
+//   bool
+//   operator==(const unique_ptr<T1, D1>& x, const unique_ptr<T2, D2>& y);
+
+// template <class T1, class D1, class T2, class D2>
+//   bool
+//   operator!=(const unique_ptr<T1, D1>& x, const unique_ptr<T2, D2>& y);
+
+// template <class T1, class D1, class T2, class D2>
+//   bool
+//   operator< (const unique_ptr<T1, D1>& x, const unique_ptr<T2, D2>& y);
+
+// template <class T1, class D1, class T2, class D2>
+//   bool
+//   operator> (const unique_ptr<T1, D1>& x, const unique_ptr<T2, D2>& y);
+
+// template <class T1, class D1, class T2, class D2>
+//   bool
+//   operator<=(const unique_ptr<T1, D1>& x, const unique_ptr<T2, D2>& y);
+
+// template <class T1, class D1, class T2, class D2>
+//   bool
+//   operator>=(const unique_ptr<T1, D1>& x, const unique_ptr<T2, D2>& y);
+
+// template<class T1, class D1, class T2, class D2>
+//   requires three_way_comparable_with<typename unique_ptr<T1, D1>::pointer,
+//                                      typename unique_ptr<T2, D2>::pointer>
+//   compare_three_way_result_t<typename unique_ptr<T1, D1>::pointer,
+//                              typename unique_ptr<T2, D2>::pointer>
+//     operator<=>(const unique_ptr<T1, D1>& x, const unique_ptr<T2, D2>& y);
+
+#include <memory>
+#include <cassert>
+
+#include "test_macros.h"
+#include "deleter_types.h"
+#include "test_comparisons.h"
+
+struct A {
+  static int count;
+  A() { ++count; }
+  A(const A&) { ++count; }
+  virtual ~A() { --count; }
+};
+
+int A::count = 0;
+
+struct B : public A {
+  static int count;
+  B() { ++count; }
+  B(const B& other) : A(other) { ++count; }
+  virtual ~B() { --count; }
+};
+
+int B::count = 0;
+
+int main(int, char**) {
+  AssertComparisonsReturnBool<std::unique_ptr<int> >();
+#if TEST_STD_VER > 17
+  AssertOrderReturn<std::strong_ordering, std::unique_ptr<int>>();
+#endif
+
+  // Pointers of same type
+  {
+    A* ptr1 = new A;
+    A* ptr2 = new A;
+    const std::unique_ptr<A, Deleter<A> > p1(ptr1);
+    const std::unique_ptr<A, Deleter<A> > p2(ptr2);
+
+    assert(!(p1 == p2));
+    assert(p1 != p2);
+    assert((p1 < p2) == (ptr1 < ptr2));
+    assert((p1 <= p2) == (ptr1 <= ptr2));
+    assert((p1 > p2) == (ptr1 > ptr2));
+    assert((p1 >= p2) == (ptr1 >= ptr2));
+#if TEST_STD_VER > 17
+    assert((p1 <=> p2) != std::strong_ordering::equal);
+    assert((p1 <=> p2) == (ptr1 <=> ptr2));
+#endif
+  }
+  // Pointers of 
diff erent type
+  {
+    A* ptr1 = new A;
+    B* ptr2 = new B;
+    const std::unique_ptr<A, Deleter<A> > p1(ptr1);
+    const std::unique_ptr<B, Deleter<B> > p2(ptr2);
+    assert(!(p1 == p2));
+    assert(p1 != p2);
+    assert((p1 < p2) == (ptr1 < ptr2));
+    assert((p1 <= p2) == (ptr1 <= ptr2));
+    assert((p1 > p2) == (ptr1 > ptr2));
+    assert((p1 >= p2) == (ptr1 >= ptr2));
+#if TEST_STD_VER > 17
+    assert((p1 <=> p2) != std::strong_ordering::equal);
+    assert((p1 <=> p2) == (ptr1 <=> ptr2));
+#endif
+  }
+  // Pointers of same array type
+  {
+    A* ptr1 = new A[3];
+    A* ptr2 = new A[3];
+    const std::unique_ptr<A[], Deleter<A[]> > p1(ptr1);
+    const std::unique_ptr<A[], Deleter<A[]> > p2(ptr2);
+    assert(!(p1 == p2));
+    assert(p1 != p2);
+    assert((p1 < p2) == (ptr1 < ptr2));
+    assert((p1 <= p2) == (ptr1 <= ptr2));
+    assert((p1 > p2) == (ptr1 > ptr2));
+    assert((p1 >= p2) == (ptr1 >= ptr2));
+#if TEST_STD_VER > 17
+    assert((p1 <=> p2) != std::strong_ordering::equal);
+    assert((p1 <=> p2) == (ptr1 <=> ptr2));
+#endif
+  }
+  // Pointers of 
diff erent array types
+  {
+    A* ptr1 = new A[3];
+    B* ptr2 = new B[3];
+    const std::unique_ptr<A[], Deleter<A[]> > p1(ptr1);
+    const std::unique_ptr<B[], Deleter<B[]> > p2(ptr2);
+    assert(!(p1 == p2));
+    assert(p1 != p2);
+    assert((p1 < p2) == (ptr1 < ptr2));
+    assert((p1 <= p2) == (ptr1 <= ptr2));
+    assert((p1 > p2) == (ptr1 > ptr2));
+    assert((p1 >= p2) == (ptr1 >= ptr2));
+#if TEST_STD_VER > 17
+    assert((p1 <=> p2) != std::strong_ordering::equal);
+    assert((p1 <=> p2) == (ptr1 <=> ptr2));
+#endif
+  }
+  // Default-constructed pointers of same type
+  {
+    const std::unique_ptr<A, Deleter<A> > p1;
+    const std::unique_ptr<A, Deleter<A> > p2;
+    assert(p1 == p2);
+#if TEST_STD_VER > 17
+    assert((p1 <=> p2) == std::strong_ordering::equal);
+#endif
+  }
+  // Default-constructed pointers of 
diff erent type
+  {
+    const std::unique_ptr<A, Deleter<A> > p1;
+    const std::unique_ptr<B, Deleter<B> > p2;
+    assert(p1 == p2);
+#if TEST_STD_VER > 17
+    assert((p1 <=> p2) == std::strong_ordering::equal);
+#endif
+  }
+
+  return 0;
+}

diff  --git a/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.special/cmp_nullptr.pass.cpp b/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.special/cmp_nullptr.pass.cpp
index ad3e1e2ddb190..22b8d25ef5fd3 100644
--- a/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.special/cmp_nullptr.pass.cpp
+++ b/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.special/cmp_nullptr.pass.cpp
@@ -19,54 +19,73 @@
 // template <class T, class D>
 //     bool operator!=(nullptr_t, const unique_ptr<T, D>& y) noexcept;
 // template <class T, class D>
-//     bool operator<(const unique_ptr<T, D>& x, nullptr_t) noexcept;
+//     bool operator<(const unique_ptr<T, D>& x, nullptr_t);
 // template <class T, class D>
-//     bool operator<(nullptr_t, const unique_ptr<T, D>& y) noexcept;
+//     bool operator<(nullptr_t, const unique_ptr<T, D>& y);
 // template <class T, class D>
-//     bool operator<=(const unique_ptr<T, D>& x, nullptr_t) noexcept;
+//     bool operator<=(const unique_ptr<T, D>& x, nullptr_t);
 // template <class T, class D>
-//     bool operator<=(nullptr_t, const unique_ptr<T, D>& y) noexcept;
+//     bool operator<=(nullptr_t, const unique_ptr<T, D>& y);
 // template <class T, class D>
-//     bool operator>(const unique_ptr<T, D>& x, nullptr_t) noexcept;
+//     bool operator>(const unique_ptr<T, D>& x, nullptr_t);
 // template <class T, class D>
-//     bool operator>(nullptr_t, const unique_ptr<T, D>& y) noexcept;
+//     bool operator>(nullptr_t, const unique_ptr<T, D>& y);
 // template <class T, class D>
-//     bool operator>=(const unique_ptr<T, D>& x, nullptr_t) noexcept;
+//     bool operator>=(const unique_ptr<T, D>& x, nullptr_t);
 // template <class T, class D>
-//     bool operator>=(nullptr_t, const unique_ptr<T, D>& y) noexcept;
+//     bool operator>=(nullptr_t, const unique_ptr<T, D>& y);
+// template<class T, class D>
+//   requires three_­way_­comparable<typename unique_ptr<T, D>::pointer>
+//   constexpr compare_three_way_result_t<typename unique_ptr<T, D>::pointer>
+//     operator<=>(const unique_ptr<T, D>& x, nullptr_t);                            // C++20
 
 #include <memory>
 #include <cassert>
 
 #include "test_macros.h"
-
-void do_nothing(int*) {}
+#include "test_comparisons.h"
 
 int main(int, char**)
 {
-    const std::unique_ptr<int> p1(new int(1));
-    assert(!(p1 == nullptr));
-    assert(!(nullptr == p1));
-    assert(!(p1 < nullptr));
-    assert( (nullptr < p1));
-    assert(!(p1 <= nullptr));
-    assert( (nullptr <= p1));
-    assert( (p1 > nullptr));
-    assert(!(nullptr > p1));
-    assert( (p1 >= nullptr));
-    assert(!(nullptr >= p1));
+  AssertEqualityAreNoexcept<std::unique_ptr<int>, nullptr_t>();
+  AssertEqualityAreNoexcept<nullptr_t, std::unique_ptr<int> >();
+  AssertComparisonsReturnBool<std::unique_ptr<int>, nullptr_t>();
+  AssertComparisonsReturnBool<nullptr_t, std::unique_ptr<int> >();
+#if TEST_STD_VER > 17
+  AssertOrderReturn<std::strong_ordering, std::unique_ptr<int>, nullptr_t>();
+  AssertOrderReturn<std::strong_ordering, nullptr_t, std::unique_ptr<int>>();
+#endif
+
+  const std::unique_ptr<int> p1(new int(1));
+  assert(!(p1 == nullptr));
+  assert(!(nullptr == p1));
+  assert(!(p1 < nullptr));
+  assert((nullptr < p1));
+  assert(!(p1 <= nullptr));
+  assert((nullptr <= p1));
+  assert((p1 > nullptr));
+  assert(!(nullptr > p1));
+  assert((p1 >= nullptr));
+  assert(!(nullptr >= p1));
+#if TEST_STD_VER > 17
+  assert((nullptr <=> p1) == std::strong_ordering::less);
+  assert((p1 <=> nullptr) == std::strong_ordering::greater);
+#endif
 
-    const std::unique_ptr<int> p2;
-    assert( (p2 == nullptr));
-    assert( (nullptr == p2));
-    assert(!(p2 < nullptr));
-    assert(!(nullptr < p2));
-    assert( (p2 <= nullptr));
-    assert( (nullptr <= p2));
-    assert(!(p2 > nullptr));
-    assert(!(nullptr > p2));
-    assert( (p2 >= nullptr));
-    assert( (nullptr >= p2));
+  const std::unique_ptr<int> p2;
+  assert((p2 == nullptr));
+  assert((nullptr == p2));
+  assert(!(p2 < nullptr));
+  assert(!(nullptr < p2));
+  assert((p2 <= nullptr));
+  assert((nullptr <= p2));
+  assert(!(p2 > nullptr));
+  assert(!(nullptr > p2));
+  assert((p2 >= nullptr));
+  assert((nullptr >= p2));
+#if TEST_STD_VER > 17
+  assert((nullptr <=> p2) == std::strong_ordering::equivalent);
+#endif
 
   return 0;
 }

diff  --git a/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.special/eq.pass.cpp b/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.special/eq.pass.cpp
deleted file mode 100644
index 6bd1451212dc0..0000000000000
--- a/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.special/eq.pass.cpp
+++ /dev/null
@@ -1,88 +0,0 @@
-//===----------------------------------------------------------------------===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-
-// <memory>
-
-// unique_ptr
-
-// template <class T1, class D1, class T2, class D2>
-//   bool
-//   operator==(const unique_ptr<T1, D1>& x, const unique_ptr<T2, D2>& y);
-
-// template <class T1, class D1, class T2, class D2>
-//   bool
-//   operator!=(const unique_ptr<T1, D1>& x, const unique_ptr<T2, D2>& y);
-
-#include <memory>
-#include <cassert>
-
-#include "test_macros.h"
-#include "deleter_types.h"
-
-struct A
-{
-    static int count;
-    A() {++count;}
-    A(const A&) {++count;}
-    virtual ~A() {--count;}
-};
-
-int A::count = 0;
-
-struct B
-    : public A
-{
-    static int count;
-    B() {++count;}
-    B(const B& other) : A(other) {++count;}
-    virtual ~B() {--count;}
-};
-
-int B::count = 0;
-
-int main(int, char**)
-{
-    {
-    const std::unique_ptr<A, Deleter<A> > p1(new A);
-    const std::unique_ptr<A, Deleter<A> > p2(new A);
-    assert(!(p1 == p2));
-    assert(p1 != p2);
-    }
-    {
-    const std::unique_ptr<A, Deleter<A> > p1(new A);
-    const std::unique_ptr<B, Deleter<B> > p2(new B);
-    assert(!(p1 == p2));
-    assert(p1 != p2);
-    }
-    {
-    const std::unique_ptr<A[], Deleter<A[]> > p1(new A[3]);
-    const std::unique_ptr<A[], Deleter<A[]> > p2(new A[3]);
-    assert(!(p1 == p2));
-    assert(p1 != p2);
-    }
-    {
-    const std::unique_ptr<A[], Deleter<A[]> > p1(new A[3]);
-    const std::unique_ptr<B[], Deleter<B[]> > p2(new B[3]);
-    assert(!(p1 == p2));
-    assert(p1 != p2);
-    }
-    {
-    const std::unique_ptr<A, Deleter<A> > p1;
-    const std::unique_ptr<A, Deleter<A> > p2;
-    assert(p1 == p2);
-    assert(!(p1 != p2));
-    }
-    {
-    const std::unique_ptr<A, Deleter<A> > p1;
-    const std::unique_ptr<B, Deleter<B> > p2;
-    assert(p1 == p2);
-    assert(!(p1 != p2));
-    }
-
-  return 0;
-}

diff  --git a/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.special/rel.pass.cpp b/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.special/rel.pass.cpp
deleted file mode 100644
index b8f1c4b91c12f..0000000000000
--- a/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.special/rel.pass.cpp
+++ /dev/null
@@ -1,102 +0,0 @@
-//===----------------------------------------------------------------------===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-
-// <memory>
-
-// unique_ptr
-
-// template <class T1, class D1, class T2, class D2>
-//   bool
-//   operator< (const unique_ptr<T1, D1>& x, const unique_ptr<T2, D2>& y);
-
-// template <class T1, class D1, class T2, class D2>
-//   bool
-//   operator> (const unique_ptr<T1, D1>& x, const unique_ptr<T2, D2>& y);
-
-// template <class T1, class D1, class T2, class D2>
-//   bool
-//   operator<=(const unique_ptr<T1, D1>& x, const unique_ptr<T2, D2>& y);
-
-// template <class T1, class D1, class T2, class D2>
-//   bool
-//   operator>=(const unique_ptr<T1, D1>& x, const unique_ptr<T2, D2>& y);
-
-#include <memory>
-#include <cassert>
-
-#include "test_macros.h"
-#include "deleter_types.h"
-
-struct A
-{
-    static int count;
-    A() {++count;}
-    A(const A&) {++count;}
-    virtual ~A() {--count;}
-};
-
-int A::count = 0;
-
-struct B
-    : public A
-{
-    static int count;
-    B() {++count;}
-    B(const B& other) : A(other) {++count;}
-    virtual ~B() {--count;}
-};
-
-int B::count = 0;
-
-int main(int, char**)
-{
-    {
-    const std::unique_ptr<A, Deleter<A> > p1(new A);
-    const std::unique_ptr<A, Deleter<A> > p2(new A);
-    assert((p1 < p2) == !(p1 > p2));
-    assert((p1 < p2) == (p1 <= p2));
-    assert((p1 < p2) == !(p1 >= p2));
-    }
-    {
-    const std::unique_ptr<A, Deleter<A> > p1(new A);
-    const std::unique_ptr<B, Deleter<B> > p2(new B);
-    assert((p1 < p2) == !(p1 > p2));
-    assert((p1 < p2) == (p1 <= p2));
-    assert((p1 < p2) == !(p1 >= p2));
-    }
-    {
-    const std::unique_ptr<A[], Deleter<A[]> > p1(new A[3]);
-    const std::unique_ptr<A[], Deleter<A[]> > p2(new A[3]);
-    assert((p1 < p2) == !(p1 > p2));
-    assert((p1 < p2) == (p1 <= p2));
-    assert((p1 < p2) == !(p1 >= p2));
-    }
-    {
-    const std::unique_ptr<A[], Deleter<A[]> > p1(new A[3]);
-    const std::unique_ptr<B[], Deleter<B[]> > p2(new B[3]);
-    assert((p1 < p2) == !(p1 > p2));
-    assert((p1 < p2) == (p1 <= p2));
-    assert((p1 < p2) == !(p1 >= p2));
-    }
-    {
-    const std::unique_ptr<A, Deleter<A> > p1;
-    const std::unique_ptr<A, Deleter<A> > p2;
-    assert((p1 < p2) == (p1 > p2));
-    assert((p1 < p2) == !(p1 <= p2));
-    assert((p1 < p2) == !(p1 >= p2));
-    }
-    {
-    const std::unique_ptr<A, Deleter<A> > p1;
-    const std::unique_ptr<B, Deleter<B> > p2;
-    assert((p1 < p2) == (p1 > p2));
-    assert((p1 < p2) == !(p1 <= p2));
-    assert((p1 < p2) == !(p1 >= p2));
-    }
-
-  return 0;
-}


        


More information about the libcxx-commits mailing list