diff options
8 files changed, 167 insertions, 107 deletions
diff --git a/libcxx/docs/Status/Cxx2bIssues.csv b/libcxx/docs/Status/Cxx2bIssues.csv index 361e766..73365da 100644 --- a/libcxx/docs/Status/Cxx2bIssues.csv +++ b/libcxx/docs/Status/Cxx2bIssues.csv @@ -28,7 +28,7 @@ "`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|" -"`3427 <https://wg21.link/LWG3427>`__","``operator<=>(const shared_ptr<T>&, nullptr_t)`` definition ill-formed","November 2020","","","|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|","" "`3437 <https://wg21.link/LWG3437>`__","``__cpp_lib_polymorphic_allocator`` is in the wrong header","November 2020","|Complete|","14.0" diff --git a/libcxx/docs/Status/SpaceshipProjects.csv b/libcxx/docs/Status/SpaceshipProjects.csv index 8e002c0..b7d1c56 100644 --- a/libcxx/docs/Status/SpaceshipProjects.csv +++ b/libcxx/docs/Status/SpaceshipProjects.csv @@ -26,7 +26,7 @@ Section,Description,Dependencies,Assignee,Complete | `[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| -| `[util.smartptr.shared.cmp] <https://wg21.link/util.smartptr.shared.cmp>`_,| `shared_ptr <https://reviews.llvm.org/D130852>`_,[comparisons.three.way],Adrian Vogelsgesang,|In Progress| +| `[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| | `[charconv.syn] <https://wg21.link/charconv.syn>`_,| from_chars_result,None,Mark de Wever,|Complete| diff --git a/libcxx/include/__memory/shared_ptr.h b/libcxx/include/__memory/shared_ptr.h index 41a7c7f..a450cba 100644 --- a/libcxx/include/__memory/shared_ptr.h +++ b/libcxx/include/__memory/shared_ptr.h @@ -11,6 +11,8 @@ #define _LIBCPP___MEMORY_SHARED_PTR_H #include <__availability> +#include <__compare/compare_three_way.h> +#include <__compare/ordering.h> #include <__config> #include <__functional/binary_function.h> #include <__functional/operations.h> @@ -1184,6 +1186,8 @@ operator==(const shared_ptr<_Tp>& __x, const shared_ptr<_Up>& __y) _NOEXCEPT return __x.get() == __y.get(); } +#if _LIBCPP_STD_VER <= 17 + template<class _Tp, class _Up> inline _LIBCPP_INLINE_VISIBILITY bool @@ -1230,6 +1234,17 @@ operator>=(const shared_ptr<_Tp>& __x, const shared_ptr<_Up>& __y) _NOEXCEPT return !(__x < __y); } +#endif // _LIBCPP_STD_VER <= 17 + +#if _LIBCPP_STD_VER > 17 +template<class _Tp, class _Up> +_LIBCPP_HIDE_FROM_ABI strong_ordering +operator<=>(shared_ptr<_Tp> const& __x, shared_ptr<_Up> const& __y) noexcept +{ + return compare_three_way()(__x.get(), __y.get()); +} +#endif + template<class _Tp> inline _LIBCPP_INLINE_VISIBILITY bool @@ -1238,6 +1253,8 @@ operator==(const shared_ptr<_Tp>& __x, nullptr_t) _NOEXCEPT return !__x; } +#if _LIBCPP_STD_VER <= 17 + template<class _Tp> inline _LIBCPP_INLINE_VISIBILITY bool @@ -1326,6 +1343,17 @@ operator>=(nullptr_t, const shared_ptr<_Tp>& __x) _NOEXCEPT return !(nullptr < __x); } +#endif // _LIBCPP_STD_VER <= 17 + +#if _LIBCPP_STD_VER > 17 +template<class _Tp> +_LIBCPP_HIDE_FROM_ABI strong_ordering +operator<=>(shared_ptr<_Tp> const& __x, nullptr_t) noexcept +{ + return compare_three_way()(__x.get(), static_cast<typename shared_ptr<_Tp>::element_type*>(nullptr)); +} +#endif + template<class _Tp> inline _LIBCPP_INLINE_VISIBILITY void diff --git a/libcxx/include/memory b/libcxx/include/memory index a986d76..a5d2bfb 100644 --- a/libcxx/include/memory +++ b/libcxx/include/memory @@ -617,40 +617,44 @@ shared_ptr(unique_ptr<T, D>) -> shared_ptr<T>; template<class T, class U> bool operator==(shared_ptr<T> const& a, shared_ptr<U> const& b) noexcept; template<class T, class U> - bool operator!=(shared_ptr<T> const& a, shared_ptr<U> const& b) noexcept; + bool operator!=(shared_ptr<T> const& a, shared_ptr<U> const& b) noexcept; // removed in C++20 template<class T, class U> - bool operator<(shared_ptr<T> const& a, shared_ptr<U> const& b) noexcept; + bool operator<(shared_ptr<T> const& a, shared_ptr<U> const& b) noexcept; // removed in C++20 template<class T, class U> - bool operator>(shared_ptr<T> const& a, shared_ptr<U> const& b) noexcept; + bool operator>(shared_ptr<T> const& a, shared_ptr<U> const& b) noexcept; // removed in C++20 template<class T, class U> - bool operator<=(shared_ptr<T> const& a, shared_ptr<U> const& b) noexcept; + bool operator<=(shared_ptr<T> const& a, shared_ptr<U> const& b) noexcept; // removed in C++20 template<class T, class U> - bool operator>=(shared_ptr<T> const& a, shared_ptr<U> const& b) noexcept; + bool operator>=(shared_ptr<T> const& a, shared_ptr<U> const& b) noexcept; // removed in C++20 +template<class T, class U> + strong_ordering operator<=>(shared_ptr<T> const& a, shared_ptr<U> const& b) noexcept; // C++20 template <class T> bool operator==(const shared_ptr<T>& x, nullptr_t) noexcept; template <class T> - bool operator==(nullptr_t, const shared_ptr<T>& y) noexcept; + bool operator==(nullptr_t, const shared_ptr<T>& y) noexcept; // removed in C++20 template <class T> - bool operator!=(const shared_ptr<T>& x, nullptr_t) noexcept; + bool operator!=(const shared_ptr<T>& x, nullptr_t) noexcept; // removed in C++20 template <class T> - bool operator!=(nullptr_t, const shared_ptr<T>& y) noexcept; + bool operator!=(nullptr_t, const shared_ptr<T>& y) noexcept; // removed in C++20 template <class T> - bool operator<(const shared_ptr<T>& x, nullptr_t) noexcept; + bool operator<(const shared_ptr<T>& x, nullptr_t) noexcept; // removed in C++20 template <class T> -bool operator<(nullptr_t, const shared_ptr<T>& y) noexcept; + bool operator<(nullptr_t, const shared_ptr<T>& y) noexcept; // removed in C++20 template <class T> - bool operator<=(const shared_ptr<T>& x, nullptr_t) noexcept; + bool operator<=(const shared_ptr<T>& x, nullptr_t) noexcept; // removed in C++20 template <class T> - bool operator<=(nullptr_t, const shared_ptr<T>& y) noexcept; + bool operator<=(nullptr_t, const shared_ptr<T>& y) noexcept; // removed in C++20 template <class T> - bool operator>(const shared_ptr<T>& x, nullptr_t) noexcept; + bool operator>(const shared_ptr<T>& x, nullptr_t) noexcept; // removed in C++20 template <class T> - bool operator>(nullptr_t, const shared_ptr<T>& y) noexcept; + bool operator>(nullptr_t, const shared_ptr<T>& y) noexcept; // removed in C++20 template <class T> - bool operator>=(const shared_ptr<T>& x, nullptr_t) noexcept; + bool operator>=(const shared_ptr<T>& x, nullptr_t) noexcept; // removed in C++20 template <class T> - bool operator>=(nullptr_t, const shared_ptr<T>& y) noexcept; + bool operator>=(nullptr_t, const shared_ptr<T>& y) noexcept; // removed in C++20 +template<class T> + strong_ordering operator<=>(shared_ptr<T> const& x, nullptr_t) noexcept; // C++20 // shared_ptr specialized algorithms: template<class T> void swap(shared_ptr<T>& a, shared_ptr<T>& b) noexcept; diff --git a/libcxx/test/std/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.cmp/cmp.pass.cpp b/libcxx/test/std/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.cmp/cmp.pass.cpp new file mode 100644 index 0000000..00060ab --- /dev/null +++ b/libcxx/test/std/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.cmp/cmp.pass.cpp @@ -0,0 +1,76 @@ +//===----------------------------------------------------------------------===// +// +// 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> + +// shared_ptr + +// template<class T, class U> bool operator==(const shared_ptr<T>& a, const shared_ptr<U>& b); +// template<class T, class U> bool operator!=(const shared_ptr<T>& a, const shared_ptr<U>& b); +// template<class T, class U> bool operator< (const shared_ptr<T>& a, const shared_ptr<U>& b); +// template<class T, class U> bool operator<=(const shared_ptr<T>& a, const shared_ptr<U>& b); +// template<class T, class U> bool operator> (const shared_ptr<T>& a, const shared_ptr<U>& b); +// template<class T, class U> bool operator>=(const shared_ptr<T>& a, const shared_ptr<U>& b); +// 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 "test_comparisons.h" + +void do_nothing(int*) {} + +int main(int, char**) { + AssertComparisonsAreNoexcept<std::shared_ptr<int> >(); + AssertComparisonsReturnBool<std::shared_ptr<int> >(); +#if TEST_STD_VER > 17 + AssertOrderAreNoexcept<std::shared_ptr<int>>(); + AssertOrderReturn<std::strong_ordering, std::shared_ptr<int>>(); +#endif + + int* ptr1(new int); + int* ptr2(new int); + const std::shared_ptr<int> p1(ptr1); + const std::shared_ptr<int> 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 + + // The deleter does not influence the comparisons + // of the `shared_ptr` + const std::shared_ptr<int> p3(ptr2, do_nothing); + assert(p2 == p3); + assert(!(p1 == p3)); + assert(!(p2 != p3)); + assert(p1 != p3); + assert((p1 < p3) == (ptr1 < ptr2)); + assert((p1 <= p3) == (ptr1 <= ptr2)); + assert((p1 > p3) == (ptr1 > ptr2)); + assert((p1 >= p3) == (ptr1 >= ptr2)); +#if TEST_STD_VER > 17 + assert((p2 <=> p3) == std::strong_ordering::equal); + assert((p1 <=> p3) != std::strong_ordering::equal); + assert((p1 <=> p3) == (ptr1 <=> ptr2)); +#endif + + return 0; +} diff --git a/libcxx/test/std/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.cmp/cmp_nullptr.pass.cpp b/libcxx/test/std/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.cmp/cmp_nullptr.pass.cpp index bea3b4e..3bc8ef3 100644 --- a/libcxx/test/std/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.cmp/cmp_nullptr.pass.cpp +++ b/libcxx/test/std/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.cmp/cmp_nullptr.pass.cpp @@ -34,39 +34,58 @@ // bool operator>=(const shared_ptr<T>& x, nullptr_t) noexcept; // template <class T> // bool operator>=(nullptr_t, const shared_ptr<T>& y) noexcept; +// template<class T> +// strong_ordering operator<=>(shared_ptr<T> const& x, nullptr_t) noexcept; // C++20 #include <memory> #include <cassert> #include "test_macros.h" +#include "test_comparisons.h" void do_nothing(int*) {} int main(int, char**) { - const std::shared_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)); + AssertComparisonsAreNoexcept<std::shared_ptr<int>, nullptr_t>(); + AssertComparisonsAreNoexcept<nullptr_t, std::shared_ptr<int> >(); + AssertComparisonsReturnBool<std::shared_ptr<int>, nullptr_t>(); + AssertComparisonsReturnBool<nullptr_t, std::shared_ptr<int> >(); +#if TEST_STD_VER > 17 + AssertOrderAreNoexcept<std::shared_ptr<int>>(); + AssertOrderReturn<std::strong_ordering, std::shared_ptr<int>>(); +#endif - const std::shared_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::shared_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::shared_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/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.cmp/eq.pass.cpp b/libcxx/test/std/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.cmp/eq.pass.cpp deleted file mode 100644 index 2d1cee8..0000000 --- a/libcxx/test/std/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.cmp/eq.pass.cpp +++ /dev/null @@ -1,34 +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> - -// shared_ptr - -// template<class T, class U> bool operator==(const shared_ptr<T>& a, const shared_ptr<U>& b); -// template<class T, class U> bool operator!=(const shared_ptr<T>& a, const shared_ptr<U>& b); - -#include <memory> -#include <cassert> - -#include "test_macros.h" - -void do_nothing(int*) {} - -int main(int, char**) -{ - int* ptr1(new int); - int* ptr2(new int); - const std::shared_ptr<int> p1(ptr1); - const std::shared_ptr<int> p2(ptr2); - const std::shared_ptr<int> p3(ptr2, do_nothing); - assert(p1 != p2); - assert(p2 == p3); - - return 0; -} diff --git a/libcxx/test/std/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.cmp/lt.pass.cpp b/libcxx/test/std/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.cmp/lt.pass.cpp deleted file mode 100644 index 478cb6c..0000000 --- a/libcxx/test/std/utilities/memory/util.smartptr/util.smartptr.shared/util.smartptr.shared.cmp/lt.pass.cpp +++ /dev/null @@ -1,33 +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> - -// shared_ptr - -// template<class T, class U> bool operator<(const shared_ptr<T>& a, const shared_ptr<U>& b); - -#include <memory> -#include <cassert> - -#include "test_macros.h" - -void do_nothing(int*) {} - -int main(int, char**) -{ - int* ptr1(new int); - int* ptr2(new int); - const std::shared_ptr<int> p1(ptr1); - const std::shared_ptr<int> p2(ptr2); - const std::shared_ptr<int> p3(ptr2, do_nothing); - assert((p1 < p2) == (ptr1 < ptr2)); - assert(!(p2 < p3) && !(p3 < p2)); - - return 0; -} |