[libcxx-commits] [libcxx] [libc++] Reland LWG2921 and LWG2976 (PR #107960)

A. Jiang via libcxx-commits libcxx-commits at lists.llvm.org
Tue Sep 10 06:09:50 PDT 2024


https://github.com/frederick-vs-ja updated https://github.com/llvm/llvm-project/pull/107960

>From a7378633ee868146dc46f7e108c2a0c63956f4cf Mon Sep 17 00:00:00 2001
From: "A. Jiang" <de34 at live.cn>
Date: Tue, 10 Sep 2024 11:42:09 +0800
Subject: [PATCH 1/2] [libc++] Reland LWG2921 and LWG2976

They were originally implemented in
d42db7e083ee0edda327782aa122ad6474c126d1 but reverted later in
a2f3c63282330be0226158cdfdc27c4c2aef9cdc. This PR implement both LWG
issues again, guarding the removed functions with
`_LIBCPP_STD_VER <= 14`, because they should be treated as patches for
P0302R1 which was adopted for C++17.
---
 libcxx/docs/Status/Cxx17Issues.csv            |  2 +-
 libcxx/docs/Status/Cxx20Issues.csv            |  2 +-
 libcxx/include/future                         | 14 ++++++++++++--
 .../ctor2.compile.pass.cpp                    | 19 ++++++++++++++-----
 4 files changed, 28 insertions(+), 9 deletions(-)

diff --git a/libcxx/docs/Status/Cxx17Issues.csv b/libcxx/docs/Status/Cxx17Issues.csv
index 7119382eb5cfb4..af3dee9ca50c98 100644
--- a/libcxx/docs/Status/Cxx17Issues.csv
+++ b/libcxx/docs/Status/Cxx17Issues.csv
@@ -306,7 +306,7 @@
 "`LWG2905 <https://wg21.link/LWG2905>`__","is_constructible_v<unique_ptr<P, D>, P, D const &> should be false when D is not copy constructible","2017-02 (Kona)","|Complete|","",""
 "`LWG2908 <https://wg21.link/LWG2908>`__","The less-than operator for shared pointers could do more","2017-02 (Kona)","|Complete|","",""
 "`LWG2911 <https://wg21.link/LWG2911>`__","An is_aggregate type trait is needed","2017-02 (Kona)","|Complete|","",""
-"`LWG2921 <https://wg21.link/LWG2921>`__","packaged_task and type-erased allocators","2017-02 (Kona)","|Complete|","",""
+"`LWG2921 <https://wg21.link/LWG2921>`__","packaged_task and type-erased allocators","2017-02 (Kona)","|Complete|","20.0","Originally implemented in LLVM 6.0 but reverted later. Old documentation incorrectly said it was implemented."
 "`LWG2934 <https://wg21.link/LWG2934>`__","optional<const T> doesn't compare with T","2017-02 (Kona)","|Complete|","",""
 "","","","","",""
 "`LWG2901 <https://wg21.link/LWG2901>`__","Variants cannot properly support allocators","2017-07 (Toronto)","|Complete|","",""
diff --git a/libcxx/docs/Status/Cxx20Issues.csv b/libcxx/docs/Status/Cxx20Issues.csv
index e5d2498473ecde..8c4224616d73e6 100644
--- a/libcxx/docs/Status/Cxx20Issues.csv
+++ b/libcxx/docs/Status/Cxx20Issues.csv
@@ -27,7 +27,7 @@
 "`LWG2964 <https://wg21.link/LWG2964>`__","Apparently redundant requirement for dynamic_pointer_cast","2017-11 (Albuquerque)","","",""
 "`LWG2965 <https://wg21.link/LWG2965>`__","Non-existing path::native_string() in filesystem_error::what() specification","2017-11 (Albuquerque)","|Nothing To Do|","",""
 "`LWG2972 <https://wg21.link/LWG2972>`__","What is ``is_trivially_destructible_v<int>``\ ?","2017-11 (Albuquerque)","|Complete|","",""
-"`LWG2976 <https://wg21.link/LWG2976>`__","Dangling uses_allocator specialization for packaged_task","2017-11 (Albuquerque)","|Complete|","",""
+"`LWG2976 <https://wg21.link/LWG2976>`__","Dangling uses_allocator specialization for packaged_task","2017-11 (Albuquerque)","|Complete|","20.0","Originally implemented in LLVM 6.0 but reverted later. Old documentation incorrectly said it was implemented."
 "`LWG2977 <https://wg21.link/LWG2977>`__","unordered_meow::merge() has incorrect Throws: clause","2017-11 (Albuquerque)","|Nothing To Do|","",""
 "`LWG2978 <https://wg21.link/LWG2978>`__","Hash support for pmr::string and friends","2017-11 (Albuquerque)","|Complete|","16.0",""
 "`LWG2979 <https://wg21.link/LWG2979>`__","aligned_union should require complete object types","2017-11 (Albuquerque)","|Complete|","",""
diff --git a/libcxx/include/future b/libcxx/include/future
index 01c0b10172cd3b..b52bcc7e25452f 100644
--- a/libcxx/include/future
+++ b/libcxx/include/future
@@ -329,7 +329,7 @@ public:
     template <class F>
         explicit packaged_task(F&& f);
     template <class F, class Allocator>
-        packaged_task(allocator_arg_t, const Allocator& a, F&& f);
+        packaged_task(allocator_arg_t, const Allocator& a, F&& f);              // removed in C++17
     ~packaged_task();
 
     // no copy
@@ -356,7 +356,7 @@ public:
 template <class R>
   void swap(packaged_task<R(ArgTypes...)&, packaged_task<R(ArgTypes...)>&) noexcept;
 
-template <class R, class Alloc> struct uses_allocator<packaged_task<R>, Alloc>;
+template <class R, class Alloc> struct uses_allocator<packaged_task<R>, Alloc>; // removed in C++17
 
 }  // std
 
@@ -1460,8 +1460,10 @@ public:
   _LIBCPP_HIDE_FROM_ABI __packaged_task_function() _NOEXCEPT : __f_(nullptr) {}
   template <class _Fp>
   _LIBCPP_HIDE_FROM_ABI __packaged_task_function(_Fp&& __f);
+#  if _LIBCPP_STD_VER <= 14
   template <class _Fp, class _Alloc>
   _LIBCPP_HIDE_FROM_ABI __packaged_task_function(allocator_arg_t, const _Alloc& __a, _Fp&& __f);
+#  endif
 
   _LIBCPP_HIDE_FROM_ABI __packaged_task_function(__packaged_task_function&&) _NOEXCEPT;
   _LIBCPP_HIDE_FROM_ABI __packaged_task_function& operator=(__packaged_task_function&&) _NOEXCEPT;
@@ -1507,6 +1509,7 @@ __packaged_task_function<_Rp(_ArgTypes...)>::__packaged_task_function(_Fp&& __f)
   }
 }
 
+#  if _LIBCPP_STD_VER <= 14
 template <class _Rp, class... _ArgTypes>
 template <class _Fp, class _Alloc>
 __packaged_task_function<_Rp(_ArgTypes...)>::__packaged_task_function(allocator_arg_t, const _Alloc& __a0, _Fp&& __f)
@@ -1525,6 +1528,7 @@ __packaged_task_function<_Rp(_ArgTypes...)>::__packaged_task_function(allocator_
     __f_ = std::addressof(*__hold.release());
   }
 }
+#  endif
 
 template <class _Rp, class... _ArgTypes>
 __packaged_task_function<_Rp(_ArgTypes...)>&
@@ -1606,9 +1610,11 @@ public:
   template <class _Fp, __enable_if_t<!is_same<__remove_cvref_t<_Fp>, packaged_task>::value, int> = 0>
   _LIBCPP_HIDE_FROM_ABI explicit packaged_task(_Fp&& __f) : __f_(std::forward<_Fp>(__f)) {}
 
+#  if _LIBCPP_STD_VER <= 14
   template <class _Fp, class _Allocator, __enable_if_t<!is_same<__remove_cvref_t<_Fp>, packaged_task>::value, int> = 0>
   _LIBCPP_HIDE_FROM_ABI packaged_task(allocator_arg_t, const _Allocator& __a, _Fp&& __f)
       : __f_(allocator_arg_t(), __a, std::forward<_Fp>(__f)), __p_(allocator_arg_t(), __a) {}
+#  endif
   // ~packaged_task() = default;
 
   // no copy
@@ -1696,9 +1702,11 @@ public:
   _LIBCPP_HIDE_FROM_ABI packaged_task() _NOEXCEPT : __p_(nullptr) {}
   template <class _Fp, __enable_if_t<!is_same<__remove_cvref_t<_Fp>, packaged_task>::value, int> = 0>
   _LIBCPP_HIDE_FROM_ABI explicit packaged_task(_Fp&& __f) : __f_(std::forward<_Fp>(__f)) {}
+#  if _LIBCPP_STD_VER <= 14
   template <class _Fp, class _Allocator, __enable_if_t<!is_same<__remove_cvref_t<_Fp>, packaged_task>::value, int> = 0>
   _LIBCPP_HIDE_FROM_ABI packaged_task(allocator_arg_t, const _Allocator& __a, _Fp&& __f)
       : __f_(allocator_arg_t(), __a, std::forward<_Fp>(__f)), __p_(allocator_arg_t(), __a) {}
+#  endif
   // ~packaged_task() = default;
 
   // no copy
@@ -1790,8 +1798,10 @@ swap(packaged_task<_Rp(_ArgTypes...)>& __x, packaged_task<_Rp(_ArgTypes...)>& __
   __x.swap(__y);
 }
 
+#  if _LIBCPP_STD_VER <= 14
 template <class _Callable, class _Alloc>
 struct _LIBCPP_TEMPLATE_VIS uses_allocator<packaged_task<_Callable>, _Alloc> : public true_type {};
+#  endif
 
 template <class _Rp, class _Fp>
 _LIBCPP_HIDE_FROM_ABI future<_Rp> __make_deferred_assoc_state(_Fp&& __f) {
diff --git a/libcxx/test/std/thread/futures/futures.task/futures.task.members/ctor2.compile.pass.cpp b/libcxx/test/std/thread/futures/futures.task/futures.task.members/ctor2.compile.pass.cpp
index 3ab59909cfafbe..a3bdd45975c96f 100644
--- a/libcxx/test/std/thread/futures/futures.task/futures.task.members/ctor2.compile.pass.cpp
+++ b/libcxx/test/std/thread/futures/futures.task/futures.task.members/ctor2.compile.pass.cpp
@@ -18,11 +18,13 @@
 
 #include <cassert>
 #include <future>
+#include <memory>
+#include <type_traits>
 
 #include "test_allocator.h"
 
 struct A {};
-using PT = std::packaged_task<A(int, char)>;
+using PT  = std::packaged_task<A(int, char)>;
 using VPT = volatile std::packaged_task<A(int, char)>;
 
 static_assert(!std::is_constructible<PT, std::allocator_arg_t, test_allocator<A>, VPT>::value, "");
@@ -35,7 +37,14 @@ static_assert(!std::is_constructible<PA, std::allocator_arg_t, std::allocator<A>
 static_assert(!std::is_constructible<PA, std::allocator_arg_t, std::allocator<A>, volatile PA&>::value, "");
 static_assert(!std::is_constructible<PA, std::allocator_arg_t, std::allocator<A>, volatile PA&&>::value, "");
 
-static_assert( std::is_constructible<PA, std::allocator_arg_t, std::allocator<A>, const PI&>::value, "");
-static_assert( std::is_constructible<PA, std::allocator_arg_t, std::allocator<A>, const PI&&>::value, "");
-static_assert( std::is_constructible<PA, std::allocator_arg_t, std::allocator<A>, volatile PI&>::value, "");
-static_assert( std::is_constructible<PA, std::allocator_arg_t, std::allocator<A>, volatile PI&&>::value, "");
+#if TEST_STD_VER >= 17 // packaged_task allocator support was removed in C++17 (LWG 2921)
+static_assert(!std::is_constructible_v<PA, std::allocator_arg_t, std::allocator<A>, const PI&>);
+static_assert(!std::is_constructible_v<PA, std::allocator_arg_t, std::allocator<A>, const PI&&>);
+static_assert(!std::is_constructible_v<PA, std::allocator_arg_t, std::allocator<A>, volatile PI&>);
+static_assert(!std::is_constructible_v<PA, std::allocator_arg_t, std::allocator<A>, volatile PI&&>);
+#else
+static_assert(std::is_constructible<PA, std::allocator_arg_t, std::allocator<A>, const PI&>::value, "");
+static_assert(std::is_constructible<PA, std::allocator_arg_t, std::allocator<A>, const PI&&>::value, "");
+static_assert(std::is_constructible<PA, std::allocator_arg_t, std::allocator<A>, volatile PI&>::value, "");
+static_assert(std::is_constructible<PA, std::allocator_arg_t, std::allocator<A>, volatile PI&&>::value, "");
+#endif

>From 5a7cec41ba8d3da8c549a7a0f5d6d5fb610cdc84 Mon Sep 17 00:00:00 2001
From: "A. Jiang" <de34 at live.cn>
Date: Tue, 10 Sep 2024 21:09:41 +0800
Subject: [PATCH 2/2] Unguard implementation details

---
 libcxx/include/future | 4 ----
 1 file changed, 4 deletions(-)

diff --git a/libcxx/include/future b/libcxx/include/future
index b52bcc7e25452f..4e9039ea425434 100644
--- a/libcxx/include/future
+++ b/libcxx/include/future
@@ -1460,10 +1460,8 @@ public:
   _LIBCPP_HIDE_FROM_ABI __packaged_task_function() _NOEXCEPT : __f_(nullptr) {}
   template <class _Fp>
   _LIBCPP_HIDE_FROM_ABI __packaged_task_function(_Fp&& __f);
-#  if _LIBCPP_STD_VER <= 14
   template <class _Fp, class _Alloc>
   _LIBCPP_HIDE_FROM_ABI __packaged_task_function(allocator_arg_t, const _Alloc& __a, _Fp&& __f);
-#  endif
 
   _LIBCPP_HIDE_FROM_ABI __packaged_task_function(__packaged_task_function&&) _NOEXCEPT;
   _LIBCPP_HIDE_FROM_ABI __packaged_task_function& operator=(__packaged_task_function&&) _NOEXCEPT;
@@ -1509,7 +1507,6 @@ __packaged_task_function<_Rp(_ArgTypes...)>::__packaged_task_function(_Fp&& __f)
   }
 }
 
-#  if _LIBCPP_STD_VER <= 14
 template <class _Rp, class... _ArgTypes>
 template <class _Fp, class _Alloc>
 __packaged_task_function<_Rp(_ArgTypes...)>::__packaged_task_function(allocator_arg_t, const _Alloc& __a0, _Fp&& __f)
@@ -1528,7 +1525,6 @@ __packaged_task_function<_Rp(_ArgTypes...)>::__packaged_task_function(allocator_
     __f_ = std::addressof(*__hold.release());
   }
 }
-#  endif
 
 template <class _Rp, class... _ArgTypes>
 __packaged_task_function<_Rp(_ArgTypes...)>&



More information about the libcxx-commits mailing list