[libcxx-commits] [libcxx] [libc++][memory_resource] Implements LWG3683. (PR #100775)

Mark de Wever via libcxx-commits libcxx-commits at lists.llvm.org
Sat Jul 27 11:12:20 PDT 2024


https://github.com/mordante updated https://github.com/llvm/llvm-project/pull/100775

>From 9b0b123a96464bc91ed39e2ffa23f2ad6a337dfb Mon Sep 17 00:00:00 2001
From: Mark de Wever <koraq at xs4all.nl>
Date: Wed, 10 Jul 2024 18:34:54 +0200
Subject: [PATCH 1/2] [libc++][memory_resource] Implements LWG3683.

The polymorphic_allocator was added in C++17.
This issue was filed in 2022 so well after C++20. This issue adds an
operator==.

Starting with C++20 this adds a compiler generated operator!=. To have the
same behaviour in C++17 and C++20 (and later) a manual operator!= is defined in
C++17.

Implements
- LWG3683 operator== for polymorphic_allocator cannot deduce template argument in common cases
---
 libcxx/docs/Status/Cxx23Issues.csv            |  2 +-
 .../__memory_resource/polymorphic_allocator.h | 11 +++++
 .../equality.pass.cpp                         | 44 +++++++++++++++++++
 3 files changed, 56 insertions(+), 1 deletion(-)
 create mode 100644 libcxx/test/std/utilities/utility/mem.res/mem.poly.allocator.class/mem.poly.allocator.class.general/equality.pass.cpp

diff --git a/libcxx/docs/Status/Cxx23Issues.csv b/libcxx/docs/Status/Cxx23Issues.csv
index e1a5aa6dd952a..02fcea1a606d1 100644
--- a/libcxx/docs/Status/Cxx23Issues.csv
+++ b/libcxx/docs/Status/Cxx23Issues.csv
@@ -166,7 +166,7 @@
 "`3670 <https://wg21.link/LWG3670>`__","``Cpp17InputIterators`` don't have integer-class difference types","July 2022","","","|ranges|"
 "`3671 <https://wg21.link/LWG3671>`__","``atomic_fetch_xor`` missing from ``stdatomic.h``","July 2022","",""
 "`3672 <https://wg21.link/LWG3672>`__","``common_iterator::operator->()`` should return by value","July 2022","|Complete|","19.0","|ranges|"
-"`3683 <https://wg21.link/LWG3683>`__","``operator==`` for ``polymorphic_allocator`` cannot deduce template argument in common cases","July 2022","",""
+"`3683 <https://wg21.link/LWG3683>`__","``operator==`` for ``polymorphic_allocator`` cannot deduce template argument in common cases","July 2022","|Complete|","20.0"
 "`3687 <https://wg21.link/LWG3687>`__","``expected<cv void, E>`` move constructor should move","July 2022","|Complete|","16.0"
 "`3692 <https://wg21.link/LWG3692>`__","``zip_view::iterator``'s ``operator<=>`` is overconstrained","July 2022","","","|ranges| |spaceship|"
 "`3701 <https://wg21.link/LWG3701>`__","Make ``formatter<remove_cvref_t<const charT[N]>, charT>`` requirement explicit","July 2022","|Complete|","15.0","|format|"
diff --git a/libcxx/include/__memory_resource/polymorphic_allocator.h b/libcxx/include/__memory_resource/polymorphic_allocator.h
index a71096d3e4784..a1a9e5ae8eee3 100644
--- a/libcxx/include/__memory_resource/polymorphic_allocator.h
+++ b/libcxx/include/__memory_resource/polymorphic_allocator.h
@@ -174,6 +174,17 @@ class _LIBCPP_AVAILABILITY_PMR _LIBCPP_TEMPLATE_VIS polymorphic_allocator {
 
   _LIBCPP_HIDE_FROM_ABI memory_resource* resource() const noexcept { return __res_; }
 
+  friend bool operator==(const polymorphic_allocator& __lhs, const polymorphic_allocator& __rhs) noexcept {
+    return *__lhs.resource() == *__rhs.resource();
+  }
+
+#  if _LIBCPP_STD_VER == 17
+  // This overload is not specified, it was added due to LWG3683.
+  friend bool operator!=(const polymorphic_allocator& __lhs, const polymorphic_allocator& __rhs) noexcept {
+    return *__lhs.resource() != *__rhs.resource();
+  }
+#  endif
+
 private:
   template <class... _Args, size_t... _Is>
   _LIBCPP_HIDE_FROM_ABI tuple<_Args&&...>
diff --git a/libcxx/test/std/utilities/utility/mem.res/mem.poly.allocator.class/mem.poly.allocator.class.general/equality.pass.cpp b/libcxx/test/std/utilities/utility/mem.res/mem.poly.allocator.class/mem.poly.allocator.class.general/equality.pass.cpp
new file mode 100644
index 0000000000000..3210b9b449a31
--- /dev/null
+++ b/libcxx/test/std/utilities/utility/mem.res/mem.poly.allocator.class/mem.poly.allocator.class.general/equality.pass.cpp
@@ -0,0 +1,44 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++03, c++11, c++14
+// TODO: Change to XFAIL once https://github.com/llvm/llvm-project/issues/40340 is fixed
+// UNSUPPORTED: availability-pmr-missing
+
+// <memory_resource>
+
+// template <class T> class polymorphic_allocator
+
+// friend bool operator==(const polymorphic_allocator& a,
+//                        const polymorphic_allocator& b) noexcept
+
+#include <memory_resource>
+#include <cassert>
+#include <vector>
+
+#include "test_macros.h"
+
+int main(int, char**) {
+  std::pmr::unsynchronized_pool_resource a;
+  std::pmr::vector<int> vec(&a);
+
+  assert(vec.get_allocator() == &a);
+  static_assert(noexcept(vec.get_allocator() == &a));
+
+#if _LIBCPP_VERSION || TEST_STD_VER >= 20
+  // LWG3683 added operator== after C++20. In C++20 operator!= is generated by
+  // the compiler. Libc++ adds operator!= in C++17 as an extension.
+  std::pmr::unsynchronized_pool_resource b;
+
+  assert(vec.get_allocator() != &b);
+  static_assert(noexcept(vec.get_allocator() != &b));
+
+#endif // _LIBCPP_VERSION || TEST_STD_VER >= 20
+
+  return 0;
+}

>From 5e09567b519859a9012037f825e1f761bf74d115 Mon Sep 17 00:00:00 2001
From: Mark de Wever <koraq at xs4all.nl>
Date: Sat, 27 Jul 2024 20:12:07 +0200
Subject: [PATCH 2/2] Addresses review comments.

---
 libcxx/include/__memory_resource/polymorphic_allocator.h   | 2 +-
 .../mem.poly.allocator.class.general/equality.pass.cpp     | 7 ++-----
 2 files changed, 3 insertions(+), 6 deletions(-)

diff --git a/libcxx/include/__memory_resource/polymorphic_allocator.h b/libcxx/include/__memory_resource/polymorphic_allocator.h
index a1a9e5ae8eee3..3444e9575e1af 100644
--- a/libcxx/include/__memory_resource/polymorphic_allocator.h
+++ b/libcxx/include/__memory_resource/polymorphic_allocator.h
@@ -178,7 +178,7 @@ class _LIBCPP_AVAILABILITY_PMR _LIBCPP_TEMPLATE_VIS polymorphic_allocator {
     return *__lhs.resource() == *__rhs.resource();
   }
 
-#  if _LIBCPP_STD_VER == 17
+#  if _LIBCPP_STD_VER <= 17
   // This overload is not specified, it was added due to LWG3683.
   friend bool operator!=(const polymorphic_allocator& __lhs, const polymorphic_allocator& __rhs) noexcept {
     return *__lhs.resource() != *__rhs.resource();
diff --git a/libcxx/test/std/utilities/utility/mem.res/mem.poly.allocator.class/mem.poly.allocator.class.general/equality.pass.cpp b/libcxx/test/std/utilities/utility/mem.res/mem.poly.allocator.class/mem.poly.allocator.class.general/equality.pass.cpp
index 3210b9b449a31..792f05d2f82f4 100644
--- a/libcxx/test/std/utilities/utility/mem.res/mem.poly.allocator.class/mem.poly.allocator.class.general/equality.pass.cpp
+++ b/libcxx/test/std/utilities/utility/mem.res/mem.poly.allocator.class/mem.poly.allocator.class.general/equality.pass.cpp
@@ -7,7 +7,6 @@
 //===----------------------------------------------------------------------===//
 
 // UNSUPPORTED: c++03, c++11, c++14
-// TODO: Change to XFAIL once https://github.com/llvm/llvm-project/issues/40340 is fixed
 // UNSUPPORTED: availability-pmr-missing
 
 // <memory_resource>
@@ -30,15 +29,13 @@ int main(int, char**) {
   assert(vec.get_allocator() == &a);
   static_assert(noexcept(vec.get_allocator() == &a));
 
-#if _LIBCPP_VERSION || TEST_STD_VER >= 20
   // LWG3683 added operator== after C++20. In C++20 operator!= is generated by
-  // the compiler. Libc++ adds operator!= in C++17 as an extension.
+  // the compiler. Libc++ adds operator!= in C++17 as an extension. MSVC STL
+  // and libstdc++ have done the same so test this extension unconditionally.
   std::pmr::unsynchronized_pool_resource b;
 
   assert(vec.get_allocator() != &b);
   static_assert(noexcept(vec.get_allocator() != &b));
 
-#endif // _LIBCPP_VERSION || TEST_STD_VER >= 20
-
   return 0;
 }



More information about the libcxx-commits mailing list