-
Notifications
You must be signed in to change notification settings - Fork 14.3k
[libc++] Reland LWG2921 and LWG2976 #107960
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
@llvm/pr-subscribers-libcxx Author: A. Jiang (frederick-vs-ja) ChangesThey were originally implemented in d42db7e but reverted later in a2f3c63. This PR implement both LWG issues again, guarding the removed functions with Fixes #103598. Fixes #103755. Full diff: https://github.com/llvm/llvm-project/pull/107960.diff 4 Files Affected:
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
|
Should these issues be reopened first before landing? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM with minor comment. Thanks for spotting this!
They were originally implemented in d42db7e but reverted later in a2f3c63.
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.Fixes #103598. Fixes #103755.