From: Jonathan Wakely Date: Thu, 25 Apr 2019 22:43:15 +0000 (+0100) Subject: PR libstdc++/90239 use uses_allocator_construction_args in X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=ee2f721c2f7ac5574456833447a492ed1b24b5c2;p=gcc.git PR libstdc++/90239 use uses_allocator_construction_args in 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. From-SVN: r270588 --- diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog index b616df758a0..f15125ba5a9 100644 --- a/libstdc++-v3/ChangeLog +++ b/libstdc++-v3/ChangeLog @@ -1,3 +1,14 @@ +2019-04-25 Jonathan Wakely + + 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. + 2019-04-24 Jonathan Wakely * doc/xml/manual/status_cxx2017.xml: Document P0024R2 status. diff --git a/libstdc++-v3/doc/xml/manual/status_cxx2020.xml b/libstdc++-v3/doc/xml/manual/status_cxx2020.xml index cedb3d03066..a075103ea4a 100644 --- a/libstdc++-v3/doc/xml/manual/status_cxx2020.xml +++ b/libstdc++-v3/doc/xml/manual/status_cxx2020.xml @@ -674,7 +674,9 @@ Feature-testing recommendations for C++. 9.1 - + + std::scoped_allocator_adaptor changes missing in 9.1.0 + diff --git a/libstdc++-v3/include/std/scoped_allocator b/libstdc++-v3/include/std/scoped_allocator index 335df483f69..2c7ad8e94d7 100644 --- a/libstdc++-v3/include/std/scoped_allocator +++ b/libstdc++-v3/include/std/scoped_allocator @@ -35,6 +35,7 @@ # include #else +#include #include #include #include @@ -187,6 +188,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION using __outermost_alloc_traits = allocator_traits::type>; +#if __cplusplus <= 201703 template void _M_construct(__uses_alloc0, _Tp* __p, _Args&&... __args) @@ -218,6 +220,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION std::forward<_Args>(__args)..., inner_allocator()); } +#endif // C++17 template static _Alloc @@ -355,6 +358,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION size_type max_size() const { return __traits::max_size(outer_allocator()); } +#if __cplusplus <= 201703 template typename __not_pair<_Tp>::type construct(_Tp* __p, _Args&&... __args) @@ -417,6 +421,21 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION std::forward_as_tuple(std::forward<_Up>(__x.first)), std::forward_as_tuple(std::forward<_Vp>(__x.second))); } +#else // C++2a + template + __attribute__((__nonnull__)) + void + construct(_Tp* __p, _Args&&... __args) + { + typedef __outermost_alloc_traits _O_traits; + std::apply([__p, this](auto&&... __newargs) { + _O_traits::construct(__outermost(*this), __p, + std::forward(__newargs)...); + }, + uses_allocator_construction_args<_Tp>(inner_allocator(), + std::forward<_Args>(__args)...)); + } +#endif // C++2a template void destroy(_Tp* __p) @@ -439,6 +458,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION const scoped_allocator_adaptor<_OutA2, _InA...>& __b) noexcept; private: +#if __cplusplus <= 201703L template tuple<_Args&&...> _M_construct_p(__uses_alloc0, _Ind, tuple<_Args...>& __t) @@ -461,6 +481,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION { return { std::get<_Ind>(std::move(__t))..., inner_allocator() }; } +#endif // C++17 }; template 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 new file mode 100644 index 00000000000..1630f2a4d09 --- /dev/null +++ b/libstdc++-v3/testsuite/20_util/scoped_allocator/construct_pair_c++2a.cc @@ -0,0 +1,97 @@ +// 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 +// . + +// { dg-options "-std=gnu++2a" } +// { dg-do run { target c++2a } } + +#include +#include +#include +#include + +struct X +{ + using allocator_type = __gnu_test::uneq_allocator; + + 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>; + using scoped_alloc + = std::scoped_allocator_adaptor<__gnu_test::uneq_allocator>; + + const scoped_alloc a(10); + std::vector 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>; + using scoped_alloc + = std::scoped_allocator_adaptor<__gnu_test::uneq_allocator, + X::allocator_type>; + + const scoped_alloc a(10, 20); + std::vector 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(); +} diff --git a/libstdc++-v3/testsuite/util/testsuite_allocator.h b/libstdc++-v3/testsuite/util/testsuite_allocator.h index 627749299d2..0392421ca04 100644 --- a/libstdc++-v3/testsuite/util/testsuite_allocator.h +++ b/libstdc++-v3/testsuite/util/testsuite_allocator.h @@ -334,7 +334,7 @@ namespace __gnu_test 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);