From 05891e9f458cc7e6ba5387c6ac84f4201e40107d Mon Sep 17 00:00:00 2001 From: Jonathan Wakely Date: Mon, 18 Jun 2018 21:17:44 +0100 Subject: [PATCH] LWG 2975 ensure construct(pair*, ...) used to construct pairs * include/std/scoped_allocator (__not_pair): Define SFINAE helper. (construct(_Tp*, _Args&&...)): Remove from overload set when _Tp is a specialization of std::pair. * testsuite/20_util/scoped_allocator/construct_pair.cc: Ensure pair elements are constructed correctly. From-SVN: r261716 --- libstdc++-v3/ChangeLog | 7 +++++ libstdc++-v3/include/std/scoped_allocator | 23 ++++++++++----- .../scoped_allocator/construct_pair.cc | 28 +++++++++++++++++++ 3 files changed, 51 insertions(+), 7 deletions(-) diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog index 0b81f047a17..89bcf2f5d5c 100644 --- a/libstdc++-v3/ChangeLog +++ b/libstdc++-v3/ChangeLog @@ -1,5 +1,12 @@ 2018-06-18 Jonathan Wakely + LWG 2975 ensure construct(pair*, ...) used to construct pairs + * include/std/scoped_allocator (__not_pair): Define SFINAE helper. + (construct(_Tp*, _Args&&...)): Remove from overload set when _Tp is + a specialization of std::pair. + * testsuite/20_util/scoped_allocator/construct_pair.cc: Ensure + pair elements are constructed correctly. + LWG 2989 hide path iostream operators from normal lookup * include/bits/fs_path.h (operator<<, operator>>): Define inline as friends. diff --git a/libstdc++-v3/include/std/scoped_allocator b/libstdc++-v3/include/std/scoped_allocator index 195db397ac9..ea62f113517 100644 --- a/libstdc++-v3/include/std/scoped_allocator +++ b/libstdc++-v3/include/std/scoped_allocator @@ -241,6 +241,14 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION is_constructible<_OuterAlloc, _Alloc>::value >::type; + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // 2975. Missing case for pair construction in scoped [...] allocators + template + struct __not_pair { using type = void; }; + + template + struct __not_pair> { }; + public: typedef _OuterAlloc outer_allocator_type; typedef typename __inner_type::__type inner_allocator_type; @@ -348,13 +356,14 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION { return __traits::max_size(outer_allocator()); } template - void construct(_Tp* __p, _Args&&... __args) - { - auto& __inner = inner_allocator(); - auto __use_tag - = __use_alloc<_Tp, inner_allocator_type, _Args...>(__inner); - _M_construct(__use_tag, __p, std::forward<_Args>(__args)...); - } + typename __not_pair<_Tp>::type + construct(_Tp* __p, _Args&&... __args) + { + auto& __inner = inner_allocator(); + auto __use_tag + = __use_alloc<_Tp, inner_allocator_type, _Args...>(__inner); + _M_construct(__use_tag, __p, std::forward<_Args>(__args)...); + } template diff --git a/libstdc++-v3/testsuite/20_util/scoped_allocator/construct_pair.cc b/libstdc++-v3/testsuite/20_util/scoped_allocator/construct_pair.cc index 341328e487f..b34efc88798 100644 --- a/libstdc++-v3/testsuite/20_util/scoped_allocator/construct_pair.cc +++ b/libstdc++-v3/testsuite/20_util/scoped_allocator/construct_pair.cc @@ -73,9 +73,37 @@ test03() a.deallocate(ptr, 1); } +void +test04() +{ + struct X + { + using allocator_type = std::allocator; + X() = default; + X(const X&) { throw 1; } + X(const X&, const allocator_type&) { } + }; + + struct Y + { + using allocator_type = std::allocator; + Y() = default; + Y(const Y&) = delete; + Y(std::allocator_arg_t, const allocator_type&, const Y&) { } + }; + + using pair_type = std::pair; + std::scoped_allocator_adaptor> a; + auto ptr = a.allocate(1); + /* not const */ pair_type p; + a.construct(ptr, p); // LWG 2975 + a.deallocate(ptr, 1); +} + int main() { test01(); test02(); test03(); + test04(); } -- 2.30.2