diff options
author | Jonathan Wakely <jwakely@redhat.com> | 2015-06-26 21:10:24 +0100 |
---|---|---|
committer | Jonathan Wakely <redi@gcc.gnu.org> | 2015-06-26 21:10:24 +0100 |
commit | a2b5fdcbdb0c8001c4cd2274ddff1a6c4fa7e4b3 (patch) | |
tree | d9fb25d310c35beaf8812ad74071315b7ff8a16c /libstdc++-v3 | |
parent | 22d035258b7dcb4e0414d413e32d20a8d8e3cdfe (diff) | |
download | gcc-a2b5fdcbdb0c8001c4cd2274ddff1a6c4fa7e4b3.tar.gz |
Implement N4258 (Cleaning-up noexcept in the Library rev 3)
* doc/xml/manual/intro.xml: Document LWG 2108 status.
* include/bits/alloc_traits.h (allocator_traits::is_always_equal):
Define.
* include/bits/allocator.h (allocator::is_always_equal): Likewise.
* include/bits/forward_list.h
(forward_list::operator=(forward_list&&)): Use __bool_constant.
(forward_list::swap(forward_list&)): Add noexcept.
* include/bits/hashtable.h (_Hashtable::operator=(_Hashtable&&)):
Likewise.
(_Hashtable::swap(_Hashtable&)): Likewise.
* include/bits/stl_deque.h (_Deque_base::_Deque_base(_Deque_base&&)):
Use _Alloc_traits::is_always_equal.
(deque::operator=(deque&&)): Likewise.
(deque::_M_move_assign1(deque&&, false_type)): Add comment and use
__bool_constant.
(swap(deque&, deque&)): Add noexcept.
* include/bits/stl_list.h (list::operator=(list&&)): Use
__bool_constant.
(swap(list&, list&)): Add noexcept.
* include/bits/stl_map.h (map::swap(map&)): Include _Compare in
noexcept.
(swap(map&, map&)): Add noexcept.
* include/bits/stl_multimap.h (multimap::swap(multimap&)): Include
_Compare in noexcept.
(swap(multimap&, multimap&)): Add noexcept.
* include/bits/stl_multiset.h (multiset::swap(multiset&)): Include
_Compare in noexcept.
(swap(multiset&, multiset&)): Add noexcept.
* include/bits/stl_set.h (set::swap(set&)): Include _Compare in
noexcept.
(swap(set&, set&)): Add noexcept.
* include/bits/stl_tree.h (_Rb_tree::operator=(_Rb_tree&&)): Include
_Compare in noexcept.
(_Rb_tree::_Rb_tree(_Rb_tree&&, _Node_alloc_type&&)): Use
is_always_equal.
* include/bits/stl_vector.h (vector::operator=(vector&&)): Use
__bool_constant.
(swap(vector&, vector&)): Add noexcept.
* include/bits/unordered_map.h (swap(unordered_map&, unordered_map&),
swap(unordered_multimap& unordered_multimap&)): Add noexcept.
* include/bits/unordered_set.h (swap(unordered_set&, unordered_set&),
swap(unordered_multiset& unordered_multiset&)): Add noexcept.
* include/ext/alloc_traits.h (__allocator_always_compares_equal):
Remove.
(__alloc_traits::_S_always_equal()): Use is_always_equal instead of
__allocator_always_compares_equal.
* include/ext/array_allocator.h (array_allocator::is_always_equal):
Define.
* include/std/scoped_allocator (__any_of, __propagate_on_copy,
__propagate_on_move, __propagate_on_swap): Remove.
(scoped_allocator_adaptor::propagate_on_container_copy_assignment,
scoped_allocator_adaptor::propagate_on_container_move_assignment,
scoped_allocator_adaptor::propagate_on_container_swap): Define with
__and_ instead of __any_of.
(scoped_allocator_adaptor::is_always_equal): Define.
* testsuite/20_util/allocator_traits/members/is_always_equal.cc: New.
* testsuite/20_util/scoped_allocator/propagation.cc: Make traits
derive from true_type or false_type.
* testsuite/23_containers/deque/allocator/move_assign-2.cc: Add
is_always_equal member and remove the trait specialization.
* testsuite/23_containers/vector/52591.cc: Likewise.
* testsuite/23_containers/deque/requirements/dr438/assign_neg.cc:
Adjust dg-error line number.
* testsuite/23_containers/deque/requirements/dr438/
constructor_1_neg.cc: Likewise.
* testsuite/23_containers/deque/requirements/dr438/
constructor_2_neg.cc: Likewise.
* testsuite/23_containers/deque/requirements/dr438/insert_neg.cc:
Likewise.
* testsuite/23_containers/list/requirements/dr438/assign_neg.cc:
Likewise.
* testsuite/23_containers/list/requirements/dr438/constructor_1_neg.cc:
Likewise.
* testsuite/23_containers/list/requirements/dr438/insert_neg.cc:
Likewise.
* testsuite/23_containers/vector/requirements/dr438/assign_neg.cc:
Likewise.
* testsuite/23_containers/vector/requirements/dr438/
constructor_1_neg.cc: Likewise.
* testsuite/23_containers/vector/requirements/dr438/
constructor_2_neg.cc: Likewise.
* testsuite/23_containers/vector/requirements/dr438/insert_neg.cc:
Likewise.
From-SVN: r225081
Diffstat (limited to 'libstdc++-v3')
34 files changed, 277 insertions, 141 deletions
diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog index f2cd0353ea6..9e76cc4d27e 100644 --- a/libstdc++-v3/ChangeLog +++ b/libstdc++-v3/ChangeLog @@ -1,5 +1,89 @@ 2015-06-26 Jonathan Wakely <jwakely@redhat.com> + * doc/xml/manual/intro.xml: Document LWG 2108 status. + * include/bits/alloc_traits.h (allocator_traits::is_always_equal): + Define. + * include/bits/allocator.h (allocator::is_always_equal): Likewise. + * include/bits/forward_list.h + (forward_list::operator=(forward_list&&)): Use __bool_constant. + (forward_list::swap(forward_list&)): Add noexcept. + * include/bits/hashtable.h (_Hashtable::operator=(_Hashtable&&)): + Likewise. + (_Hashtable::swap(_Hashtable&)): Likewise. + * include/bits/stl_deque.h (_Deque_base::_Deque_base(_Deque_base&&)): + Use _Alloc_traits::is_always_equal. + (deque::operator=(deque&&)): Likewise. + (deque::_M_move_assign1(deque&&, false_type)): Add comment and use + __bool_constant. + (swap(deque&, deque&)): Add noexcept. + * include/bits/stl_list.h (list::operator=(list&&)): Use + __bool_constant. + (swap(list&, list&)): Add noexcept. + * include/bits/stl_map.h (map::swap(map&)): Include _Compare in + noexcept. + (swap(map&, map&)): Add noexcept. + * include/bits/stl_multimap.h (multimap::swap(multimap&)): Include + _Compare in noexcept. + (swap(multimap&, multimap&)): Add noexcept. + * include/bits/stl_multiset.h (multiset::swap(multiset&)): Include + _Compare in noexcept. + (swap(multiset&, multiset&)): Add noexcept. + * include/bits/stl_set.h (set::swap(set&)): Include _Compare in + noexcept. + (swap(set&, set&)): Add noexcept. + * include/bits/stl_tree.h (_Rb_tree::operator=(_Rb_tree&&)): Include + _Compare in noexcept. + (_Rb_tree::_Rb_tree(_Rb_tree&&, _Node_alloc_type&&)): Use + is_always_equal. + * include/bits/stl_vector.h (vector::operator=(vector&&)): Use + __bool_constant. + (swap(vector&, vector&)): Add noexcept. + * include/bits/unordered_map.h (swap(unordered_map&, unordered_map&), + swap(unordered_multimap& unordered_multimap&)): Add noexcept. + * include/bits/unordered_set.h (swap(unordered_set&, unordered_set&), + swap(unordered_multiset& unordered_multiset&)): Add noexcept. + * include/ext/alloc_traits.h (__allocator_always_compares_equal): + Remove. + (__alloc_traits::_S_always_equal()): Use is_always_equal instead of + __allocator_always_compares_equal. + * include/ext/array_allocator.h (array_allocator::is_always_equal): + Define. + * include/std/scoped_allocator (__any_of, __propagate_on_copy, + __propagate_on_move, __propagate_on_swap): Remove. + (scoped_allocator_adaptor::propagate_on_container_copy_assignment, + scoped_allocator_adaptor::propagate_on_container_move_assignment, + scoped_allocator_adaptor::propagate_on_container_swap): Define with + __and_ instead of __any_of. + (scoped_allocator_adaptor::is_always_equal): Define. + * testsuite/20_util/allocator_traits/members/is_always_equal.cc: New. + * testsuite/20_util/scoped_allocator/propagation.cc: Make traits + derive from true_type or false_type. + * testsuite/23_containers/deque/allocator/move_assign-2.cc: Add + is_always_equal member and remove the trait specialization. + * testsuite/23_containers/vector/52591.cc: Likewise. + * testsuite/23_containers/deque/requirements/dr438/assign_neg.cc: + Adjust dg-error line number. + * testsuite/23_containers/deque/requirements/dr438/ + constructor_1_neg.cc: Likewise. + * testsuite/23_containers/deque/requirements/dr438/ + constructor_2_neg.cc: Likewise. + * testsuite/23_containers/deque/requirements/dr438/insert_neg.cc: + Likewise. + * testsuite/23_containers/list/requirements/dr438/assign_neg.cc: + Likewise. + * testsuite/23_containers/list/requirements/dr438/constructor_1_neg.cc: + Likewise. + * testsuite/23_containers/list/requirements/dr438/insert_neg.cc: + Likewise. + * testsuite/23_containers/vector/requirements/dr438/assign_neg.cc: + Likewise. + * testsuite/23_containers/vector/requirements/dr438/ + constructor_1_neg.cc: Likewise. + * testsuite/23_containers/vector/requirements/dr438/ + constructor_2_neg.cc: Likewise. + * testsuite/23_containers/vector/requirements/dr438/insert_neg.cc: + Likewise. + * include/bits/stl_bvector.h (vector<bool>::vector()): Add noexcept. * include/bits/stl_map.h (map::map()): Likewise. * include/bits/stl_multimap.h (multimap::multimap()): Likewise. diff --git a/libstdc++-v3/doc/xml/manual/intro.xml b/libstdc++-v3/doc/xml/manual/intro.xml index e6039ebf7a6..1cc183e2dc3 100644 --- a/libstdc++-v3/doc/xml/manual/intro.xml +++ b/libstdc++-v3/doc/xml/manual/intro.xml @@ -868,6 +868,12 @@ requirements of the license of GCC. <listitem><para>Change the <code>reference</code> type. </para></listitem></varlistentry> + <varlistentry><term><link xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="../ext/lwg-defects.html#2108">2108</link>: + <emphasis>No way to identify allocator types that always compare equal</emphasis> + </term> + <listitem><para>Define and use <code>is_always_equal</code> even for C++11. + </para></listitem></varlistentry> + <varlistentry><term><link xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="../ext/lwg-defects.html#2118">2118</link>: <emphasis><code>unique_ptr</code> for array does not support cv qualification conversion of actual argument</emphasis> </term> diff --git a/libstdc++-v3/include/bits/alloc_traits.h b/libstdc++-v3/include/bits/alloc_traits.h index e434261802f..bb98c1d4ce8 100644 --- a/libstdc++-v3/include/bits/alloc_traits.h +++ b/libstdc++-v3/include/bits/alloc_traits.h @@ -89,9 +89,9 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION #define _GLIBCXX_ALLOC_TR_NESTED_TYPE(_NTYPE, _ALT) \ private: \ - template<typename _Tp> \ - static typename _Tp::_NTYPE _S_##_NTYPE##_helper(_Tp*); \ - static _ALT _S_##_NTYPE##_helper(...); \ + template<typename _Tp> \ + static typename _Tp::_NTYPE _S_##_NTYPE##_helper(_Tp*); \ + static _ALT _S_##_NTYPE##_helper(...); \ typedef decltype(_S_##_NTYPE##_helper((_Alloc*)0)) __##_NTYPE; \ public: @@ -194,6 +194,17 @@ _GLIBCXX_ALLOC_TR_NESTED_TYPE(propagate_on_container_swap, */ typedef __propagate_on_container_swap propagate_on_container_swap; +_GLIBCXX_ALLOC_TR_NESTED_TYPE(is_always_equal, + typename is_empty<_Alloc>::type) + + /** + * @brief Whether all instances of the allocator type compare equal. + * + * @c Alloc::is_always_equal if that type exists, + * otherwise @c is_empty<Alloc>::type + */ + typedef __is_always_equal is_always_equal; + #undef _GLIBCXX_ALLOC_TR_NESTED_TYPE template<typename _Tp> diff --git a/libstdc++-v3/include/bits/allocator.h b/libstdc++-v3/include/bits/allocator.h index 7f5e659e22f..c7a25038467 100644 --- a/libstdc++-v3/include/bits/allocator.h +++ b/libstdc++-v3/include/bits/allocator.h @@ -77,6 +77,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION // _GLIBCXX_RESOLVE_LIB_DEFECTS // 2103. std::allocator propagate_on_container_move_assignment typedef true_type propagate_on_container_move_assignment; + + typedef true_type is_always_equal; #endif }; diff --git a/libstdc++-v3/include/bits/forward_list.h b/libstdc++-v3/include/bits/forward_list.h index 57c2d7bbfbb..db02661d3a0 100644 --- a/libstdc++-v3/include/bits/forward_list.h +++ b/libstdc++-v3/include/bits/forward_list.h @@ -587,8 +587,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER constexpr bool __move_storage = _Node_alloc_traits::_S_propagate_on_move_assign() || _Node_alloc_traits::_S_always_equal(); - _M_move_assign(std::move(__list), - integral_constant<bool, __move_storage>()); + _M_move_assign(std::move(__list), __bool_constant<__move_storage>()); return *this; } @@ -1410,6 +1409,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER inline void swap(forward_list<_Tp, _Alloc>& __lx, forward_list<_Tp, _Alloc>& __ly) + noexcept(noexcept(__lx.swap(__ly))) { __lx.swap(__ly); } _GLIBCXX_END_NAMESPACE_CONTAINER diff --git a/libstdc++-v3/include/bits/hashtable.h b/libstdc++-v3/include/bits/hashtable.h index f5f298ea33c..31d237e7783 100644 --- a/libstdc++-v3/include/bits/hashtable.h +++ b/libstdc++-v3/include/bits/hashtable.h @@ -451,13 +451,14 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION _Hashtable& operator=(_Hashtable&& __ht) - noexcept(__node_alloc_traits::_S_nothrow_move()) + noexcept(__node_alloc_traits::_S_nothrow_move() + && is_nothrow_move_assignable<_H1>::value + && is_nothrow_move_assignable<_Equal>::value) { constexpr bool __move_storage = - __node_alloc_traits::_S_propagate_on_move_assign() - || __node_alloc_traits::_S_always_equal(); - _M_move_assign(std::move(__ht), - integral_constant<bool, __move_storage>()); + __node_alloc_traits::_S_propagate_on_move_assign() + || __node_alloc_traits::_S_always_equal(); + _M_move_assign(std::move(__ht), __bool_constant<__move_storage>()); return *this; } @@ -475,7 +476,9 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION void swap(_Hashtable&) - noexcept(__node_alloc_traits::_S_nothrow_swap()); + noexcept(__node_alloc_traits::_S_nothrow_swap() + && __is_nothrow_swappable<_H1>::value + && __is_nothrow_swappable<_Equal>::value); // Basic container operations iterator @@ -1234,7 +1237,9 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION _Hashtable<_Key, _Value, _Alloc, _ExtractKey, _Equal, _H1, _H2, _Hash, _RehashPolicy, _Traits>:: swap(_Hashtable& __x) - noexcept(__node_alloc_traits::_S_nothrow_swap()) + noexcept(__node_alloc_traits::_S_nothrow_swap() + && __is_nothrow_swappable<_H1>::value + && __is_nothrow_swappable<_Equal>::value) { // The only base class with member variables is hash_code_base. // We define _Hash_code_base::_M_swap because different diff --git a/libstdc++-v3/include/bits/stl_deque.h b/libstdc++-v3/include/bits/stl_deque.h index 1b02b119e28..9b996684ef9 100644 --- a/libstdc++-v3/include/bits/stl_deque.h +++ b/libstdc++-v3/include/bits/stl_deque.h @@ -515,8 +515,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER } _Deque_base(_Deque_base&& __x) - : _Deque_base(std::move(__x), - __gnu_cxx::__allocator_always_compares_equal<_Alloc>{}) + : _Deque_base(std::move(__x), typename _Alloc_traits::is_always_equal{}) { } _Deque_base(_Deque_base&& __x, const allocator_type& __a, size_type __n) @@ -1059,9 +1058,8 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER deque& operator=(deque&& __x) noexcept(_Alloc_traits::_S_always_equal()) { - constexpr bool __always_equal = _Alloc_traits::_S_always_equal(); - _M_move_assign1(std::move(__x), - integral_constant<bool, __always_equal>()); + using __always_equal = typename _Alloc_traits::is_always_equal; + _M_move_assign1(std::move(__x), __always_equal{}); return *this; } @@ -2140,13 +2138,15 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER std::__alloc_on_move(_M_get_Tp_allocator(), __x._M_get_Tp_allocator()); } + // When the allocators are not equal the operation could throw, because + // we might need to allocate a new map for __x after moving from it + // or we might need to allocate new elements for *this. void _M_move_assign1(deque&& __x, /* always equal: */ false_type) { constexpr bool __move_storage = _Alloc_traits::_S_propagate_on_move_assign(); - _M_move_assign2(std::move(__x), - integral_constant<bool, __move_storage>()); + _M_move_assign2(std::move(__x), __bool_constant<__move_storage>()); } // Destroy all elements and deallocate all memory, then replace @@ -2271,6 +2271,9 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER template<typename _Tp, typename _Alloc> inline void swap(deque<_Tp,_Alloc>& __x, deque<_Tp,_Alloc>& __y) +#if __cplusplus >= 201103L + noexcept(noexcept(__x.swap(__y))) +#endif { __x.swap(__y); } #undef _GLIBCXX_DEQUE_BUF_SIZE diff --git a/libstdc++-v3/include/bits/stl_list.h b/libstdc++-v3/include/bits/stl_list.h index 6a729fb992e..409f1fc0262 100644 --- a/libstdc++-v3/include/bits/stl_list.h +++ b/libstdc++-v3/include/bits/stl_list.h @@ -751,8 +751,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11 constexpr bool __move_storage = _Node_alloc_traits::_S_propagate_on_move_assign() || _Node_alloc_traits::_S_always_equal(); - _M_move_assign(std::move(__x), - integral_constant<bool, __move_storage>()); + _M_move_assign(std::move(__x), __bool_constant<__move_storage>()); return *this; } @@ -1920,6 +1919,9 @@ _GLIBCXX_END_NAMESPACE_CXX11 template<typename _Tp, typename _Alloc> inline void swap(list<_Tp, _Alloc>& __x, list<_Tp, _Alloc>& __y) +#if __cplusplus >= 201103L + noexcept(noexcept(__x.swap(__y))) +#endif { __x.swap(__y); } _GLIBCXX_END_NAMESPACE_CONTAINER diff --git a/libstdc++-v3/include/bits/stl_map.h b/libstdc++-v3/include/bits/stl_map.h index 179e3f2a0bd..d6ad16a1950 100644 --- a/libstdc++-v3/include/bits/stl_map.h +++ b/libstdc++-v3/include/bits/stl_map.h @@ -795,7 +795,8 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER void swap(map& __x) #if __cplusplus >= 201103L - noexcept(_Alloc_traits::_S_nothrow_swap()) + noexcept(_Alloc_traits::_S_nothrow_swap() + && __is_nothrow_swappable<_Compare>::value) #endif { _M_t.swap(__x._M_t); } @@ -1124,6 +1125,9 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER inline void swap(map<_Key, _Tp, _Compare, _Alloc>& __x, map<_Key, _Tp, _Compare, _Alloc>& __y) +#if __cplusplus >= 201103L + noexcept(noexcept(__x.swap(__y))) +#endif { __x.swap(__y); } _GLIBCXX_END_NAMESPACE_CONTAINER diff --git a/libstdc++-v3/include/bits/stl_multimap.h b/libstdc++-v3/include/bits/stl_multimap.h index 10ac0fadea8..725dea38aaf 100644 --- a/libstdc++-v3/include/bits/stl_multimap.h +++ b/libstdc++-v3/include/bits/stl_multimap.h @@ -705,7 +705,8 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER void swap(multimap& __x) #if __cplusplus >= 201103L - noexcept(_Alloc_traits::_S_nothrow_swap()) + noexcept(_Alloc_traits::_S_nothrow_swap() + && __is_nothrow_swappable<_Compare>::value) #endif { _M_t.swap(__x._M_t); } @@ -1025,6 +1026,9 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER inline void swap(multimap<_Key, _Tp, _Compare, _Alloc>& __x, multimap<_Key, _Tp, _Compare, _Alloc>& __y) +#if __cplusplus >= 201103L + noexcept(noexcept(__x.swap(__y))) +#endif { __x.swap(__y); } _GLIBCXX_END_NAMESPACE_CONTAINER diff --git a/libstdc++-v3/include/bits/stl_multiset.h b/libstdc++-v3/include/bits/stl_multiset.h index 0a476d1b084..578b6793878 100644 --- a/libstdc++-v3/include/bits/stl_multiset.h +++ b/libstdc++-v3/include/bits/stl_multiset.h @@ -407,7 +407,8 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER void swap(multiset& __x) #if __cplusplus >= 201103L - noexcept(_Alloc_traits::_S_nothrow_swap()) + noexcept(_Alloc_traits::_S_nothrow_swap() + && __is_nothrow_swappable<_Compare>::value) #endif { _M_t.swap(__x._M_t); } @@ -874,6 +875,9 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER inline void swap(multiset<_Key, _Compare, _Alloc>& __x, multiset<_Key, _Compare, _Alloc>& __y) +#if __cplusplus >= 201103L + noexcept(noexcept(__x.swap(__y))) +#endif { __x.swap(__y); } _GLIBCXX_END_NAMESPACE_CONTAINER diff --git a/libstdc++-v3/include/bits/stl_set.h b/libstdc++-v3/include/bits/stl_set.h index 2e5c89f22c2..21c7db971cd 100644 --- a/libstdc++-v3/include/bits/stl_set.h +++ b/libstdc++-v3/include/bits/stl_set.h @@ -411,7 +411,8 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER void swap(set& __x) #if __cplusplus >= 201103L - noexcept(_Alloc_traits::_S_nothrow_swap()) + noexcept(_Alloc_traits::_S_nothrow_swap() + && __is_nothrow_swappable<_Compare>::value) #endif { _M_t.swap(__x._M_t); } @@ -890,6 +891,9 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER template<typename _Key, typename _Compare, typename _Alloc> inline void swap(set<_Key, _Compare, _Alloc>& __x, set<_Key, _Compare, _Alloc>& __y) +#if __cplusplus >= 201103L + noexcept(noexcept(__x.swap(__y))) +#endif { __x.swap(__y); } _GLIBCXX_END_NAMESPACE_CONTAINER diff --git a/libstdc++-v3/include/bits/stl_tree.h b/libstdc++-v3/include/bits/stl_tree.h index 0ba15ab2b4b..58c6b43fac0 100644 --- a/libstdc++-v3/include/bits/stl_tree.h +++ b/libstdc++-v3/include/bits/stl_tree.h @@ -1241,7 +1241,9 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION #if __cplusplus >= 201103L _Rb_tree& - operator=(_Rb_tree&&) noexcept(_Alloc_traits::_S_nothrow_move()); + operator=(_Rb_tree&&) + noexcept(_Alloc_traits::_S_nothrow_move() + && is_nothrow_move_assignable<_Compare>::value); template<typename _Iterator> void @@ -1325,7 +1327,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION _Rb_tree(_Rb_tree&& __x, _Node_allocator&& __a) : _M_impl(__x._M_impl._M_key_compare, std::move(__a)) { - using __eq = integral_constant<bool, _Alloc_traits::_S_always_equal()>; + using __eq = typename _Alloc_traits::is_always_equal; if (__x._M_root() != nullptr) _M_move_data(__x, __eq()); } @@ -1378,7 +1380,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>& _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>:: operator=(_Rb_tree&& __x) - noexcept(_Alloc_traits::_S_nothrow_move()) + noexcept(_Alloc_traits::_S_nothrow_move() + && is_nothrow_move_assignable<_Compare>::value) { _M_impl._M_key_compare = __x._M_impl._M_key_compare; if (_Alloc_traits::_S_propagate_on_move_assign() diff --git a/libstdc++-v3/include/bits/stl_vector.h b/libstdc++-v3/include/bits/stl_vector.h index b00f7704f81..1f3269b1c0a 100644 --- a/libstdc++-v3/include/bits/stl_vector.h +++ b/libstdc++-v3/include/bits/stl_vector.h @@ -450,8 +450,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER constexpr bool __move_storage = _Alloc_traits::_S_propagate_on_move_assign() || _Alloc_traits::_S_always_equal(); - _M_move_assign(std::move(__x), - integral_constant<bool, __move_storage>()); + _M_move_assign(std::move(__x), __bool_constant<__move_storage>()); return *this; } @@ -1557,6 +1556,9 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER template<typename _Tp, typename _Alloc> inline void swap(vector<_Tp, _Alloc>& __x, vector<_Tp, _Alloc>& __y) +#if __cplusplus >= 201103L + noexcept(noexcept(__x.swap(__y))) +#endif { __x.swap(__y); } _GLIBCXX_END_NAMESPACE_CONTAINER diff --git a/libstdc++-v3/include/bits/unordered_map.h b/libstdc++-v3/include/bits/unordered_map.h index 3c434abb6aa..d44efb5f1c3 100644 --- a/libstdc++-v3/include/bits/unordered_map.h +++ b/libstdc++-v3/include/bits/unordered_map.h @@ -1517,12 +1517,14 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER inline void swap(unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>& __x, unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>& __y) + noexcept(noexcept(__x.swap(__y))) { __x.swap(__y); } template<class _Key, class _Tp, class _Hash, class _Pred, class _Alloc> inline void swap(unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>& __x, unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>& __y) + noexcept(noexcept(__x.swap(__y))) { __x.swap(__y); } template<class _Key, class _Tp, class _Hash, class _Pred, class _Alloc> diff --git a/libstdc++-v3/include/bits/unordered_set.h b/libstdc++-v3/include/bits/unordered_set.h index 664d97ef27a..b9b94ca6803 100644 --- a/libstdc++-v3/include/bits/unordered_set.h +++ b/libstdc++-v3/include/bits/unordered_set.h @@ -1396,12 +1396,14 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER inline void swap(unordered_set<_Value, _Hash, _Pred, _Alloc>& __x, unordered_set<_Value, _Hash, _Pred, _Alloc>& __y) + noexcept(noexcept(__x.swap(__y))) { __x.swap(__y); } template<class _Value, class _Hash, class _Pred, class _Alloc> inline void swap(unordered_multiset<_Value, _Hash, _Pred, _Alloc>& __x, unordered_multiset<_Value, _Hash, _Pred, _Alloc>& __y) + noexcept(noexcept(__x.swap(__y))) { __x.swap(__y); } template<class _Value, class _Hash, class _Pred, class _Alloc> diff --git a/libstdc++-v3/include/ext/alloc_traits.h b/libstdc++-v3/include/ext/alloc_traits.h index bd0f75945aa..5da32c5b0ec 100644 --- a/libstdc++-v3/include/ext/alloc_traits.h +++ b/libstdc++-v3/include/ext/alloc_traits.h @@ -42,53 +42,8 @@ namespace __gnu_cxx _GLIBCXX_VISIBILITY(default) { _GLIBCXX_BEGIN_NAMESPACE_VERSION -#if __cplusplus >= 201103L - template<typename _Alloc> - struct __allocator_always_compares_equal : std::false_type { }; - - template<typename _Tp> - struct __allocator_always_compares_equal<std::allocator<_Tp>> - : std::true_type { }; - - template<typename, typename> struct array_allocator; - - template<typename _Tp, typename _Array> - struct __allocator_always_compares_equal<array_allocator<_Tp, _Array>> - : std::true_type { }; - - template<typename> struct bitmap_allocator; - - template<typename _Tp> - struct __allocator_always_compares_equal<bitmap_allocator<_Tp>> - : std::true_type { }; - - template<typename> struct malloc_allocator; - - template<typename _Tp> - struct __allocator_always_compares_equal<malloc_allocator<_Tp>> - : std::true_type { }; - - template<typename> struct mt_allocator; - - template<typename _Tp> - struct __allocator_always_compares_equal<mt_allocator<_Tp>> - : std::true_type { }; - - template<typename> struct new_allocator; - - template<typename _Tp> - struct __allocator_always_compares_equal<new_allocator<_Tp>> - : std::true_type { }; - - template<typename> struct pool_allocator; - - template<typename _Tp> - struct __allocator_always_compares_equal<pool_allocator<_Tp>> - : std::true_type { }; -#endif - /** - * @brief Uniform interface to C++98 and C++0x allocators. + * @brief Uniform interface to C++98 and C++11 allocators. * @ingroup allocators */ template<typename _Alloc> @@ -152,7 +107,7 @@ template<typename _Alloc> { return _Base_type::propagate_on_container_swap::value; } static constexpr bool _S_always_equal() - { return __allocator_always_compares_equal<_Alloc>::value; } + { return _Base_type::is_always_equal::value; } static constexpr bool _S_nothrow_move() { return _S_propagate_on_move_assign() || _S_always_equal(); } diff --git a/libstdc++-v3/include/ext/array_allocator.h b/libstdc++-v3/include/ext/array_allocator.h index d909ceab9ca..779d155d892 100644 --- a/libstdc++-v3/include/ext/array_allocator.h +++ b/libstdc++-v3/include/ext/array_allocator.h @@ -123,6 +123,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION // _GLIBCXX_RESOLVE_LIB_DEFECTS // 2103. std::allocator propagate_on_container_move_assignment typedef std::true_type propagate_on_container_move_assignment; + + typedef std::true_type is_always_equal; #endif private: diff --git a/libstdc++-v3/include/std/scoped_allocator b/libstdc++-v3/include/std/scoped_allocator index d163edd109a..b3b9493cd88 100644 --- a/libstdc++-v3/include/std/scoped_allocator +++ b/libstdc++-v3/include/std/scoped_allocator @@ -43,39 +43,12 @@ namespace std _GLIBCXX_VISIBILITY(default) { _GLIBCXX_BEGIN_NAMESPACE_VERSION - template<template<typename> class _Pred, typename... _Allocs> - struct __any_of; - - template<template<typename> class _Pred, typename _Alloc, typename... _Allocs> - struct __any_of<_Pred, _Alloc, _Allocs...> - : __or_<_Pred<_Alloc>, __any_of<_Pred, _Allocs...>> - { }; - - template<template<typename> class _Pred, typename _Alloc> - struct __any_of<_Pred, _Alloc> - : _Pred<_Alloc> - { }; - /** * @addtogroup allocators * @{ */ template<typename _Alloc> - struct __propagate_on_copy - : allocator_traits<_Alloc>::propagate_on_container_copy_assignment - { }; - template<typename _Alloc> - struct __propagate_on_move - : allocator_traits<_Alloc>::propagate_on_container_move_assignment - { }; - template<typename _Alloc> - struct __propagate_on_swap - : allocator_traits<_Alloc>::propagate_on_container_swap - { }; - - - template<typename _Alloc> inline auto __do_outermost(_Alloc& __a, _Alloc*) -> decltype(__a.outer_allocator()) { return __a.outer_allocator(); } @@ -263,15 +236,28 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION typedef typename __traits::void_pointer void_pointer; typedef typename __traits::const_void_pointer const_void_pointer; - typedef typename conditional< - __any_of<__propagate_on_copy, _OuterAlloc, _InnerAllocs...>::value, - true_type, false_type>::type propagate_on_container_copy_assignment; - typedef typename conditional< - __any_of<__propagate_on_move, _OuterAlloc, _InnerAllocs...>::value, - true_type, false_type>::type propagate_on_container_move_assignment; - typedef typename conditional< - __any_of<__propagate_on_swap, _OuterAlloc, _InnerAllocs...>::value, - true_type, false_type>::type propagate_on_container_swap; + typedef typename __or_< + typename __traits::propagate_on_container_copy_assignment, + typename allocator_traits<_InnerAllocs>:: + propagate_on_container_copy_assignment...>::type + propagate_on_container_copy_assignment; + + typedef typename __or_< + typename __traits::propagate_on_container_move_assignment, + typename allocator_traits<_InnerAllocs>:: + propagate_on_container_move_assignment...>::type + propagate_on_container_move_assignment; + + typedef typename __or_< + typename __traits::propagate_on_container_swap, + typename allocator_traits<_InnerAllocs>:: + propagate_on_container_swap...>::type + propagate_on_container_swap; + + typedef typename __and_< + typename __traits::is_always_equal, + typename allocator_traits<_InnerAllocs>::is_always_equal...>::type + is_always_equal; template <class _Tp> struct rebind diff --git a/libstdc++-v3/testsuite/20_util/allocator_traits/members/is_always_equal.cc b/libstdc++-v3/testsuite/20_util/allocator_traits/members/is_always_equal.cc new file mode 100644 index 00000000000..16974d18e0d --- /dev/null +++ b/libstdc++-v3/testsuite/20_util/allocator_traits/members/is_always_equal.cc @@ -0,0 +1,66 @@ +// Copyright (C) 2015 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++11" } +// { dg-do compile } + +#include <type_traits> +#include <memory> + +template<typename T, typename Base> + struct Alloc : Base + { + typedef T value_type; + Alloc(); + template <typename U> + Alloc(const Alloc<U, Base>&); + T* allocate(std::size_t); + void deallocate(T*, std::size_t); + }; + +template<bool> struct Empty { }; +template<> struct Empty<false> { int x; }; + +template<bool B> + struct WithType + { using is_always_equal = std::integral_constant<bool, B>; }; + +struct EmptyAndTrue : Empty<true>, WithType<true> { }; +struct EmptyButFalse : Empty<true>, WithType<false> { }; + +struct NotEmptyButTrue : Empty<false>, WithType<true> { }; +struct NotEmptyAndFalse : Empty<false>, WithType<false> { }; + +template<typename Base> + constexpr bool test() + { + using traits = std::allocator_traits<Alloc<int, Base>>; + using test_type = typename traits::is_always_equal; + static_assert(std::is_base_of<std::true_type, test_type>::value + || std::is_base_of<std::false_type, test_type>::value, + "has correct base characteristic"); + return test_type::value; + } + +static_assert( test<Empty<true>>(), "empty type is always equal" ); +static_assert( !test<Empty<false>>(), "non-empty type is not always equal" ); + +static_assert( test<EmptyAndTrue>(), "nested type is used" ); +static_assert( !test<EmptyButFalse>(), "nested type is used" ); + +static_assert( test<NotEmptyButTrue>(), "nested type is used" ); +static_assert( !test<NotEmptyAndFalse>(), "nested type is used" ); diff --git a/libstdc++-v3/testsuite/20_util/scoped_allocator/propagation.cc b/libstdc++-v3/testsuite/20_util/scoped_allocator/propagation.cc index ee63629b02c..e1e59460288 100644 --- a/libstdc++-v3/testsuite/20_util/scoped_allocator/propagation.cc +++ b/libstdc++-v3/testsuite/20_util/scoped_allocator/propagation.cc @@ -42,13 +42,13 @@ template<typename T, bool copy, bool move, bool swap> struct test_allocator : minimal_allocator<T> { struct propagate_on_container_copy_assignment - { static const bool value = copy; }; + : std::integral_constant<bool, copy> { }; struct propagate_on_container_move_assignment - { static const bool value = move; }; + : std::integral_constant<bool, move> { }; struct propagate_on_container_swap - { static const bool value = swap; }; + : std::integral_constant<bool, swap> { }; }; template<typename A> diff --git a/libstdc++-v3/testsuite/23_containers/deque/allocator/move_assign-2.cc b/libstdc++-v3/testsuite/23_containers/deque/allocator/move_assign-2.cc index b852f6cac75..e0a09d231c3 100644 --- a/libstdc++-v3/testsuite/23_containers/deque/allocator/move_assign-2.cc +++ b/libstdc++-v3/testsuite/23_containers/deque/allocator/move_assign-2.cc @@ -61,14 +61,9 @@ struct A2 : std::allocator<T> template<typename U> A2(const A2<U>&) { } using propagate_on_container_move_assignment = std::false_type; -}; -namespace __gnu_cxx -{ - template<typename T> - struct __allocator_always_compares_equal<A2<T>> : std::true_type - { }; -} + using is_always_equal = std::true_type; +}; void test02() { diff --git a/libstdc++-v3/testsuite/23_containers/deque/requirements/dr438/assign_neg.cc b/libstdc++-v3/testsuite/23_containers/deque/requirements/dr438/assign_neg.cc index d9bc2ace552..09e2fc20416 100644 --- a/libstdc++-v3/testsuite/23_containers/deque/requirements/dr438/assign_neg.cc +++ b/libstdc++-v3/testsuite/23_containers/deque/requirements/dr438/assign_neg.cc @@ -18,7 +18,7 @@ // <http://www.gnu.org/licenses/>. // { dg-do compile } -// { dg-prune-output 1881 } +// { dg-prune-output 1879 } #include <deque> diff --git a/libstdc++-v3/testsuite/23_containers/deque/requirements/dr438/constructor_1_neg.cc b/libstdc++-v3/testsuite/23_containers/deque/requirements/dr438/constructor_1_neg.cc index b4eb75edde1..deb75489019 100644 --- a/libstdc++-v3/testsuite/23_containers/deque/requirements/dr438/constructor_1_neg.cc +++ b/libstdc++-v3/testsuite/23_containers/deque/requirements/dr438/constructor_1_neg.cc @@ -18,7 +18,7 @@ // <http://www.gnu.org/licenses/>. // { dg-do compile } -// { dg-prune-output 1814 } +// { dg-prune-output 1812 } #include <deque> diff --git a/libstdc++-v3/testsuite/23_containers/deque/requirements/dr438/constructor_2_neg.cc b/libstdc++-v3/testsuite/23_containers/deque/requirements/dr438/constructor_2_neg.cc index 90ce50a1fee..f02cd27ad1f 100644 --- a/libstdc++-v3/testsuite/23_containers/deque/requirements/dr438/constructor_2_neg.cc +++ b/libstdc++-v3/testsuite/23_containers/deque/requirements/dr438/constructor_2_neg.cc @@ -18,7 +18,7 @@ // <http://www.gnu.org/licenses/>. // { dg-do compile } -// { dg-prune-output 1814 } +// { dg-prune-output 1812 } #include <deque> #include <utility> diff --git a/libstdc++-v3/testsuite/23_containers/deque/requirements/dr438/insert_neg.cc b/libstdc++-v3/testsuite/23_containers/deque/requirements/dr438/insert_neg.cc index 5ff969580a9..5fffef7aff8 100644 --- a/libstdc++-v3/testsuite/23_containers/deque/requirements/dr438/insert_neg.cc +++ b/libstdc++-v3/testsuite/23_containers/deque/requirements/dr438/insert_neg.cc @@ -18,7 +18,7 @@ // <http://www.gnu.org/licenses/>. // { dg-do compile } -// { dg-prune-output 1965 } +// { dg-prune-output 1963 } #include <deque> diff --git a/libstdc++-v3/testsuite/23_containers/list/requirements/dr438/assign_neg.cc b/libstdc++-v3/testsuite/23_containers/list/requirements/dr438/assign_neg.cc index 84c74734806..c6eab0beb25 100644 --- a/libstdc++-v3/testsuite/23_containers/list/requirements/dr438/assign_neg.cc +++ b/libstdc++-v3/testsuite/23_containers/list/requirements/dr438/assign_neg.cc @@ -18,7 +18,7 @@ // <http://www.gnu.org/licenses/>. // { dg-do compile } -// { dg-prune-output 1741 } +// { dg-prune-output 1740 } #include <list> diff --git a/libstdc++-v3/testsuite/23_containers/list/requirements/dr438/constructor_1_neg.cc b/libstdc++-v3/testsuite/23_containers/list/requirements/dr438/constructor_1_neg.cc index 947029c043f..833f731b146 100644 --- a/libstdc++-v3/testsuite/23_containers/list/requirements/dr438/constructor_1_neg.cc +++ b/libstdc++-v3/testsuite/23_containers/list/requirements/dr438/constructor_1_neg.cc @@ -18,7 +18,7 @@ // <http://www.gnu.org/licenses/>. // { dg-do compile } -// { dg-prune-output 1693 } +// { dg-prune-output 1692 } #include <list> diff --git a/libstdc++-v3/testsuite/23_containers/list/requirements/dr438/insert_neg.cc b/libstdc++-v3/testsuite/23_containers/list/requirements/dr438/insert_neg.cc index 54e89328ce0..09d1d470ed3 100644 --- a/libstdc++-v3/testsuite/23_containers/list/requirements/dr438/insert_neg.cc +++ b/libstdc++-v3/testsuite/23_containers/list/requirements/dr438/insert_neg.cc @@ -18,7 +18,7 @@ // <http://www.gnu.org/licenses/>. // { dg-do compile } -// { dg-prune-output 1693 } +// { dg-prune-output 1692 } #include <list> diff --git a/libstdc++-v3/testsuite/23_containers/vector/52591.cc b/libstdc++-v3/testsuite/23_containers/vector/52591.cc index c32f0622d7e..291fb29798b 100644 --- a/libstdc++-v3/testsuite/23_containers/vector/52591.cc +++ b/libstdc++-v3/testsuite/23_containers/vector/52591.cc @@ -60,15 +60,9 @@ struct A2 : std::allocator<T> template<typename U> A2(const A2<U>&) { } using propagate_on_container_move_assignment = std::false_type; + using is_always_equal = std::true_type; }; -namespace __gnu_cxx -{ - template<typename T> - struct __allocator_always_compares_equal<A2<T>> : std::true_type - { }; -} - void test02() { using test_type = std::vector<C, A2<C>>; diff --git a/libstdc++-v3/testsuite/23_containers/vector/requirements/dr438/assign_neg.cc b/libstdc++-v3/testsuite/23_containers/vector/requirements/dr438/assign_neg.cc index ce8f525c2e6..8d87c34f919 100644 --- a/libstdc++-v3/testsuite/23_containers/vector/requirements/dr438/assign_neg.cc +++ b/libstdc++-v3/testsuite/23_containers/vector/requirements/dr438/assign_neg.cc @@ -18,7 +18,7 @@ // <http://www.gnu.org/licenses/>. // { dg-do compile } -// { dg-prune-output 1326 } +// { dg-prune-output 1325 } #include <vector> diff --git a/libstdc++-v3/testsuite/23_containers/vector/requirements/dr438/constructor_1_neg.cc b/libstdc++-v3/testsuite/23_containers/vector/requirements/dr438/constructor_1_neg.cc index 4f0d365d247..2c453d1e626 100644 --- a/libstdc++-v3/testsuite/23_containers/vector/requirements/dr438/constructor_1_neg.cc +++ b/libstdc++-v3/testsuite/23_containers/vector/requirements/dr438/constructor_1_neg.cc @@ -18,7 +18,7 @@ // <http://www.gnu.org/licenses/>. // { dg-do compile } -// { dg-prune-output 1252 } +// { dg-prune-output 1251 } #include <vector> diff --git a/libstdc++-v3/testsuite/23_containers/vector/requirements/dr438/constructor_2_neg.cc b/libstdc++-v3/testsuite/23_containers/vector/requirements/dr438/constructor_2_neg.cc index 34ffaecfc0b..d0c8d447ee3 100644 --- a/libstdc++-v3/testsuite/23_containers/vector/requirements/dr438/constructor_2_neg.cc +++ b/libstdc++-v3/testsuite/23_containers/vector/requirements/dr438/constructor_2_neg.cc @@ -18,7 +18,7 @@ // <http://www.gnu.org/licenses/>. // { dg-do compile } -// { dg-prune-output 1252 } +// { dg-prune-output 1251 } #include <vector> #include <utility> diff --git a/libstdc++-v3/testsuite/23_containers/vector/requirements/dr438/insert_neg.cc b/libstdc++-v3/testsuite/23_containers/vector/requirements/dr438/insert_neg.cc index 6f611bf4cb1..f176a6f0152 100644 --- a/libstdc++-v3/testsuite/23_containers/vector/requirements/dr438/insert_neg.cc +++ b/libstdc++-v3/testsuite/23_containers/vector/requirements/dr438/insert_neg.cc @@ -18,7 +18,7 @@ // <http://www.gnu.org/licenses/>. // { dg-do compile } -// { dg-prune-output 1367 } +// { dg-prune-output 1366 } #include <vector> |