From 8b0cd47a1caedcd752884b1a785b7fc975530d18 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Fran=C3=A7ois=20Dumont?= Date: Fri, 18 May 2018 20:49:49 +0000 Subject: [PATCH] =?utf8?q?2018-05-18=20=20Fran=C3=A7ois=20Dumont=20=20?= MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit * include/bits/stl_tree.h (_Rb_tree_impl(_Rb_tree_impl&&, _Node_allocator&&)): New. (_Rb_tree(_Rb_tree&&, _Node_allocator&&, true_type)): New, use latter. (_Rb_tree(_Rb_tree&&, _Node_allocator&&, false_type)): New. (_Rb_tree(_Rb_tree&&, _Node_allocator&&)): Adapt, use latters. * include/debug/map.h (map(map&&, const_allocator_type&)): Add noexcept qualitication. * include/debug/multimap.h (multimap(multimap&&, const_allocator_type&)): Likewise. * include/debug/set.h (set(set&&, const_allocator_type&)): Likewise. * include/debug/multiset.h (multiset(multiset&&, const_allocator_type&)): Likewise. * testsuite/23_containers/map/cons/noexcept_default_construct.cc: Add checks. * testsuite/23_containers/map/cons/noexcept_move_construct.cc: Add checks. * testsuite/23_containers/multimap/cons/noexcept_default_construct.cc: Add checks. * testsuite/23_containers/multimap/cons/noexcept_move_construct.cc: Add checks. * testsuite/23_containers/multiset/cons/noexcept_default_construct.cc: Add checks. * testsuite/23_containers/multiset/cons/noexcept_move_construct.cc: Add checks. * testsuite/23_containers/set/cons/noexcept_default_construct.cc: Add checks. * testsuite/23_containers/set/cons/noexcept_move_construct.cc: Add checks. From-SVN: r260382 --- libstdc++-v3/ChangeLog | 32 +++++++++++ libstdc++-v3/include/bits/stl_tree.h | 57 ++++++++++++------- libstdc++-v3/include/debug/map.h | 1 + libstdc++-v3/include/debug/multimap.h | 1 + libstdc++-v3/include/debug/multiset.h | 1 + libstdc++-v3/include/debug/set.h | 1 + .../map/cons/noexcept_default_construct.cc | 16 ++++++ .../map/cons/noexcept_move_construct.cc | 23 +++++++- .../cons/noexcept_default_construct.cc | 16 ++++++ .../multimap/cons/noexcept_move_construct.cc | 23 +++++++- .../cons/noexcept_default_construct.cc | 16 ++++++ .../multiset/cons/noexcept_move_construct.cc | 23 +++++++- .../set/cons/noexcept_default_construct.cc | 16 ++++++ .../set/cons/noexcept_move_construct.cc | 23 +++++++- 14 files changed, 224 insertions(+), 25 deletions(-) diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog index c4e10f11b5f..092fa755087 100644 --- a/libstdc++-v3/ChangeLog +++ b/libstdc++-v3/ChangeLog @@ -1,3 +1,35 @@ +2018-05-18 François Dumont + + * include/bits/stl_tree.h + (_Rb_tree_impl(_Rb_tree_impl&&, _Node_allocator&&)): New. + (_Rb_tree(_Rb_tree&&, _Node_allocator&&, true_type)): New, use latter. + (_Rb_tree(_Rb_tree&&, _Node_allocator&&, false_type)): New. + (_Rb_tree(_Rb_tree&&, _Node_allocator&&)): Adapt, use latters. + * include/debug/map.h + (map(map&&, const_allocator_type&)): Add noexcept qualitication. + * include/debug/multimap.h + (multimap(multimap&&, const_allocator_type&)): Likewise. + * include/debug/set.h + (set(set&&, const_allocator_type&)): Likewise. + * include/debug/multiset.h + (multiset(multiset&&, const_allocator_type&)): Likewise. + * testsuite/23_containers/map/cons/noexcept_default_construct.cc: + Add checks. + * testsuite/23_containers/map/cons/noexcept_move_construct.cc: + Add checks. + * testsuite/23_containers/multimap/cons/noexcept_default_construct.cc: + Add checks. + * testsuite/23_containers/multimap/cons/noexcept_move_construct.cc: + Add checks. + * testsuite/23_containers/multiset/cons/noexcept_default_construct.cc: + Add checks. + * testsuite/23_containers/multiset/cons/noexcept_move_construct.cc: + Add checks. + * testsuite/23_containers/set/cons/noexcept_default_construct.cc: + Add checks. + * testsuite/23_containers/set/cons/noexcept_move_construct.cc: + Add checks. + 2018-05-18 Jason Merrill * include/bits/stl_deque.h (_Deque_iterator): Constrain constructor diff --git a/libstdc++-v3/include/bits/stl_tree.h b/libstdc++-v3/include/bits/stl_tree.h index d0a8448eb0b..85f190acccf 100644 --- a/libstdc++-v3/include/bits/stl_tree.h +++ b/libstdc++-v3/include/bits/stl_tree.h @@ -471,7 +471,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION struct _Reuse_or_alloc_node { _Reuse_or_alloc_node(_Rb_tree& __t) - : _M_root(__t._M_root()), _M_nodes(__t._M_rightmost()), _M_t(__t) + : _M_root(__t._M_root()), _M_nodes(__t._M_rightmost()), _M_t(__t) { if (_M_root) { @@ -555,7 +555,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION struct _Alloc_node { _Alloc_node(_Rb_tree& __t) - : _M_t(__t) { } + : _M_t(__t) { } template _Link_type @@ -715,6 +715,12 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION #else _Rb_tree_impl(_Rb_tree_impl&&) = default; + _Rb_tree_impl(_Rb_tree_impl&& __x, _Node_allocator&& __a) + : _Node_allocator(std::move(__a)), + _Base_key_compare(std::move(__x)), + _Rb_tree_header(std::move(__x)) + { } + _Rb_tree_impl(const _Key_compare& __comp, _Node_allocator&& __a) : _Node_allocator(std::move(__a)), _Base_key_compare(__comp) { } @@ -958,7 +964,27 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION : _Rb_tree(std::move(__x), _Node_allocator(__a)) { } - _Rb_tree(_Rb_tree&& __x, _Node_allocator&& __a); + private: + _Rb_tree(_Rb_tree&& __x, _Node_allocator&& __a, true_type) + noexcept(is_nothrow_default_constructible<_Compare>::value) + : _M_impl(std::move(__x._M_impl), std::move(__a)) + { } + + _Rb_tree(_Rb_tree&& __x, _Node_allocator&& __a, false_type) + : _M_impl(__x._M_impl._M_key_compare, std::move(__a)) + { + if (__x._M_root() != nullptr) + _M_move_data(__x, false_type{}); + } + + public: + _Rb_tree(_Rb_tree&& __x, _Node_allocator&& __a) + noexcept( noexcept( + _Rb_tree(std::declval<_Rb_tree>(), std::declval<_Node_allocator>(), + std::declval())) ) + : _Rb_tree(std::move(__x), std::move(__a), + typename _Alloc_traits::is_always_equal{}) + { } #endif ~_Rb_tree() _GLIBCXX_NOEXCEPT @@ -1358,22 +1384,22 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION private: // Move elements from container with equal allocator. void - _M_move_data(_Rb_tree& __x, std::true_type) + _M_move_data(_Rb_tree& __x, true_type) { _M_impl._M_move_data(__x._M_impl); } // Move elements from container with possibly non-equal allocator, // which might result in a copy not a move. void - _M_move_data(_Rb_tree&, std::false_type); + _M_move_data(_Rb_tree&, false_type); // Move assignment from container with equal allocator. void - _M_move_assign(_Rb_tree&, std::true_type); + _M_move_assign(_Rb_tree&, true_type); // Move assignment from container with possibly non-equal allocator, // which might result in a copy not a move. void - _M_move_assign(_Rb_tree&, std::false_type); + _M_move_assign(_Rb_tree&, false_type); #endif #if __cplusplus > 201402L @@ -1599,25 +1625,14 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION { __x.swap(__y); } #if __cplusplus >= 201103L - template - _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>:: - _Rb_tree(_Rb_tree&& __x, _Node_allocator&& __a) - : _M_impl(__x._M_impl._M_key_compare, std::move(__a)) - { - using __eq = typename _Alloc_traits::is_always_equal; - if (__x._M_root() != nullptr) - _M_move_data(__x, __eq()); - } - template void _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>:: - _M_move_data(_Rb_tree& __x, std::false_type) + _M_move_data(_Rb_tree& __x, false_type) { if (_M_get_Node_allocator() == __x._M_get_Node_allocator()) - _M_move_data(__x, std::true_type()); + _M_move_data(__x, true_type()); else { _Alloc_node __an(*this); @@ -1639,7 +1654,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION { clear(); if (__x._M_root() != nullptr) - _M_move_data(__x, std::true_type()); + _M_move_data(__x, true_type()); std::__alloc_on_move(_M_get_Node_allocator(), __x._M_get_Node_allocator()); } diff --git a/libstdc++-v3/include/debug/map.h b/libstdc++-v3/include/debug/map.h index 3f0649aef9e..23966ba968d 100644 --- a/libstdc++-v3/include/debug/map.h +++ b/libstdc++-v3/include/debug/map.h @@ -105,6 +105,7 @@ namespace __debug : _Base(__m, __a) { } map(map&& __m, const allocator_type& __a) + noexcept( noexcept(_Base(std::move(__m._M_base()), __a)) ) : _Safe(std::move(__m._M_safe()), __a), _Base(std::move(__m._M_base()), __a) { } diff --git a/libstdc++-v3/include/debug/multimap.h b/libstdc++-v3/include/debug/multimap.h index e709eb7452f..80549848fcb 100644 --- a/libstdc++-v3/include/debug/multimap.h +++ b/libstdc++-v3/include/debug/multimap.h @@ -105,6 +105,7 @@ namespace __debug : _Base(__m, __a) { } multimap(multimap&& __m, const allocator_type& __a) + noexcept( noexcept(_Base(std::move(__m._M_base()), __a)) ) : _Safe(std::move(__m._M_safe()), __a), _Base(std::move(__m._M_base()), __a) { } diff --git a/libstdc++-v3/include/debug/multiset.h b/libstdc++-v3/include/debug/multiset.h index 461f4f632dd..6e4c1b0e564 100644 --- a/libstdc++-v3/include/debug/multiset.h +++ b/libstdc++-v3/include/debug/multiset.h @@ -104,6 +104,7 @@ namespace __debug : _Base(__m, __a) { } multiset(multiset&& __m, const allocator_type& __a) + noexcept( noexcept(_Base(std::move(__m._M_base()), __a)) ) : _Safe(std::move(__m._M_safe()), __a), _Base(std::move(__m._M_base()), __a) { } diff --git a/libstdc++-v3/include/debug/set.h b/libstdc++-v3/include/debug/set.h index 2ac8f1c1fab..571cc474948 100644 --- a/libstdc++-v3/include/debug/set.h +++ b/libstdc++-v3/include/debug/set.h @@ -104,6 +104,7 @@ namespace __debug : _Base(__x, __a) { } set(set&& __x, const allocator_type& __a) + noexcept( noexcept(_Base(std::move(__x._M_base()), __a)) ) : _Safe(std::move(__x._M_safe()), __a), _Base(std::move(__x._M_base()), __a) { } diff --git a/libstdc++-v3/testsuite/23_containers/map/cons/noexcept_default_construct.cc b/libstdc++-v3/testsuite/23_containers/map/cons/noexcept_default_construct.cc index 4b9e11931a1..e5c924d2507 100644 --- a/libstdc++-v3/testsuite/23_containers/map/cons/noexcept_default_construct.cc +++ b/libstdc++-v3/testsuite/23_containers/map/cons/noexcept_default_construct.cc @@ -30,3 +30,19 @@ struct cmp using mtype2 = std::map; static_assert( !std::is_nothrow_default_constructible::value, "Error"); + +template + struct not_noexcept_cons_alloc : std::allocator<_Tp> + { + not_noexcept_cons_alloc() /* noexcept */ + { } + + template + struct rebind + { typedef not_noexcept_cons_alloc<_Tp1> other; }; + }; + +using mtype3 = std::map, + not_noexcept_cons_alloc>>; + +static_assert(!std::is_nothrow_default_constructible::value, "Error"); diff --git a/libstdc++-v3/testsuite/23_containers/map/cons/noexcept_move_construct.cc b/libstdc++-v3/testsuite/23_containers/map/cons/noexcept_move_construct.cc index 00414089dd4..723a63f7d62 100644 --- a/libstdc++-v3/testsuite/23_containers/map/cons/noexcept_move_construct.cc +++ b/libstdc++-v3/testsuite/23_containers/map/cons/noexcept_move_construct.cc @@ -23,4 +23,25 @@ typedef std::map mtype; -static_assert(std::is_nothrow_move_constructible::value, "Error"); +static_assert( std::is_nothrow_move_constructible::value, + "noexcept move constructor" ); +static_assert( std::is_nothrow_constructible::value, + "noexcept move constructor with allocator" ); + +struct not_noexcept_less +{ + not_noexcept_less() = default; + not_noexcept_less(const not_noexcept_less&) /* noexcept */ + { } + + bool + operator()(int l, int r) const + { return l < r; } +}; + +typedef std::map emtype; + +static_assert( !std::is_nothrow_constructible::value, + "except move constructor with allocator" ); diff --git a/libstdc++-v3/testsuite/23_containers/multimap/cons/noexcept_default_construct.cc b/libstdc++-v3/testsuite/23_containers/multimap/cons/noexcept_default_construct.cc index 9873770f783..62f5d60673b 100644 --- a/libstdc++-v3/testsuite/23_containers/multimap/cons/noexcept_default_construct.cc +++ b/libstdc++-v3/testsuite/23_containers/multimap/cons/noexcept_default_construct.cc @@ -30,3 +30,19 @@ struct cmp using mtype2 = std::multimap; static_assert( !std::is_nothrow_default_constructible::value, "Error"); + +template + struct not_noexcept_cons_alloc : std::allocator<_Tp> + { + not_noexcept_cons_alloc() /* noexcept */ + { } + + template + struct rebind + { typedef not_noexcept_cons_alloc<_Tp1> other; }; + }; + +using mtype3 = std::multimap, + not_noexcept_cons_alloc>>; + +static_assert(!std::is_nothrow_default_constructible::value, "Error"); diff --git a/libstdc++-v3/testsuite/23_containers/multimap/cons/noexcept_move_construct.cc b/libstdc++-v3/testsuite/23_containers/multimap/cons/noexcept_move_construct.cc index 0319a612157..1612b0d59ef 100644 --- a/libstdc++-v3/testsuite/23_containers/multimap/cons/noexcept_move_construct.cc +++ b/libstdc++-v3/testsuite/23_containers/multimap/cons/noexcept_move_construct.cc @@ -23,4 +23,25 @@ typedef std::multimap mmtype; -static_assert(std::is_nothrow_move_constructible::value, "Error"); +static_assert( std::is_nothrow_move_constructible::value, + "noexcept move constructor" ); +static_assert( std::is_nothrow_constructible::value, + "noexcept move constructor with allocator" ); + +struct not_noexcept_less +{ + not_noexcept_less() = default; + not_noexcept_less(const not_noexcept_less&) /* noexcept */ + { } + + bool + operator()(int l, int r) const + { return l < r; } +}; + +typedef std::multimap emmtype; + +static_assert( !std::is_nothrow_constructible::value, + "except move constructor with allocator" ); diff --git a/libstdc++-v3/testsuite/23_containers/multiset/cons/noexcept_default_construct.cc b/libstdc++-v3/testsuite/23_containers/multiset/cons/noexcept_default_construct.cc index 963e3d1e952..8e491682102 100644 --- a/libstdc++-v3/testsuite/23_containers/multiset/cons/noexcept_default_construct.cc +++ b/libstdc++-v3/testsuite/23_containers/multiset/cons/noexcept_default_construct.cc @@ -30,3 +30,19 @@ struct cmp using stype2 = std::multiset; static_assert( !std::is_nothrow_default_constructible::value, "Error"); + +template + struct not_noexcept_cons_alloc : std::allocator<_Tp> + { + not_noexcept_cons_alloc() /* noexcept */ + { } + + template + struct rebind + { typedef not_noexcept_cons_alloc<_Tp1> other; }; + }; + +using stype3 = std::multiset, + not_noexcept_cons_alloc>; + +static_assert(!std::is_nothrow_default_constructible::value, "Error"); diff --git a/libstdc++-v3/testsuite/23_containers/multiset/cons/noexcept_move_construct.cc b/libstdc++-v3/testsuite/23_containers/multiset/cons/noexcept_move_construct.cc index b1c6dd5a7e7..4ef5127ec0e 100644 --- a/libstdc++-v3/testsuite/23_containers/multiset/cons/noexcept_move_construct.cc +++ b/libstdc++-v3/testsuite/23_containers/multiset/cons/noexcept_move_construct.cc @@ -23,4 +23,25 @@ typedef std::multiset mstype; -static_assert(std::is_nothrow_move_constructible::value, "Error"); +static_assert( std::is_nothrow_move_constructible::value, + "noexcept move constructor" ); +static_assert( std::is_nothrow_constructible::value, + "noexcept move constructor with allocator" ); + +struct not_noexcept_less +{ + not_noexcept_less() = default; + not_noexcept_less(const not_noexcept_less&) /* noexcept */ + { } + + bool + operator()(int l, int r) const + { return l < r; } +}; + +typedef std::multiset emstype; + +static_assert( !std::is_nothrow_constructible::value, + "except move constructor with allocator" ); diff --git a/libstdc++-v3/testsuite/23_containers/set/cons/noexcept_default_construct.cc b/libstdc++-v3/testsuite/23_containers/set/cons/noexcept_default_construct.cc index 882a12cbdd7..d3dc98df44a 100644 --- a/libstdc++-v3/testsuite/23_containers/set/cons/noexcept_default_construct.cc +++ b/libstdc++-v3/testsuite/23_containers/set/cons/noexcept_default_construct.cc @@ -30,3 +30,19 @@ struct cmp using stype2 = std::set; static_assert( !std::is_nothrow_default_constructible::value, "Error"); + +template + struct not_noexcept_cons_alloc : std::allocator<_Tp> + { + not_noexcept_cons_alloc() /* noexcept */ + { } + + template + struct rebind + { typedef not_noexcept_cons_alloc<_Tp1> other; }; + }; + +using stype3 = std::set, + not_noexcept_cons_alloc>; + +static_assert(!std::is_nothrow_default_constructible::value, "Error"); diff --git a/libstdc++-v3/testsuite/23_containers/set/cons/noexcept_move_construct.cc b/libstdc++-v3/testsuite/23_containers/set/cons/noexcept_move_construct.cc index a7de0efadf3..942400ea2f3 100644 --- a/libstdc++-v3/testsuite/23_containers/set/cons/noexcept_move_construct.cc +++ b/libstdc++-v3/testsuite/23_containers/set/cons/noexcept_move_construct.cc @@ -23,4 +23,25 @@ typedef std::set stype; -static_assert(std::is_nothrow_move_constructible::value, "Error"); +static_assert( std::is_nothrow_move_constructible::value, + "noexcept move constructor" ); +static_assert( std::is_nothrow_constructible::value, + "noexcept move constructor with allocator" ); + +struct not_noexcept_less +{ + not_noexcept_less() = default; + not_noexcept_less(const not_noexcept_less&) /* noexcept */ + { } + + bool + operator()(int l, int r) const + { return l < r; } +}; + +typedef std::set estype; + +static_assert( !std::is_nothrow_constructible::value, + "except move constructor with allocator" ); -- 2.30.2