On 25/04/19 23:43 +0100, Jonathan Wakely wrote:
PR libstdc++/90239
* doc/xml/manual/status_cxx2020.xml: Amend P0591R4 status.
* include/std/scoped_allocator [__cplusplus > 201703L]
(scoped_allocator_adaptor::construct): Define in terms of
uses_allocator_construction_args, as per P0591R4.
* testsuite/20_util/scoped_allocator/construct_pair_c++2a.cc: New test.
* testsuite/util/testsuite_allocator.h: Remove name of unused
parameter.
Tested powerpc64le-linux, committed to trunk.
Here's a follow-up which adds a similar test for polymorphic_allocator
(which was already using the new utilities so already had the correct
c++2a behaviour, but it was untested).
Tested powerpc64le-linux, using default flags, and also -std=gnu++2a
and also -std=gnu++2a/-fconcepts.
Committed to trunk.
I'll backport this to gcc-9-branch after the 9.1.0 release.
Richi said the previous patch is OK to backport now, so I'll ask about
this one too (which also only touches C++2a code) after testing on the
branch.
commit 771a0481d6b388c1485ecbd5747aeee9f075edbe
Author: Jonathan Wakely <jwak...@redhat.com>
Date: Fri Apr 26 13:10:10 2019 +0100
Tweak C++2a uses-allocator construction utilities
The 20_util/scoped_allocator/69293_neg.cc test was failing in C++2a mode
because the expected static_assert text wasn't matched. The code is
still ill-formed in C++2a, but uses the new __uses_alloc_args function
and so fails a different static_assert. This patch adds the same string
to the new static_assert, so the test passes.
Now that G++ allows concepts to be declared without 'bool' we can use
the correct C++2a syntax for the _Std_pair concept used to constrain the
uses-allocator construction utilities.
Also add a new test to verify that pmr::polymorphic_allocator correctly
performs recursive uses-allocator construction for nested pairs in
C++2a.
* include/std/memory (__uses_alloc_args): Add string-literal to
static_assert, to match the one in __uses_alloc.
[__cpp_concepts] (_Std_pair): Use C++2a syntax for concept.
* testsuite/20_util/polymorphic_allocator/construct_c++2a.cc: Check
for recursive uses-allocator construction of nested pairs.
* testsuite/20_util/scoped_allocator/construct_pair_c++2a.cc:: Add
comment.
diff --git a/libstdc++-v3/include/std/memory b/libstdc++-v3/include/std/memory
index 57ccf93de86..6677fe782de 100644
--- a/libstdc++-v3/include/std/memory
+++ b/libstdc++-v3/include/std/memory
@@ -191,7 +191,9 @@ get_pointer_safety() noexcept { return pointer_safety::relaxed; }
}
else
{
- static_assert(is_constructible_v<_Tp, _Args..., const _Alloc&>);
+ static_assert(is_constructible_v<_Tp, _Args..., const _Alloc&>,
+ "construction with an allocator must be possible"
+ " if uses_allocator is true");
return tuple<_Args&&..., const _Alloc&>(
std::forward<_Args>(__args)..., __a);
@@ -207,7 +209,7 @@ get_pointer_safety() noexcept { return pointer_safety::relaxed; }
#if __cpp_concepts
template<typename _Tp>
- concept bool _Std_pair = __is_pair<_Tp>::value;
+ concept _Std_pair = __is_pair<_Tp>::value;
#endif
// This is a temporary workaround until -fconcepts is implied by -std=gnu++2a
diff --git a/libstdc++-v3/testsuite/20_util/polymorphic_allocator/construct_c++2a.cc b/libstdc++-v3/testsuite/20_util/polymorphic_allocator/construct_c++2a.cc
index 9048ca196ff..df01dccafe1 100644
--- a/libstdc++-v3/testsuite/20_util/polymorphic_allocator/construct_c++2a.cc
+++ b/libstdc++-v3/testsuite/20_util/polymorphic_allocator/construct_c++2a.cc
@@ -21,6 +21,8 @@
#include <memory_resource>
#include <utility>
#include <tuple>
+#include <testsuite_hooks.h>
+#include <testsuite_allocator.h>
struct do_not_copy {
do_not_copy() = default;
@@ -115,6 +117,54 @@ test05()
a.deallocate(ptr, 1);
}
+// P0591R4 makes uses-allocator construction apply recursively for nested pairs
+void
+test06()
+{
+ struct X
+ {
+ using allocator_type = std::pmr::polymorphic_allocator<int>;
+ X() = default;
+ X(const X&) { throw 1; }
+ X(const X&, const allocator_type& a) : mr(a.resource()) { }
+
+ std::pmr::memory_resource* mr = nullptr;
+ };
+
+ struct Y
+ {
+ using allocator_type = std::pmr::polymorphic_allocator<int>;
+ Y() = default;
+ Y(const Y&) = delete;
+ Y(std::allocator_arg_t, const allocator_type& a, const Y&)
+ : mr(a.resource()) { }
+
+ std::pmr::memory_resource* mr = nullptr;
+ };
+
+ using value_type = std::pair<std::pair<X, int>, std::pair<int, Y>>;
+ __gnu_test::memory_resource mr;
+ std::pmr::polymorphic_allocator<int> a(&mr);
+ std::pmr::vector<value_type> v(a);
+ VERIFY( v.get_allocator().resource() == &mr );
+
+ value_type val;
+ val.first.second = 2;
+ val.second.first = 3;
+ v.push_back(val);
+ X& x = v.back().first.first;
+ VERIFY( x.mr != val.first.first.mr );
+ VERIFY( x.mr == &mr );
+
+ Y& y = v.back().second.second;
+ VERIFY( y.mr != val.second.second.mr );
+ VERIFY( y.mr == &mr );
+
+ // Check other members of the pairs are correctly initialized too:
+ VERIFY( v.back().first.second == val.first.second );
+ VERIFY( v.back().second.first == val.second.first );
+}
+
int main()
{
test01();
@@ -122,4 +172,5 @@ int main()
test03();
test04();
test05();
+ test06();
}
diff --git a/libstdc++-v3/testsuite/20_util/scoped_allocator/construct_pair_c++2a.cc b/libstdc++-v3/testsuite/20_util/scoped_allocator/construct_pair_c++2a.cc
index 1630f2a4d09..09050b2bc08 100644
--- a/libstdc++-v3/testsuite/20_util/scoped_allocator/construct_pair_c++2a.cc
+++ b/libstdc++-v3/testsuite/20_util/scoped_allocator/construct_pair_c++2a.cc
@@ -18,6 +18,8 @@
// { dg-options "-std=gnu++2a" }
// { dg-do run { target c++2a } }
+// P0591R4 makes uses-allocator construction apply recursively for nested pairs
+
#include <scoped_allocator>
#include <vector>
#include <testsuite_hooks.h>