From 5f2f14c5d29b1a815cde3dcd8c775d91139f8889 Mon Sep 17 00:00:00 2001 From: Howard Hinnant Date: Sat, 4 Jun 2011 18:54:24 +0000 Subject: [PATCH] noexcept for . git-svn-id: https://llvm.org/svn/llvm-project/libcxx/trunk@132646 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/__hash_table | 209 ++++++++++---- include/unordered_map | 269 +++++++++++------- .../unord.map.cnstr/default_noexcept.pass.cpp | 70 +++++ .../unord.map.cnstr/dtor_noexcept.pass.cpp | 67 +++++ .../move_assign_noexcept.pass.cpp | 69 +++++ .../unord.map.cnstr/move_noexcept.pass.cpp | 66 +++++ .../unord.map.swap/swap_noexcept.pass.cpp | 73 +++++ .../default_noexcept.pass.cpp | 70 +++++ .../dtor_noexcept.pass.cpp | 67 +++++ .../move_assign_noexcept.pass.cpp | 69 +++++ .../move_noexcept.pass.cpp | 66 +++++ .../swap_noexcept.pass.cpp | 73 +++++ 12 files changed, 1015 insertions(+), 153 deletions(-) create mode 100644 test/containers/unord/unord.map/unord.map.cnstr/default_noexcept.pass.cpp create mode 100644 test/containers/unord/unord.map/unord.map.cnstr/dtor_noexcept.pass.cpp create mode 100644 test/containers/unord/unord.map/unord.map.cnstr/move_assign_noexcept.pass.cpp create mode 100644 test/containers/unord/unord.map/unord.map.cnstr/move_noexcept.pass.cpp create mode 100644 test/containers/unord/unord.map/unord.map.swap/swap_noexcept.pass.cpp create mode 100644 test/containers/unord/unord.multimap/unord.multimap.cnstr/default_noexcept.pass.cpp create mode 100644 test/containers/unord/unord.multimap/unord.multimap.cnstr/dtor_noexcept.pass.cpp create mode 100644 test/containers/unord/unord.multimap/unord.multimap.cnstr/move_assign_noexcept.pass.cpp create mode 100644 test/containers/unord/unord.multimap/unord.multimap.cnstr/move_noexcept.pass.cpp create mode 100644 test/containers/unord/unord.multimap/unord.multimap.swap/swap_noexcept.pass.cpp diff --git a/include/__hash_table b/include/__hash_table index 41dbaa010..2e371a424 100644 --- a/include/__hash_table +++ b/include/__hash_table @@ -33,7 +33,7 @@ struct __hash_node_base _NodePtr __next_; - _LIBCPP_INLINE_VISIBILITY __hash_node_base() : __next_(nullptr) {} + _LIBCPP_INLINE_VISIBILITY __hash_node_base() _NOEXCEPT : __next_(nullptr) {} }; template @@ -80,7 +80,7 @@ public: #endif pointer; - _LIBCPP_INLINE_VISIBILITY __hash_iterator() {} + _LIBCPP_INLINE_VISIBILITY __hash_iterator() _NOEXCEPT {} _LIBCPP_INLINE_VISIBILITY reference operator*() const {return __node_->__value_;} @@ -111,7 +111,7 @@ public: private: _LIBCPP_INLINE_VISIBILITY - __hash_iterator(__node_pointer __node) + __hash_iterator(__node_pointer __node) _NOEXCEPT : __node_(__node) {} @@ -154,9 +154,9 @@ public: __non_const_node_pointer; typedef __hash_iterator<__non_const_node_pointer> __non_const_iterator; - _LIBCPP_INLINE_VISIBILITY __hash_const_iterator() {} + _LIBCPP_INLINE_VISIBILITY __hash_const_iterator() _NOEXCEPT {} _LIBCPP_INLINE_VISIBILITY - __hash_const_iterator(const __non_const_iterator& __x) + __hash_const_iterator(const __non_const_iterator& __x) _NOEXCEPT : __node_(__x.__node_) {} @@ -189,7 +189,7 @@ public: private: _LIBCPP_INLINE_VISIBILITY - __hash_const_iterator(__node_pointer __node) + __hash_const_iterator(__node_pointer __node) _NOEXCEPT : __node_(__node) {} @@ -224,7 +224,7 @@ public: #endif pointer; - _LIBCPP_INLINE_VISIBILITY __hash_local_iterator() {} + _LIBCPP_INLINE_VISIBILITY __hash_local_iterator() _NOEXCEPT {} _LIBCPP_INLINE_VISIBILITY reference operator*() const {return __node_->__value_;} @@ -258,7 +258,7 @@ public: private: _LIBCPP_INLINE_VISIBILITY __hash_local_iterator(__node_pointer __node, size_t __bucket, - size_t __bucket_count) + size_t __bucket_count) _NOEXCEPT : __node_(__node), __bucket_(__bucket), __bucket_count_(__bucket_count) @@ -308,9 +308,9 @@ public: #endif pointer; - _LIBCPP_INLINE_VISIBILITY __hash_const_local_iterator() {} + _LIBCPP_INLINE_VISIBILITY __hash_const_local_iterator() _NOEXCEPT {} _LIBCPP_INLINE_VISIBILITY - __hash_const_local_iterator(const __non_const_iterator& __x) + __hash_const_local_iterator(const __non_const_iterator& __x) _NOEXCEPT : __node_(__x.__node_), __bucket_(__x.__bucket_), __bucket_count_(__x.__bucket_count_) @@ -348,7 +348,7 @@ public: private: _LIBCPP_INLINE_VISIBILITY __hash_const_local_iterator(__node_pointer __node, size_t __bucket, - size_t __bucket_count) + size_t __bucket_count) _NOEXCEPT : __node_(__node), __bucket_(__bucket), __bucket_count_(__bucket_count) @@ -374,16 +374,19 @@ public: _LIBCPP_INLINE_VISIBILITY __bucket_list_deallocator() + _NOEXCEPT_(is_nothrow_default_constructible::value) : __data_(0) {} _LIBCPP_INLINE_VISIBILITY __bucket_list_deallocator(const allocator_type& __a, size_type __size) + _NOEXCEPT_(is_nothrow_copy_constructible::value) : __data_(__size, __a) {} #ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES _LIBCPP_INLINE_VISIBILITY __bucket_list_deallocator(__bucket_list_deallocator&& __x) + _NOEXCEPT_(is_nothrow_move_constructible::value) : __data_(_STD::move(__x.__data_)) { __x.size() = 0; @@ -391,14 +394,18 @@ public: #endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES - _LIBCPP_INLINE_VISIBILITY size_type& size() {return __data_.first();} - _LIBCPP_INLINE_VISIBILITY size_type size() const {return __data_.first();} - - _LIBCPP_INLINE_VISIBILITY allocator_type& __alloc() {return __data_.second();} - _LIBCPP_INLINE_VISIBILITY const allocator_type& __alloc() const {return __data_.second();} + _LIBCPP_INLINE_VISIBILITY + size_type& size() _NOEXCEPT {return __data_.first();} + _LIBCPP_INLINE_VISIBILITY + size_type size() const _NOEXCEPT {return __data_.first();} _LIBCPP_INLINE_VISIBILITY - void operator()(pointer __p) + allocator_type& __alloc() _NOEXCEPT {return __data_.second();} + _LIBCPP_INLINE_VISIBILITY + const allocator_type& __alloc() const _NOEXCEPT {return __data_.second();} + + _LIBCPP_INLINE_VISIBILITY + void operator()(pointer __p) _NOEXCEPT { __alloc_traits::deallocate(__alloc(), __p, size()); } @@ -424,13 +431,13 @@ public: bool __value_constructed; _LIBCPP_INLINE_VISIBILITY - explicit __hash_node_destructor(allocator_type& __na) + explicit __hash_node_destructor(allocator_type& __na) _NOEXCEPT : __na_(__na), __value_constructed(false) {} _LIBCPP_INLINE_VISIBILITY - void operator()(pointer __p) + void operator()(pointer __p) _NOEXCEPT { if (__value_constructed) __alloc_traits::destroy(__na_, _STD::addressof(__p->__value_)); @@ -495,21 +502,32 @@ private: __compressed_pair __p3_; // --- Member data end --- - _LIBCPP_INLINE_VISIBILITY size_type& size() {return __p2_.first();} + _LIBCPP_INLINE_VISIBILITY + size_type& size() _NOEXCEPT {return __p2_.first();} public: - _LIBCPP_INLINE_VISIBILITY size_type size() const {return __p2_.first();} + _LIBCPP_INLINE_VISIBILITY + size_type size() const _NOEXCEPT {return __p2_.first();} - _LIBCPP_INLINE_VISIBILITY hasher& hash_function() {return __p2_.second();} - _LIBCPP_INLINE_VISIBILITY const hasher& hash_function() const {return __p2_.second();} + _LIBCPP_INLINE_VISIBILITY + hasher& hash_function() _NOEXCEPT {return __p2_.second();} + _LIBCPP_INLINE_VISIBILITY + const hasher& hash_function() const _NOEXCEPT {return __p2_.second();} - _LIBCPP_INLINE_VISIBILITY float& max_load_factor() {return __p3_.first();} - _LIBCPP_INLINE_VISIBILITY float max_load_factor() const {return __p3_.first();} + _LIBCPP_INLINE_VISIBILITY + float& max_load_factor() _NOEXCEPT {return __p3_.first();} + _LIBCPP_INLINE_VISIBILITY + float max_load_factor() const _NOEXCEPT {return __p3_.first();} - _LIBCPP_INLINE_VISIBILITY key_equal& key_eq() {return __p3_.second();} - _LIBCPP_INLINE_VISIBILITY const key_equal& key_eq() const {return __p3_.second();} + _LIBCPP_INLINE_VISIBILITY + key_equal& key_eq() _NOEXCEPT {return __p3_.second();} + _LIBCPP_INLINE_VISIBILITY + const key_equal& key_eq() const _NOEXCEPT {return __p3_.second();} - _LIBCPP_INLINE_VISIBILITY __node_allocator& __node_alloc() {return __p1_.second();} - _LIBCPP_INLINE_VISIBILITY const __node_allocator& __node_alloc() const {return __p1_.second();} + _LIBCPP_INLINE_VISIBILITY + __node_allocator& __node_alloc() _NOEXCEPT {return __p1_.second();} + _LIBCPP_INLINE_VISIBILITY + const __node_allocator& __node_alloc() const _NOEXCEPT + {return __p1_.second();} public: typedef __hash_iterator<__node_pointer> iterator; @@ -517,7 +535,13 @@ public: typedef __hash_local_iterator<__node_pointer> local_iterator; typedef __hash_const_local_iterator<__node_const_pointer> const_local_iterator; - __hash_table(); + __hash_table() + _NOEXCEPT_( + is_nothrow_default_constructible<__bucket_list>::value && + is_nothrow_default_constructible<__first_node>::value && + is_nothrow_default_constructible<__node_allocator>::value && + is_nothrow_default_constructible::value && + is_nothrow_default_constructible::value); __hash_table(const hasher& __hf, const key_equal& __eql); __hash_table(const hasher& __hf, const key_equal& __eql, const allocator_type& __a); @@ -525,14 +549,25 @@ public: __hash_table(const __hash_table& __u); __hash_table(const __hash_table& __u, const allocator_type& __a); #ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES - __hash_table(__hash_table&& __u); + __hash_table(__hash_table&& __u) + _NOEXCEPT_( + is_nothrow_move_constructible<__bucket_list>::value && + is_nothrow_move_constructible<__first_node>::value && + is_nothrow_move_constructible<__node_allocator>::value && + is_nothrow_move_constructible::value && + is_nothrow_move_constructible::value); __hash_table(__hash_table&& __u, const allocator_type& __a); #endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES ~__hash_table(); __hash_table& operator=(const __hash_table& __u); #ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES - __hash_table& operator=(__hash_table&& __u); + __hash_table& operator=(__hash_table&& __u) + _NOEXCEPT_( + __node_traits::propagate_on_container_move_assignment::value && + is_nothrow_move_assignable<__node_allocator>::value && + is_nothrow_move_assignable::value && + is_nothrow_move_assignable::value); #endif template void __assign_unique(_InputIterator __first, _InputIterator __last); @@ -540,7 +575,7 @@ public: void __assign_multi(_InputIterator __first, _InputIterator __last); _LIBCPP_INLINE_VISIBILITY - size_type max_size() const + size_type max_size() const _NOEXCEPT { return allocator_traits<__pointer_allocator>::max_size( __bucket_list_.get_deleter().__alloc()); @@ -577,21 +612,21 @@ public: iterator __insert_multi(const_iterator __p, const value_type& __x); #endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES - void clear(); + void clear() _NOEXCEPT; void rehash(size_type __n); _LIBCPP_INLINE_VISIBILITY void reserve(size_type __n) {rehash(static_cast(ceil(__n / max_load_factor())));} _LIBCPP_INLINE_VISIBILITY - size_type bucket_count() const + size_type bucket_count() const _NOEXCEPT { return __bucket_list_.get_deleter().size(); } - iterator begin(); - iterator end(); - const_iterator begin() const; - const_iterator end() const; + iterator begin() _NOEXCEPT; + iterator end() _NOEXCEPT; + const_iterator begin() const _NOEXCEPT; + const_iterator end() const _NOEXCEPT; template _LIBCPP_INLINE_VISIBILITY @@ -612,7 +647,7 @@ public: size_type __erase_unique(const _Key& __k); template size_type __erase_multi(const _Key& __k); - __node_holder remove(const_iterator __p); + __node_holder remove(const_iterator __p) _NOEXCEPT; template size_type __count_unique(const _Key& __k) const; @@ -633,18 +668,25 @@ public: pair __equal_range_multi(const _Key& __k) const; - void swap(__hash_table& __u); + void swap(__hash_table& __u) + _NOEXCEPT_( + (!allocator_traits<__pointer_allocator>::propagate_on_container_swap::value || + __is_nothrow_swappable<__pointer_allocator>::value) && + (!__node_traits::propagate_on_container_swap::value || + __is_nothrow_swappable<__node_allocator>::value) && + __is_nothrow_swappable::value && + __is_nothrow_swappable::value); _LIBCPP_INLINE_VISIBILITY - size_type max_bucket_count() const + size_type max_bucket_count() const _NOEXCEPT {return __bucket_list_.get_deleter().__alloc().max_size();} size_type bucket_size(size_type __n) const; - _LIBCPP_INLINE_VISIBILITY float load_factor() const + _LIBCPP_INLINE_VISIBILITY float load_factor() const _NOEXCEPT { size_type __bc = bucket_count(); return __bc != 0 ? (float)size() / __bc : 0.f; } - _LIBCPP_INLINE_VISIBILITY void max_load_factor(float __mlf) + _LIBCPP_INLINE_VISIBILITY void max_load_factor(float __mlf) _NOEXCEPT {max_load_factor() = _STD::max(__mlf, load_factor());} _LIBCPP_INLINE_VISIBILITY local_iterator begin(size_type __n) @@ -678,25 +720,40 @@ private: void __copy_assign_alloc(const __hash_table& __u, false_type) {} void __move_assign(__hash_table& __u, false_type); - void __move_assign(__hash_table& __u, true_type); - _LIBCPP_INLINE_VISIBILITY void __move_assign_alloc(__hash_table& __u) + void __move_assign(__hash_table& __u, true_type) + _NOEXCEPT_( + is_nothrow_move_assignable<__node_allocator>::value && + is_nothrow_move_assignable::value && + is_nothrow_move_assignable::value); + _LIBCPP_INLINE_VISIBILITY + void __move_assign_alloc(__hash_table& __u) + _NOEXCEPT_( + !__node_traits::propagate_on_container_move_assignment::value || + (is_nothrow_move_assignable<__pointer_allocator>::value && + is_nothrow_move_assignable<__node_allocator>::value)) {__move_assign_alloc(__u, integral_constant());} _LIBCPP_INLINE_VISIBILITY void __move_assign_alloc(__hash_table& __u, true_type) + _NOEXCEPT_( + is_nothrow_move_assignable<__pointer_allocator>::value && + is_nothrow_move_assignable<__node_allocator>::value) { __bucket_list_.get_deleter().__alloc() = _STD::move(__u.__bucket_list_.get_deleter().__alloc()); __node_alloc() = _STD::move(__u.__node_alloc()); } _LIBCPP_INLINE_VISIBILITY - void __move_assign_alloc(__hash_table&, false_type) {} + void __move_assign_alloc(__hash_table&, false_type) _NOEXCEPT {} template _LIBCPP_INLINE_VISIBILITY static void __swap_alloc(_A& __x, _A& __y) + _NOEXCEPT_( + !allocator_traits<_A>::propagate_on_container_swap::value || + __is_nothrow_swappable<_A>::value) { __swap_alloc(__x, __y, integral_constant::value) { using _STD::swap; swap(__x, __y); @@ -718,15 +776,20 @@ private: _LIBCPP_INLINE_VISIBILITY static void - __swap_alloc(_A& __x, _A& __y, false_type) {} + __swap_alloc(_A& __x, _A& __y, false_type) _NOEXCEPT {} - void __deallocate(__node_pointer __np); - __node_pointer __detach(); + void __deallocate(__node_pointer __np) _NOEXCEPT; + __node_pointer __detach() _NOEXCEPT; }; template inline _LIBCPP_INLINE_VISIBILITY __hash_table<_Tp, _Hash, _Equal, _Alloc>::__hash_table() + _NOEXCEPT_( + is_nothrow_default_constructible<__bucket_list>::value && + is_nothrow_default_constructible<__first_node>::value && + is_nothrow_default_constructible::value && + is_nothrow_default_constructible::value) : __p2_(0), __p3_(1.0f) { @@ -790,6 +853,11 @@ __hash_table<_Tp, _Hash, _Equal, _Alloc>::__hash_table(const __hash_table& __u, template __hash_table<_Tp, _Hash, _Equal, _Alloc>::__hash_table(__hash_table&& __u) + _NOEXCEPT_( + is_nothrow_move_constructible<__bucket_list>::value && + is_nothrow_move_constructible<__first_node>::value && + is_nothrow_move_constructible::value && + is_nothrow_move_constructible::value) : __bucket_list_(_STD::move(__u.__bucket_list_)), __p1_(_STD::move(__u.__p1_)), __p2_(_STD::move(__u.__p2_)), @@ -870,6 +938,7 @@ __hash_table<_Tp, _Hash, _Equal, _Alloc>::operator=(const __hash_table& __u) template void __hash_table<_Tp, _Hash, _Equal, _Alloc>::__deallocate(__node_pointer __np) + _NOEXCEPT { __node_allocator& __na = __node_alloc(); while (__np != nullptr) @@ -883,7 +952,7 @@ __hash_table<_Tp, _Hash, _Equal, _Alloc>::__deallocate(__node_pointer __np) template typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::__node_pointer -__hash_table<_Tp, _Hash, _Equal, _Alloc>::__detach() +__hash_table<_Tp, _Hash, _Equal, _Alloc>::__detach() _NOEXCEPT { size_type __bc = bucket_count(); for (size_type __i = 0; __i < __bc; ++__i) @@ -900,6 +969,10 @@ template void __hash_table<_Tp, _Hash, _Equal, _Alloc>::__move_assign( __hash_table& __u, true_type) + _NOEXCEPT_( + is_nothrow_move_assignable<__node_allocator>::value && + is_nothrow_move_assignable::value && + is_nothrow_move_assignable::value) { clear(); __bucket_list_.reset(__u.__bucket_list_.release()); @@ -972,6 +1045,11 @@ template inline _LIBCPP_INLINE_VISIBILITY __hash_table<_Tp, _Hash, _Equal, _Alloc>& __hash_table<_Tp, _Hash, _Equal, _Alloc>::operator=(__hash_table&& __u) + _NOEXCEPT_( + __node_traits::propagate_on_container_move_assignment::value && + is_nothrow_move_assignable<__node_allocator>::value && + is_nothrow_move_assignable::value && + is_nothrow_move_assignable::value) { __move_assign(__u, integral_constant()); @@ -1051,7 +1129,7 @@ __hash_table<_Tp, _Hash, _Equal, _Alloc>::__assign_multi(_InputIterator __first, template inline _LIBCPP_INLINE_VISIBILITY typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::iterator -__hash_table<_Tp, _Hash, _Equal, _Alloc>::begin() +__hash_table<_Tp, _Hash, _Equal, _Alloc>::begin() _NOEXCEPT { return iterator(__p1_.first().__next_); } @@ -1059,7 +1137,7 @@ __hash_table<_Tp, _Hash, _Equal, _Alloc>::begin() template inline _LIBCPP_INLINE_VISIBILITY typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::iterator -__hash_table<_Tp, _Hash, _Equal, _Alloc>::end() +__hash_table<_Tp, _Hash, _Equal, _Alloc>::end() _NOEXCEPT { return iterator(nullptr); } @@ -1067,7 +1145,7 @@ __hash_table<_Tp, _Hash, _Equal, _Alloc>::end() template inline _LIBCPP_INLINE_VISIBILITY typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::const_iterator -__hash_table<_Tp, _Hash, _Equal, _Alloc>::begin() const +__hash_table<_Tp, _Hash, _Equal, _Alloc>::begin() const _NOEXCEPT { return const_iterator(__p1_.first().__next_); } @@ -1075,14 +1153,14 @@ __hash_table<_Tp, _Hash, _Equal, _Alloc>::begin() const template inline _LIBCPP_INLINE_VISIBILITY typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::const_iterator -__hash_table<_Tp, _Hash, _Equal, _Alloc>::end() const +__hash_table<_Tp, _Hash, _Equal, _Alloc>::end() const _NOEXCEPT { return const_iterator(nullptr); } template void -__hash_table<_Tp, _Hash, _Equal, _Alloc>::clear() +__hash_table<_Tp, _Hash, _Equal, _Alloc>::clear() _NOEXCEPT { if (size() > 0) { @@ -1645,7 +1723,7 @@ __hash_table<_Tp, _Hash, _Equal, _Alloc>::__erase_multi(const _Key& __k) template typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::__node_holder -__hash_table<_Tp, _Hash, _Equal, _Alloc>::remove(const_iterator __p) +__hash_table<_Tp, _Hash, _Equal, _Alloc>::remove(const_iterator __p) _NOEXCEPT { // current node __node_pointer __cn = const_cast<__node_pointer>(__p.__node_); @@ -1776,6 +1854,13 @@ __hash_table<_Tp, _Hash, _Equal, _Alloc>::__equal_range_multi( template void __hash_table<_Tp, _Hash, _Equal, _Alloc>::swap(__hash_table& __u) + _NOEXCEPT_( + (!allocator_traits<__pointer_allocator>::propagate_on_container_swap::value || + __is_nothrow_swappable<__pointer_allocator>::value) && + (!__node_traits::propagate_on_container_swap::value || + __is_nothrow_swappable<__node_allocator>::value) && + __is_nothrow_swappable::value && + __is_nothrow_swappable::value) { { __node_pointer_pointer __npp = __bucket_list_.release(); @@ -1814,6 +1899,16 @@ __hash_table<_Tp, _Hash, _Equal, _Alloc>::bucket_size(size_type __n) const return __r; } +template +inline _LIBCPP_INLINE_VISIBILITY +void +swap(__hash_table<_Tp, _Hash, _Equal, _Alloc>& __x, + __hash_table<_Tp, _Hash, _Equal, _Alloc>& __y) + _NOEXCEPT_(_NOEXCEPT_(__x.swap(__y))) +{ + __x.swap(__y); +} + _LIBCPP_END_NAMESPACE_STD #endif // _LIBCPP__HASH_TABLE diff --git a/include/unordered_map b/include/unordered_map index f2c5d710d..2a22a56d6 100644 --- a/include/unordered_map +++ b/include/unordered_map @@ -44,7 +44,12 @@ public: typedef /unspecified/ local_iterator; typedef /unspecified/ const_local_iterator; - explicit unordered_map(size_type n = 0, const hasher& hf = hasher(), + unordered_map() + noexcept( + is_nothrow_default_constructible::value && + is_nothrow_default_constructible::value && + is_nothrow_default_constructible::value); + explicit unordered_map(size_type n, const hasher& hf = hasher(), const key_equal& eql = key_equal(), const allocator_type& a = allocator_type()); template @@ -55,28 +60,37 @@ public: explicit unordered_map(const allocator_type&); unordered_map(const unordered_map&); unordered_map(const unordered_map&, const Allocator&); - unordered_map(unordered_map&&); + unordered_map(unordered_map&&) + noexcept( + is_nothrow_move_constructible::value && + is_nothrow_move_constructible::value && + is_nothrow_move_constructible::value); unordered_map(unordered_map&&, const Allocator&); unordered_map(initializer_list, size_type n = 0, const hasher& hf = hasher(), const key_equal& eql = key_equal(), const allocator_type& a = allocator_type()); ~unordered_map(); unordered_map& operator=(const unordered_map&); - unordered_map& operator=(unordered_map&&); + unordered_map& operator=(unordered_map&&) + noexcept( + allocator_type::propagate_on_container_move_assignment::value && + is_nothrow_move_assignable::value && + is_nothrow_move_assignable::value && + is_nothrow_move_assignable::value); unordered_map& operator=(initializer_list); - allocator_type get_allocator() const; + allocator_type get_allocator() const noexcept; - bool empty() const; - size_type size() const; - size_type max_size() const; + bool empty() const noexcept; + size_type size() const noexcept; + size_type max_size() const noexcept; - iterator begin(); - iterator end(); - const_iterator begin() const; - const_iterator end() const; - const_iterator cbegin() const; - const_iterator cend() const; + iterator begin() noexcept; + iterator end() noexcept; + const_iterator begin() const noexcept; + const_iterator end() const noexcept; + const_iterator cbegin() const noexcept; + const_iterator cend() const noexcept; template pair emplace(Args&&... args); @@ -95,9 +109,14 @@ public: iterator erase(const_iterator position); size_type erase(const key_type& k); iterator erase(const_iterator first, const_iterator last); - void clear(); + void clear() noexcept; - void swap(unordered_map&); + void swap(unordered_map&) + noexcept( + (!allocator_type::propagate_on_container_swap::value || + __is_nothrow_swappable::value) && + __is_nothrow_swappable::value && + __is_nothrow_swappable::value); hasher hash_function() const; key_equal key_eq() const; @@ -114,8 +133,8 @@ public: mapped_type& at(const key_type& k); const mapped_type& at(const key_type& k) const; - size_type bucket_count() const; - size_type max_bucket_count() const; + size_type bucket_count() const noexcept; + size_type max_bucket_count() const noexcept; size_type bucket_size(size_type n) const; size_type bucket(const key_type& k) const; @@ -127,8 +146,8 @@ public: const_local_iterator cbegin(size_type n) const; const_local_iterator cend(size_type n) const; - float load_factor() const; - float max_load_factor() const; + float load_factor() const noexcept; + float max_load_factor() const noexcept; void max_load_factor(float z); void rehash(size_type n); void reserve(size_type n); @@ -136,7 +155,8 @@ public: template void swap(unordered_map& x, - unordered_map& y); + unordered_map& y) + noexcept(noexcept(x.swap(y))); template bool @@ -172,7 +192,12 @@ public: typedef /unspecified/ local_iterator; typedef /unspecified/ const_local_iterator; - explicit unordered_multimap(size_type n = 0, const hasher& hf = hasher(), + unordered_multimap() + noexcept( + is_nothrow_default_constructible::value && + is_nothrow_default_constructible::value && + is_nothrow_default_constructible::value); + explicit unordered_multimap(size_type n, const hasher& hf = hasher(), const key_equal& eql = key_equal(), const allocator_type& a = allocator_type()); template @@ -183,28 +208,37 @@ public: explicit unordered_multimap(const allocator_type&); unordered_multimap(const unordered_multimap&); unordered_multimap(const unordered_multimap&, const Allocator&); - unordered_multimap(unordered_multimap&&); + unordered_multimap(unordered_multimap&&) + noexcept( + is_nothrow_move_constructible::value && + is_nothrow_move_constructible::value && + is_nothrow_move_constructible::value); unordered_multimap(unordered_multimap&&, const Allocator&); unordered_multimap(initializer_list, size_type n = 0, const hasher& hf = hasher(), const key_equal& eql = key_equal(), const allocator_type& a = allocator_type()); ~unordered_multimap(); unordered_multimap& operator=(const unordered_multimap&); - unordered_multimap& operator=(unordered_multimap&&); + unordered_multimap& operator=(unordered_multimap&&) + noexcept( + allocator_type::propagate_on_container_move_assignment::value && + is_nothrow_move_assignable::value && + is_nothrow_move_assignable::value && + is_nothrow_move_assignable::value); unordered_multimap& operator=(initializer_list); - allocator_type get_allocator() const; + allocator_type get_allocator() const noexcept; - bool empty() const; - size_type size() const; - size_type max_size() const; + bool empty() const noexcept; + size_type size() const noexcept; + size_type max_size() const noexcept; - iterator begin(); - iterator end(); - const_iterator begin() const; - const_iterator end() const; - const_iterator cbegin() const; - const_iterator cend() const; + iterator begin() noexcept; + iterator end() noexcept; + const_iterator begin() const noexcept; + const_iterator end() const noexcept; + const_iterator cbegin() const noexcept; + const_iterator cend() const noexcept; template iterator emplace(Args&&... args); @@ -223,9 +257,14 @@ public: iterator erase(const_iterator position); size_type erase(const key_type& k); iterator erase(const_iterator first, const_iterator last); - void clear(); + void clear() noexcept; - void swap(unordered_multimap&); + void swap(unordered_multimap&) + noexcept( + (!allocator_type::propagate_on_container_swap::value || + __is_nothrow_swappable::value) && + __is_nothrow_swappable::value && + __is_nothrow_swappable::value); hasher hash_function() const; key_equal key_eq() const; @@ -236,8 +275,8 @@ public: pair equal_range(const key_type& k); pair equal_range(const key_type& k) const; - size_type bucket_count() const; - size_type max_bucket_count() const; + size_type bucket_count() const noexcept; + size_type max_bucket_count() const noexcept; size_type bucket_size(size_type n) const; size_type bucket(const key_type& k) const; @@ -249,8 +288,8 @@ public: const_local_iterator cbegin(size_type n) const; const_local_iterator cend(size_type n) const; - float load_factor() const; - float max_load_factor() const; + float load_factor() const noexcept; + float max_load_factor() const noexcept; void max_load_factor(float z); void rehash(size_type n); void reserve(size_type n); @@ -258,7 +297,8 @@ public: template void swap(unordered_multimap& x, - unordered_multimap& y); + unordered_multimap& y) + noexcept(noexcept(x.swap(y))); template bool @@ -289,11 +329,15 @@ class __unordered_map_hasher { public: _LIBCPP_INLINE_VISIBILITY - __unordered_map_hasher() : _Hash() {} + __unordered_map_hasher() + _NOEXCEPT_(is_nothrow_default_constructible<_Hash>::value) + : _Hash() {} _LIBCPP_INLINE_VISIBILITY - __unordered_map_hasher(const _Hash& __h) : _Hash(__h) {} + __unordered_map_hasher(const _Hash& __h) + _NOEXCEPT_(is_nothrow_copy_constructible<_Hash>::value) + : _Hash(__h) {} _LIBCPP_INLINE_VISIBILITY - const _Hash& hash_function() const {return *this;} + const _Hash& hash_function() const _NOEXCEPT {return *this;} _LIBCPP_INLINE_VISIBILITY size_t operator()(const _Tp& __x) const {return static_cast(*this)(__x.first);} @@ -308,11 +352,15 @@ class __unordered_map_hasher<_Tp, _Hash, false> _Hash __hash_; public: _LIBCPP_INLINE_VISIBILITY - __unordered_map_hasher() : __hash_() {} + __unordered_map_hasher() + _NOEXCEPT_(is_nothrow_default_constructible<_Hash>::value) + : __hash_() {} _LIBCPP_INLINE_VISIBILITY - __unordered_map_hasher(const _Hash& __h) : __hash_(__h) {} + __unordered_map_hasher(const _Hash& __h) + _NOEXCEPT_(is_nothrow_copy_constructible<_Hash>::value) + : __hash_(__h) {} _LIBCPP_INLINE_VISIBILITY - const _Hash& hash_function() const {return __hash_;} + const _Hash& hash_function() const _NOEXCEPT {return __hash_;} _LIBCPP_INLINE_VISIBILITY size_t operator()(const _Tp& __x) const {return __hash_(__x.first);} @@ -327,11 +375,15 @@ class __unordered_map_equal { public: _LIBCPP_INLINE_VISIBILITY - __unordered_map_equal() : _Pred() {} + __unordered_map_equal() + _NOEXCEPT_(is_nothrow_default_constructible<_Pred>::value) + : _Pred() {} _LIBCPP_INLINE_VISIBILITY - __unordered_map_equal(const _Pred& __p) : _Pred(__p) {} + __unordered_map_equal(const _Pred& __p) + _NOEXCEPT_(is_nothrow_copy_constructible<_Pred>::value) + : _Pred(__p) {} _LIBCPP_INLINE_VISIBILITY - const _Pred& key_eq() const {return *this;} + const _Pred& key_eq() const _NOEXCEPT {return *this;} _LIBCPP_INLINE_VISIBILITY bool operator()(const _Tp& __x, const _Tp& __y) const {return static_cast(*this)(__x.first, __y.first);} @@ -353,11 +405,15 @@ class __unordered_map_equal<_Tp, _Pred, false> _Pred __pred_; public: _LIBCPP_INLINE_VISIBILITY - __unordered_map_equal() : __pred_() {} + __unordered_map_equal() + _NOEXCEPT_(is_nothrow_default_constructible<_Pred>::value) + : __pred_() {} _LIBCPP_INLINE_VISIBILITY - __unordered_map_equal(const _Pred& __p) : __pred_(__p) {} + __unordered_map_equal(const _Pred& __p) + _NOEXCEPT_(is_nothrow_copy_constructible<_Pred>::value) + : __pred_(__p) {} _LIBCPP_INLINE_VISIBILITY - const _Pred& key_eq() const {return __pred_;} + const _Pred& key_eq() const _NOEXCEPT {return __pred_;} _LIBCPP_INLINE_VISIBILITY bool operator()(const _Tp& __x, const _Tp& __y) const {return __pred_(__x.first, __y.first);} @@ -394,7 +450,7 @@ public: bool __second_constructed; _LIBCPP_INLINE_VISIBILITY - explicit __hash_map_node_destructor(allocator_type& __na) + explicit __hash_map_node_destructor(allocator_type& __na) _NOEXCEPT : __na_(__na), __first_constructed(false), __second_constructed(false) @@ -403,6 +459,7 @@ public: #ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES _LIBCPP_INLINE_VISIBILITY __hash_map_node_destructor(__hash_node_destructor&& __x) + _NOEXCEPT : __na_(__x.__na_), __first_constructed(__x.__value_constructed), __second_constructed(__x.__value_constructed) @@ -421,7 +478,7 @@ public: #endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES _LIBCPP_INLINE_VISIBILITY - void operator()(pointer __p) + void operator()(pointer __p) _NOEXCEPT { if (__second_constructed) __alloc_traits::destroy(__na_, _STD::addressof(__p->__value_.second)); @@ -454,10 +511,10 @@ public: pointer; _LIBCPP_INLINE_VISIBILITY - __hash_map_iterator() {} + __hash_map_iterator() _NOEXCEPT {} _LIBCPP_INLINE_VISIBILITY - __hash_map_iterator(_HashIterator __i) : __i_(__i) {} + __hash_map_iterator(_HashIterator __i) _NOEXCEPT : __i_(__i) {} _LIBCPP_INLINE_VISIBILITY reference operator*() const {return *operator->();} @@ -510,13 +567,14 @@ public: pointer; _LIBCPP_INLINE_VISIBILITY - __hash_map_const_iterator() {} + __hash_map_const_iterator() _NOEXCEPT {} _LIBCPP_INLINE_VISIBILITY - __hash_map_const_iterator(_HashIterator __i) : __i_(__i) {} + __hash_map_const_iterator(_HashIterator __i) _NOEXCEPT : __i_(__i) {} _LIBCPP_INLINE_VISIBILITY __hash_map_const_iterator( __hash_map_iterator __i) + _NOEXCEPT : __i_(__i.__i_) {} _LIBCPP_INLINE_VISIBILITY @@ -599,7 +657,9 @@ public: typedef __hash_map_const_iterator const_local_iterator; _LIBCPP_INLINE_VISIBILITY - unordered_map() {} // = default; + unordered_map() + _NOEXCEPT_(is_nothrow_default_constructible<__table>::value) + {} // = default; explicit unordered_map(size_type __n, const hasher& __hf = hasher(), const key_equal& __eql = key_equal()); unordered_map(size_type __n, const hasher& __hf, @@ -620,7 +680,8 @@ public: unordered_map(const unordered_map& __u); unordered_map(const unordered_map& __u, const allocator_type& __a); #ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES - unordered_map(unordered_map&& __u); + unordered_map(unordered_map&& __u) + _NOEXCEPT_(is_nothrow_move_constructible<__table>::value); unordered_map(unordered_map&& __u, const allocator_type& __a); #endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES unordered_map(initializer_list __il); @@ -632,33 +693,34 @@ public: // ~unordered_map() = default; // unordered_map& operator=(const unordered_map& __u) = default; #ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES - unordered_map& operator=(unordered_map&& __u); + unordered_map& operator=(unordered_map&& __u) + _NOEXCEPT_(is_nothrow_move_assignable<__table>::value); #endif unordered_map& operator=(initializer_list __il); _LIBCPP_INLINE_VISIBILITY - allocator_type get_allocator() const + allocator_type get_allocator() const _NOEXCEPT {return allocator_type(__table_.__node_alloc());} _LIBCPP_INLINE_VISIBILITY - bool empty() const {return __table_.size() == 0;} + bool empty() const _NOEXCEPT {return __table_.size() == 0;} _LIBCPP_INLINE_VISIBILITY - size_type size() const {return __table_.size();} + size_type size() const _NOEXCEPT {return __table_.size();} _LIBCPP_INLINE_VISIBILITY - size_type max_size() const {return __table_.max_size();} + size_type max_size() const _NOEXCEPT {return __table_.max_size();} _LIBCPP_INLINE_VISIBILITY - iterator begin() {return __table_.begin();} + iterator begin() _NOEXCEPT {return __table_.begin();} _LIBCPP_INLINE_VISIBILITY - iterator end() {return __table_.end();} + iterator end() _NOEXCEPT {return __table_.end();} _LIBCPP_INLINE_VISIBILITY - const_iterator begin() const {return __table_.begin();} + const_iterator begin() const _NOEXCEPT {return __table_.begin();} _LIBCPP_INLINE_VISIBILITY - const_iterator end() const {return __table_.end();} + const_iterator end() const _NOEXCEPT {return __table_.end();} _LIBCPP_INLINE_VISIBILITY - const_iterator cbegin() const {return __table_.begin();} + const_iterator cbegin() const _NOEXCEPT {return __table_.begin();} _LIBCPP_INLINE_VISIBILITY - const_iterator cend() const {return __table_.end();} + const_iterator cend() const _NOEXCEPT {return __table_.end();} #ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES _LIBCPP_INLINE_VISIBILITY @@ -733,10 +795,12 @@ public: iterator erase(const_iterator __first, const_iterator __last) {return __table_.erase(__first.__i_, __last.__i_);} _LIBCPP_INLINE_VISIBILITY - void clear() {__table_.clear();} + void clear() _NOEXCEPT {__table_.clear();} _LIBCPP_INLINE_VISIBILITY - void swap(unordered_map& __u) {__table_.swap(__u.__table_);} + void swap(unordered_map& __u) + _NOEXCEPT_(__is_nothrow_swappable<__table>::value) + {__table_.swap(__u.__table_);} _LIBCPP_INLINE_VISIBILITY hasher hash_function() const @@ -767,9 +831,9 @@ public: const mapped_type& at(const key_type& __k) const; _LIBCPP_INLINE_VISIBILITY - size_type bucket_count() const {return __table_.bucket_count();} + size_type bucket_count() const _NOEXCEPT {return __table_.bucket_count();} _LIBCPP_INLINE_VISIBILITY - size_type max_bucket_count() const {return __table_.max_bucket_count();} + size_type max_bucket_count() const _NOEXCEPT {return __table_.max_bucket_count();} _LIBCPP_INLINE_VISIBILITY size_type bucket_size(size_type __n) const @@ -791,9 +855,9 @@ public: const_local_iterator cend(size_type __n) const {return __table_.cend(__n);} _LIBCPP_INLINE_VISIBILITY - float load_factor() const {return __table_.load_factor();} + float load_factor() const _NOEXCEPT {return __table_.load_factor();} _LIBCPP_INLINE_VISIBILITY - float max_load_factor() const {return __table_.max_load_factor();} + float max_load_factor() const _NOEXCEPT {return __table_.max_load_factor();} _LIBCPP_INLINE_VISIBILITY void max_load_factor(float __mlf) {__table_.max_load_factor(__mlf);} _LIBCPP_INLINE_VISIBILITY @@ -895,6 +959,7 @@ template inline _LIBCPP_INLINE_VISIBILITY unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>::unordered_map( unordered_map&& __u) + _NOEXCEPT_(is_nothrow_move_constructible<__table>::value) : __table_(_STD::move(__u.__table_)) { } @@ -949,6 +1014,7 @@ template inline _LIBCPP_INLINE_VISIBILITY unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>& unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>::operator=(unordered_map&& __u) + _NOEXCEPT_(is_nothrow_move_assignable<__table>::value) { __table_ = _STD::move(__u.__table_); return *this; @@ -1111,6 +1177,7 @@ inline _LIBCPP_INLINE_VISIBILITY 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); } @@ -1193,7 +1260,9 @@ public: typedef __hash_map_const_iterator const_local_iterator; _LIBCPP_INLINE_VISIBILITY - unordered_multimap() {} // = default + unordered_multimap() + _NOEXCEPT_(is_nothrow_default_constructible<__table>::value) + {} // = default; explicit unordered_multimap(size_type __n, const hasher& __hf = hasher(), const key_equal& __eql = key_equal()); unordered_multimap(size_type __n, const hasher& __hf, @@ -1214,7 +1283,8 @@ public: unordered_multimap(const unordered_multimap& __u); unordered_multimap(const unordered_multimap& __u, const allocator_type& __a); #ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES - unordered_multimap(unordered_multimap&& __u); + unordered_multimap(unordered_multimap&& __u) + _NOEXCEPT_(is_nothrow_move_constructible<__table>::value); unordered_multimap(unordered_multimap&& __u, const allocator_type& __a); #endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES unordered_multimap(initializer_list __il); @@ -1227,33 +1297,34 @@ public: // ~unordered_multimap() = default; // unordered_multimap& operator=(const unordered_multimap& __u) = default; #ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES - unordered_multimap& operator=(unordered_multimap&& __u); + unordered_multimap& operator=(unordered_multimap&& __u) + _NOEXCEPT_(is_nothrow_move_assignable<__table>::value); #endif unordered_multimap& operator=(initializer_list __il); _LIBCPP_INLINE_VISIBILITY - allocator_type get_allocator() const + allocator_type get_allocator() const _NOEXCEPT {return allocator_type(__table_.__node_alloc());} _LIBCPP_INLINE_VISIBILITY - bool empty() const {return __table_.size() == 0;} + bool empty() const _NOEXCEPT {return __table_.size() == 0;} _LIBCPP_INLINE_VISIBILITY - size_type size() const {return __table_.size();} + size_type size() const _NOEXCEPT {return __table_.size();} _LIBCPP_INLINE_VISIBILITY - size_type max_size() const {return __table_.max_size();} + size_type max_size() const _NOEXCEPT {return __table_.max_size();} _LIBCPP_INLINE_VISIBILITY - iterator begin() {return __table_.begin();} + iterator begin() _NOEXCEPT {return __table_.begin();} _LIBCPP_INLINE_VISIBILITY - iterator end() {return __table_.end();} + iterator end() _NOEXCEPT {return __table_.end();} _LIBCPP_INLINE_VISIBILITY - const_iterator begin() const {return __table_.begin();} + const_iterator begin() const _NOEXCEPT {return __table_.begin();} _LIBCPP_INLINE_VISIBILITY - const_iterator end() const {return __table_.end();} + const_iterator end() const _NOEXCEPT {return __table_.end();} _LIBCPP_INLINE_VISIBILITY - const_iterator cbegin() const {return __table_.begin();} + const_iterator cbegin() const _NOEXCEPT {return __table_.begin();} _LIBCPP_INLINE_VISIBILITY - const_iterator cend() const {return __table_.end();} + const_iterator cend() const _NOEXCEPT {return __table_.end();} #ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES _LIBCPP_INLINE_VISIBILITY @@ -1324,10 +1395,12 @@ public: iterator erase(const_iterator __first, const_iterator __last) {return __table_.erase(__first.__i_, __last.__i_);} _LIBCPP_INLINE_VISIBILITY - void clear() {__table_.clear();} + void clear() _NOEXCEPT {__table_.clear();} _LIBCPP_INLINE_VISIBILITY - void swap(unordered_multimap& __u) {__table_.swap(__u.__table_);} + void swap(unordered_multimap& __u) + _NOEXCEPT_(__is_nothrow_swappable<__table>::value) + {__table_.swap(__u.__table_);} _LIBCPP_INLINE_VISIBILITY hasher hash_function() const @@ -1350,9 +1423,10 @@ public: {return __table_.__equal_range_multi(__k);} _LIBCPP_INLINE_VISIBILITY - size_type bucket_count() const {return __table_.bucket_count();} + size_type bucket_count() const _NOEXCEPT {return __table_.bucket_count();} _LIBCPP_INLINE_VISIBILITY - size_type max_bucket_count() const {return __table_.max_bucket_count();} + size_type max_bucket_count() const _NOEXCEPT + {return __table_.max_bucket_count();} _LIBCPP_INLINE_VISIBILITY size_type bucket_size(size_type __n) const @@ -1374,9 +1448,9 @@ public: const_local_iterator cend(size_type __n) const {return __table_.cend(__n);} _LIBCPP_INLINE_VISIBILITY - float load_factor() const {return __table_.load_factor();} + float load_factor() const _NOEXCEPT {return __table_.load_factor();} _LIBCPP_INLINE_VISIBILITY - float max_load_factor() const {return __table_.max_load_factor();} + float max_load_factor() const _NOEXCEPT {return __table_.max_load_factor();} _LIBCPP_INLINE_VISIBILITY void max_load_factor(float __mlf) {__table_.max_load_factor(__mlf);} _LIBCPP_INLINE_VISIBILITY @@ -1474,6 +1548,7 @@ template inline _LIBCPP_INLINE_VISIBILITY unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>::unordered_multimap( unordered_multimap&& __u) + _NOEXCEPT_(is_nothrow_move_constructible<__table>::value) : __table_(_STD::move(__u.__table_)) { } @@ -1530,6 +1605,7 @@ template inline _LIBCPP_INLINE_VISIBILITY unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>& unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>::operator=(unordered_multimap&& __u) + _NOEXCEPT_(is_nothrow_move_assignable<__table>::value) { __table_ = _STD::move(__u.__table_); return *this; @@ -1637,6 +1713,7 @@ inline _LIBCPP_INLINE_VISIBILITY 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); } diff --git a/test/containers/unord/unord.map/unord.map.cnstr/default_noexcept.pass.cpp b/test/containers/unord/unord.map/unord.map.cnstr/default_noexcept.pass.cpp new file mode 100644 index 000000000..7f426fdb4 --- /dev/null +++ b/test/containers/unord/unord.map/unord.map.cnstr/default_noexcept.pass.cpp @@ -0,0 +1,70 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// + +// unordered_map() +// noexcept( +// is_nothrow_default_constructible::value && +// is_nothrow_default_constructible::value && +// is_nothrow_copy_constructible::value); + +// This tests a conforming extension + +#include +#include + +#include "../../../MoveOnly.h" +#include "../../../test_allocator.h" +#include "../../../test_hash.h" + +template +struct some_comp +{ + typedef T value_type; + some_comp(); + some_comp(const some_comp&); +}; + +template +struct some_hash +{ + typedef T value_type; + some_hash(); + some_hash(const some_hash&); +}; + +int main() +{ +#if __has_feature(cxx_noexcept) + { + typedef std::unordered_map C; + static_assert(std::is_nothrow_default_constructible::value, ""); + } + { + typedef std::unordered_map, + std::equal_to, test_allocator> C; + static_assert(std::is_nothrow_default_constructible::value, ""); + } + { + typedef std::unordered_map, + std::equal_to, other_allocator> C; + static_assert(!std::is_nothrow_default_constructible::value, ""); + } + { + typedef std::unordered_map> C; + static_assert(!std::is_nothrow_default_constructible::value, ""); + } + { + typedef std::unordered_map, + some_comp> C; + static_assert(!std::is_nothrow_default_constructible::value, ""); + } +#endif +} diff --git a/test/containers/unord/unord.map/unord.map.cnstr/dtor_noexcept.pass.cpp b/test/containers/unord/unord.map/unord.map.cnstr/dtor_noexcept.pass.cpp new file mode 100644 index 000000000..e605b66e4 --- /dev/null +++ b/test/containers/unord/unord.map/unord.map.cnstr/dtor_noexcept.pass.cpp @@ -0,0 +1,67 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// + +// ~unordered_map() // implied noexcept; + +#include +#include + +#include "../../../MoveOnly.h" +#include "../../../test_allocator.h" + +#if __has_feature(cxx_noexcept) + +template +struct some_comp +{ + typedef T value_type; + ~some_comp() noexcept(false); +}; + +template +struct some_hash +{ + typedef T value_type; + some_hash(); + some_hash(const some_hash&); + ~some_hash() noexcept(false); +}; + +#endif + +int main() +{ +#if __has_feature(cxx_noexcept) + { + typedef std::unordered_map C; + static_assert(std::is_nothrow_destructible::value, ""); + } + { + typedef std::unordered_map, + std::equal_to, test_allocator> C; + static_assert(std::is_nothrow_destructible::value, ""); + } + { + typedef std::unordered_map, + std::equal_to, other_allocator> C; + static_assert(std::is_nothrow_destructible::value, ""); + } + { + typedef std::unordered_map> C; + static_assert(!std::is_nothrow_destructible::value, ""); + } + { + typedef std::unordered_map, + some_comp> C; + static_assert(!std::is_nothrow_destructible::value, ""); + } +#endif +} diff --git a/test/containers/unord/unord.map/unord.map.cnstr/move_assign_noexcept.pass.cpp b/test/containers/unord/unord.map/unord.map.cnstr/move_assign_noexcept.pass.cpp new file mode 100644 index 000000000..758a78688 --- /dev/null +++ b/test/containers/unord/unord.map/unord.map.cnstr/move_assign_noexcept.pass.cpp @@ -0,0 +1,69 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// + +// unordered_map& operator=(unordered_map&& c) +// noexcept( +// allocator_type::propagate_on_container_move_assignment::value && +// is_nothrow_move_assignable::value && +// is_nothrow_move_assignable::value); + +// This tests a conforming extension + +#include +#include + +#include "../../../MoveOnly.h" +#include "../../../test_allocator.h" + +template +struct some_comp +{ + typedef T value_type; + some_comp& operator=(const some_comp&); +}; + +template +struct some_hash +{ + typedef T value_type; + some_hash(); + some_hash(const some_hash&); + some_hash& operator=(const some_hash&); +}; + +int main() +{ +#if __has_feature(cxx_noexcept) + { + typedef std::unordered_map C; + static_assert(std::is_nothrow_move_assignable::value, ""); + } + { + typedef std::unordered_map, + std::equal_to, test_allocator> C; + static_assert(!std::is_nothrow_move_assignable::value, ""); + } + { + typedef std::unordered_map, + std::equal_to, other_allocator> C; + static_assert(std::is_nothrow_move_assignable::value, ""); + } + { + typedef std::unordered_map> C; + static_assert(!std::is_nothrow_move_assignable::value, ""); + } + { + typedef std::unordered_map, + some_comp> C; + static_assert(!std::is_nothrow_move_assignable::value, ""); + } +#endif +} diff --git a/test/containers/unord/unord.map/unord.map.cnstr/move_noexcept.pass.cpp b/test/containers/unord/unord.map/unord.map.cnstr/move_noexcept.pass.cpp new file mode 100644 index 000000000..952c478b1 --- /dev/null +++ b/test/containers/unord/unord.map/unord.map.cnstr/move_noexcept.pass.cpp @@ -0,0 +1,66 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// + +// unordered_map(unordered_map&&) +// noexcept(is_nothrow_move_constructible::value && +// is_nothrow_move_constructible::value); + +// This tests a conforming extension + +#include +#include + +#include "../../../MoveOnly.h" +#include "../../../test_allocator.h" + +template +struct some_comp +{ + typedef T value_type; + some_comp(const some_comp&); +}; + +template +struct some_hash +{ + typedef T value_type; + some_hash(); + some_hash(const some_hash&); +}; + +int main() +{ +#if __has_feature(cxx_noexcept) + { + typedef std::unordered_map C; + static_assert(std::is_nothrow_move_constructible::value, ""); + } + { + typedef std::unordered_map, + std::equal_to, test_allocator> C; + static_assert(std::is_nothrow_move_constructible::value, ""); + } + { + typedef std::unordered_map, + std::equal_to, other_allocator> C; + static_assert(std::is_nothrow_move_constructible::value, ""); + } + { + typedef std::unordered_map> C; + static_assert(!std::is_nothrow_move_constructible::value, ""); + } + { + typedef std::unordered_map, + some_comp> C; + static_assert(!std::is_nothrow_move_constructible::value, ""); + } +#endif +} diff --git a/test/containers/unord/unord.map/unord.map.swap/swap_noexcept.pass.cpp b/test/containers/unord/unord.map/unord.map.swap/swap_noexcept.pass.cpp new file mode 100644 index 000000000..3786f18f5 --- /dev/null +++ b/test/containers/unord/unord.map/unord.map.swap/swap_noexcept.pass.cpp @@ -0,0 +1,73 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// + +// void swap(unordered_map& c) +// noexcept(!allocator_type::propagate_on_container_swap::value || +// __is_nothrow_swappable::value); + +// This tests a conforming extension + +#include +#include + +#include "../../../MoveOnly.h" +#include "../../../test_allocator.h" + +template +struct some_comp +{ + typedef T value_type; + + some_comp() {} + some_comp(const some_comp&) {} +}; + +template +struct some_hash +{ + typedef T value_type; + some_hash() {} + some_hash(const some_hash&); +}; + +int main() +{ +#if __has_feature(cxx_noexcept) + { + typedef std::unordered_map C; + C c1, c2; + static_assert(noexcept(swap(c1, c2)), ""); + } + { + typedef std::unordered_map, + std::equal_to, test_allocator> C; + C c1, c2; + static_assert(noexcept(swap(c1, c2)), ""); + } + { + typedef std::unordered_map, + std::equal_to, other_allocator> C; + C c1, c2; + static_assert(noexcept(swap(c1, c2)), ""); + } + { + typedef std::unordered_map> C; + C c1, c2; + static_assert(!noexcept(swap(c1, c2)), ""); + } + { + typedef std::unordered_map, + some_comp> C; + C c1, c2; + static_assert(!noexcept(swap(c1, c2)), ""); + } +#endif +} diff --git a/test/containers/unord/unord.multimap/unord.multimap.cnstr/default_noexcept.pass.cpp b/test/containers/unord/unord.multimap/unord.multimap.cnstr/default_noexcept.pass.cpp new file mode 100644 index 000000000..cbf7a0da9 --- /dev/null +++ b/test/containers/unord/unord.multimap/unord.multimap.cnstr/default_noexcept.pass.cpp @@ -0,0 +1,70 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// + +// unordered_multimap() +// noexcept( +// is_nothrow_default_constructible::value && +// is_nothrow_default_constructible::value && +// is_nothrow_copy_constructible::value); + +// This tests a conforming extension + +#include +#include + +#include "../../../MoveOnly.h" +#include "../../../test_allocator.h" +#include "../../../test_hash.h" + +template +struct some_comp +{ + typedef T value_type; + some_comp(); + some_comp(const some_comp&); +}; + +template +struct some_hash +{ + typedef T value_type; + some_hash(); + some_hash(const some_hash&); +}; + +int main() +{ +#if __has_feature(cxx_noexcept) + { + typedef std::unordered_multimap C; + static_assert(std::is_nothrow_default_constructible::value, ""); + } + { + typedef std::unordered_multimap, + std::equal_to, test_allocator> C; + static_assert(std::is_nothrow_default_constructible::value, ""); + } + { + typedef std::unordered_multimap, + std::equal_to, other_allocator> C; + static_assert(!std::is_nothrow_default_constructible::value, ""); + } + { + typedef std::unordered_multimap> C; + static_assert(!std::is_nothrow_default_constructible::value, ""); + } + { + typedef std::unordered_multimap, + some_comp> C; + static_assert(!std::is_nothrow_default_constructible::value, ""); + } +#endif +} diff --git a/test/containers/unord/unord.multimap/unord.multimap.cnstr/dtor_noexcept.pass.cpp b/test/containers/unord/unord.multimap/unord.multimap.cnstr/dtor_noexcept.pass.cpp new file mode 100644 index 000000000..2833f7e8a --- /dev/null +++ b/test/containers/unord/unord.multimap/unord.multimap.cnstr/dtor_noexcept.pass.cpp @@ -0,0 +1,67 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// + +// ~unordered_multimap() // implied noexcept; + +#include +#include + +#include "../../../MoveOnly.h" +#include "../../../test_allocator.h" + +#if __has_feature(cxx_noexcept) + +template +struct some_comp +{ + typedef T value_type; + ~some_comp() noexcept(false); +}; + +template +struct some_hash +{ + typedef T value_type; + some_hash(); + some_hash(const some_hash&); + ~some_hash() noexcept(false); +}; + +#endif + +int main() +{ +#if __has_feature(cxx_noexcept) + { + typedef std::unordered_multimap C; + static_assert(std::is_nothrow_destructible::value, ""); + } + { + typedef std::unordered_multimap, + std::equal_to, test_allocator> C; + static_assert(std::is_nothrow_destructible::value, ""); + } + { + typedef std::unordered_multimap, + std::equal_to, other_allocator> C; + static_assert(std::is_nothrow_destructible::value, ""); + } + { + typedef std::unordered_multimap> C; + static_assert(!std::is_nothrow_destructible::value, ""); + } + { + typedef std::unordered_multimap, + some_comp> C; + static_assert(!std::is_nothrow_destructible::value, ""); + } +#endif +} diff --git a/test/containers/unord/unord.multimap/unord.multimap.cnstr/move_assign_noexcept.pass.cpp b/test/containers/unord/unord.multimap/unord.multimap.cnstr/move_assign_noexcept.pass.cpp new file mode 100644 index 000000000..d53c5cdb8 --- /dev/null +++ b/test/containers/unord/unord.multimap/unord.multimap.cnstr/move_assign_noexcept.pass.cpp @@ -0,0 +1,69 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// + +// unordered_multimap& operator=(unordered_multimap&& c) +// noexcept( +// allocator_type::propagate_on_container_move_assignment::value && +// is_nothrow_move_assignable::value && +// is_nothrow_move_assignable::value); + +// This tests a conforming extension + +#include +#include + +#include "../../../MoveOnly.h" +#include "../../../test_allocator.h" + +template +struct some_comp +{ + typedef T value_type; + some_comp& operator=(const some_comp&); +}; + +template +struct some_hash +{ + typedef T value_type; + some_hash(); + some_hash(const some_hash&); + some_hash& operator=(const some_hash&); +}; + +int main() +{ +#if __has_feature(cxx_noexcept) + { + typedef std::unordered_multimap C; + static_assert(std::is_nothrow_move_assignable::value, ""); + } + { + typedef std::unordered_multimap, + std::equal_to, test_allocator> C; + static_assert(!std::is_nothrow_move_assignable::value, ""); + } + { + typedef std::unordered_multimap, + std::equal_to, other_allocator> C; + static_assert(std::is_nothrow_move_assignable::value, ""); + } + { + typedef std::unordered_multimap> C; + static_assert(!std::is_nothrow_move_assignable::value, ""); + } + { + typedef std::unordered_multimap, + some_comp> C; + static_assert(!std::is_nothrow_move_assignable::value, ""); + } +#endif +} diff --git a/test/containers/unord/unord.multimap/unord.multimap.cnstr/move_noexcept.pass.cpp b/test/containers/unord/unord.multimap/unord.multimap.cnstr/move_noexcept.pass.cpp new file mode 100644 index 000000000..b6e7c4de3 --- /dev/null +++ b/test/containers/unord/unord.multimap/unord.multimap.cnstr/move_noexcept.pass.cpp @@ -0,0 +1,66 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// + +// unordered_multimap(unordered_multimap&&) +// noexcept(is_nothrow_move_constructible::value && +// is_nothrow_move_constructible::value); + +// This tests a conforming extension + +#include +#include + +#include "../../../MoveOnly.h" +#include "../../../test_allocator.h" + +template +struct some_comp +{ + typedef T value_type; + some_comp(const some_comp&); +}; + +template +struct some_hash +{ + typedef T value_type; + some_hash(); + some_hash(const some_hash&); +}; + +int main() +{ +#if __has_feature(cxx_noexcept) + { + typedef std::unordered_multimap C; + static_assert(std::is_nothrow_move_constructible::value, ""); + } + { + typedef std::unordered_multimap, + std::equal_to, test_allocator> C; + static_assert(std::is_nothrow_move_constructible::value, ""); + } + { + typedef std::unordered_multimap, + std::equal_to, other_allocator> C; + static_assert(std::is_nothrow_move_constructible::value, ""); + } + { + typedef std::unordered_multimap> C; + static_assert(!std::is_nothrow_move_constructible::value, ""); + } + { + typedef std::unordered_multimap, + some_comp> C; + static_assert(!std::is_nothrow_move_constructible::value, ""); + } +#endif +} diff --git a/test/containers/unord/unord.multimap/unord.multimap.swap/swap_noexcept.pass.cpp b/test/containers/unord/unord.multimap/unord.multimap.swap/swap_noexcept.pass.cpp new file mode 100644 index 000000000..2560919b1 --- /dev/null +++ b/test/containers/unord/unord.multimap/unord.multimap.swap/swap_noexcept.pass.cpp @@ -0,0 +1,73 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// + +// void swap(unordered_multimap& c) +// noexcept(!allocator_type::propagate_on_container_swap::value || +// __is_nothrow_swappable::value); + +// This tests a conforming extension + +#include +#include + +#include "../../../MoveOnly.h" +#include "../../../test_allocator.h" + +template +struct some_comp +{ + typedef T value_type; + + some_comp() {} + some_comp(const some_comp&) {} +}; + +template +struct some_hash +{ + typedef T value_type; + some_hash() {} + some_hash(const some_hash&); +}; + +int main() +{ +#if __has_feature(cxx_noexcept) + { + typedef std::unordered_multimap C; + C c1, c2; + static_assert(noexcept(swap(c1, c2)), ""); + } + { + typedef std::unordered_multimap, + std::equal_to, test_allocator> C; + C c1, c2; + static_assert(noexcept(swap(c1, c2)), ""); + } + { + typedef std::unordered_multimap, + std::equal_to, other_allocator> C; + C c1, c2; + static_assert(noexcept(swap(c1, c2)), ""); + } + { + typedef std::unordered_multimap> C; + C c1, c2; + static_assert(!noexcept(swap(c1, c2)), ""); + } + { + typedef std::unordered_multimap, + some_comp> C; + C c1, c2; + static_assert(!noexcept(swap(c1, c2)), ""); + } +#endif +}