Commit 05891e9f by Jonathan Wakely Committed by Jonathan Wakely

LWG 2975 ensure construct(pair<T,U>*, ...) 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
parent df0b55f0
2018-06-18 Jonathan Wakely <jwakely@redhat.com> 2018-06-18 Jonathan Wakely <jwakely@redhat.com>
LWG 2975 ensure construct(pair<T,U>*, ...) 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 LWG 2989 hide path iostream operators from normal lookup
* include/bits/fs_path.h (operator<<, operator>>): Define inline as * include/bits/fs_path.h (operator<<, operator>>): Define inline as
friends. friends.
......
...@@ -241,6 +241,14 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION ...@@ -241,6 +241,14 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
is_constructible<_OuterAlloc, _Alloc>::value is_constructible<_OuterAlloc, _Alloc>::value
>::type; >::type;
// _GLIBCXX_RESOLVE_LIB_DEFECTS
// 2975. Missing case for pair construction in scoped [...] allocators
template<typename _Tp>
struct __not_pair { using type = void; };
template<typename _Tp, typename _Up>
struct __not_pair<pair<_Tp, _Up>> { };
public: public:
typedef _OuterAlloc outer_allocator_type; typedef _OuterAlloc outer_allocator_type;
typedef typename __inner_type::__type inner_allocator_type; typedef typename __inner_type::__type inner_allocator_type;
...@@ -348,13 +356,14 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION ...@@ -348,13 +356,14 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
{ return __traits::max_size(outer_allocator()); } { return __traits::max_size(outer_allocator()); }
template<typename _Tp, typename... _Args> template<typename _Tp, typename... _Args>
void construct(_Tp* __p, _Args&&... __args) typename __not_pair<_Tp>::type
{ construct(_Tp* __p, _Args&&... __args)
auto& __inner = inner_allocator(); {
auto __use_tag auto& __inner = inner_allocator();
= __use_alloc<_Tp, inner_allocator_type, _Args...>(__inner); auto __use_tag
_M_construct(__use_tag, __p, std::forward<_Args>(__args)...); = __use_alloc<_Tp, inner_allocator_type, _Args...>(__inner);
} _M_construct(__use_tag, __p, std::forward<_Args>(__args)...);
}
template<typename _T1, typename _T2, typename... _Args1, template<typename _T1, typename _T2, typename... _Args1,
typename... _Args2> typename... _Args2>
......
...@@ -73,9 +73,37 @@ test03() ...@@ -73,9 +73,37 @@ test03()
a.deallocate(ptr, 1); a.deallocate(ptr, 1);
} }
void
test04()
{
struct X
{
using allocator_type = std::allocator<int>;
X() = default;
X(const X&) { throw 1; }
X(const X&, const allocator_type&) { }
};
struct Y
{
using allocator_type = std::allocator<int>;
Y() = default;
Y(const Y&) = delete;
Y(std::allocator_arg_t, const allocator_type&, const Y&) { }
};
using pair_type = std::pair<X, Y>;
std::scoped_allocator_adaptor<std::allocator<pair_type>> a;
auto ptr = a.allocate(1);
/* not const */ pair_type p;
a.construct(ptr, p); // LWG 2975
a.deallocate(ptr, 1);
}
int main() int main()
{ {
test01(); test01();
test02(); test02();
test03(); test03();
test04();
} }
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment