+2019-05-10 Jonathan Wakely <jwakely@redhat.com>
+
+ Backport from mainline
+ 2019-04-25 Jonathan Wakely <jwakely@redhat.com>
+
+ 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.
+ * doc/html/*: Regenerate.
+
2019-05-03 Release Manager
* GCC 9.1.0 released.
<a class="link" href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2018/p0487r1.html" target="_top">
P0487R1
</a>
- </td><td align="center"> </td><td align="left"> </td></tr><tr bgcolor="#B0B0B0"><td align="left"> Utility functions to implement uses-allocator construction </td><td align="left">
+ </td><td align="center"> </td><td align="left"> </td></tr><tr><td align="left"> Utility functions to implement uses-allocator construction </td><td align="left">
<a class="link" href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2018/p0591r4.pdf" target="_top">
P0591R4
</a>
- </td><td align="center"> 9.1 </td><td align="left">Missing changes to <code class="code">std::scoped_allocator_adaptor</code></td></tr><tr><td align="left"> P0595R2 <code class="code">std::is_constant_evaluated()</code> </td><td align="left">
+ </td><td align="center"> 9.1 </td><td align="left">
+ <code class="code">std::scoped_allocator_adaptor</code> changes missing in 9.1.0
+ </td></tr><tr><td align="left"> P0595R2 <code class="code">std::is_constant_evaluated()</code> </td><td align="left">
<a class="link" href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2018/p0595r2.html" target="_top">
P0595R2
</a>
</row>
<row>
- <?dbhtml bgcolor="#B0B0B0" ?>
<entry> Utility functions to implement uses-allocator construction </entry>
<entry>
<link xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2018/p0591r4.pdf">
</link>
</entry>
<entry align="center"> 9.1 </entry>
- <entry>Missing changes to <code>std::scoped_allocator_adaptor</code></entry>
+ <entry>
+ <code>std::scoped_allocator_adaptor</code> changes missing in 9.1.0
+ </entry>
</row>
<row>
# include <bits/c++0x_warning.h>
#else
+#include <memory>
#include <utility>
#include <tuple>
#include <bits/alloc_traits.h>
using __outermost_alloc_traits
= allocator_traits<typename __outermost_type<_Alloc>::type>;
+#if __cplusplus <= 201703
template<typename _Tp, typename... _Args>
void
_M_construct(__uses_alloc0, _Tp* __p, _Args&&... __args)
std::forward<_Args>(__args)...,
inner_allocator());
}
+#endif // C++17
template<typename _Alloc>
static _Alloc
size_type max_size() const
{ return __traits::max_size(outer_allocator()); }
+#if __cplusplus <= 201703
template<typename _Tp, typename... _Args>
typename __not_pair<_Tp>::type
construct(_Tp* __p, _Args&&... __args)
std::forward_as_tuple(std::forward<_Up>(__x.first)),
std::forward_as_tuple(std::forward<_Vp>(__x.second)));
}
+#else // C++2a
+ template<typename _Tp, typename... _Args>
+ __attribute__((__nonnull__))
+ void
+ construct(_Tp* __p, _Args&&... __args)
+ {
+ typedef __outermost_alloc_traits<scoped_allocator_adaptor> _O_traits;
+ std::apply([__p, this](auto&&... __newargs) {
+ _O_traits::construct(__outermost(*this), __p,
+ std::forward<decltype(__newargs)>(__newargs)...);
+ },
+ uses_allocator_construction_args<_Tp>(inner_allocator(),
+ std::forward<_Args>(__args)...));
+ }
+#endif // C++2a
template<typename _Tp>
void destroy(_Tp* __p)
const scoped_allocator_adaptor<_OutA2, _InA...>& __b) noexcept;
private:
+#if __cplusplus <= 201703L
template<typename _Ind, typename... _Args>
tuple<_Args&&...>
_M_construct_p(__uses_alloc0, _Ind, tuple<_Args...>& __t)
{
return { std::get<_Ind>(std::move(__t))..., inner_allocator() };
}
+#endif // C++17
};
template <typename _OutA1, typename _OutA2, typename... _InA>
--- /dev/null
+// Copyright (C) 2019 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library. This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3. If not see
+// <http://www.gnu.org/licenses/>.
+
+// { dg-options "-std=gnu++2a" }
+// { dg-do run { target c++2a } }
+
+#include <scoped_allocator>
+#include <vector>
+#include <testsuite_hooks.h>
+#include <testsuite_allocator.h>
+
+struct X
+{
+ using allocator_type = __gnu_test::uneq_allocator<int>;
+
+ X(int personality) : a(personality) { }
+ X(std::allocator_arg_t, allocator_type a) : a(a) { }
+ X(std::allocator_arg_t, allocator_type a, const X&) : a(a) { }
+
+ allocator_type a;
+};
+
+void
+test01()
+{
+ using value_type = std::pair<std::pair<X, int>, std::pair<int, X>>;
+ using scoped_alloc
+ = std::scoped_allocator_adaptor<__gnu_test::uneq_allocator<value_type>>;
+
+ const scoped_alloc a(10);
+ std::vector<value_type, scoped_alloc> v(a);
+ VERIFY( v.get_allocator().get_personality() == a.get_personality() );
+
+ value_type val( { X(1), 2 }, { 3, X(4) } );
+ v.push_back(val);
+ X& x1 = v.back().first.first;
+ VERIFY( x1.a.get_personality() != val.first.first.a.get_personality() );
+ VERIFY( x1.a.get_personality() == a.get_personality() );
+
+ X& x2 = v.back().second.second;
+ VERIFY( x2.a.get_personality() != val.second.second.a.get_personality() );
+ VERIFY( x2.a.get_personality() == a.get_personality() );
+
+ // 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 );
+}
+
+void
+test02()
+{
+ using value_type = std::pair<std::pair<X, int>, std::pair<int, X>>;
+ using scoped_alloc
+ = std::scoped_allocator_adaptor<__gnu_test::uneq_allocator<value_type>,
+ X::allocator_type>;
+
+ const scoped_alloc a(10, 20);
+ std::vector<value_type, scoped_alloc> v(a);
+ VERIFY( v.get_allocator().get_personality() == a.get_personality() );
+
+ value_type val( { X(1), 2 }, { 3, X(4) } );
+ v.push_back(val);
+ X& x1 = v.back().first.first;
+ VERIFY( x1.a.get_personality() != val.first.first.a.get_personality() );
+ VERIFY( x1.a.get_personality() != a.get_personality() );
+ VERIFY( x1.a.get_personality() == a.inner_allocator().get_personality() );
+
+ X& x2 = v.back().second.second;
+ VERIFY( x2.a.get_personality() != val.second.second.a.get_personality() );
+ VERIFY( x2.a.get_personality() != a.get_personality() );
+ VERIFY( x2.a.get_personality() == a.inner_allocator().get_personality() );
+
+ // 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();
+ test02();
+}
int get_personality() const { return personality; }
pointer
- allocate(size_type n, const void* hint = 0)
+ allocate(size_type n, const void* = 0)
{
pointer p = AllocTraits::allocate(*this, n);