From 18884f4e9f19f81e8772f4ce324e509e11928cdc Mon Sep 17 00:00:00 2001 From: Howard Hinnant Date: Thu, 2 Jun 2011 21:38:57 +0000 Subject: [PATCH] Second try at getting noexcept on move and swap for deque. I changed std::alloctor to propagate_on_container_move_assignment so as to make deque move assignment noexcept. What we really need is a compile-time switch that says an allocator always compares equal. git-svn-id: https://llvm.org/svn/llvm-project/libcxx/trunk@132490 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/deque | 41 +++++++++++++++++++++-------------------- include/memory | 2 ++ 2 files changed, 23 insertions(+), 20 deletions(-) diff --git a/include/deque b/include/deque index 1ffd9d81..a4920598 100644 --- a/include/deque +++ b/include/deque @@ -48,14 +48,18 @@ public: template deque(InputIterator f, InputIterator l, const allocator_type& a); deque(const deque& c); - deque(deque&& c); + deque(deque&& c) + noexcept(is_nothrow_move_constructible::value); deque(initializer_list il, const Allocator& a = allocator_type()); deque(const deque& c, const allocator_type& a); deque(deque&& c, const allocator_type& a); ~deque(); deque& operator=(const deque& c); - deque& operator=(deque&& c); + deque& operator=(deque&& c) + noexcept( + allocator_type::propagate_on_container_move_assignment::value && + is_nothrow_move_assignable::value); deque& operator=(initializer_list il); template @@ -118,7 +122,9 @@ public: void pop_back(); iterator erase(const_iterator p); iterator erase(const_iterator f, const_iterator l); - void swap(deque& c); + void swap(deque& c) + noexcept(!allocator_type::propagate_on_container_swap::value || + __is_nothrow_swappable::value); void clear() noexcept; }; @@ -137,7 +143,7 @@ template // specialized algorithms: template - void swap(deque& x, deque& y); + void swap(deque& x, deque& y) noexcept(x.swap(y)); } // std @@ -950,9 +956,8 @@ protected: _LIBCPP_INLINE_VISIBILITY void __move_assign(__deque_base& __c) - _NOEXCEPT_(is_nothrow_move_assignable<__map>::value && - (!__alloc_traits::propagate_on_container_move_assignment::value || - is_nothrow_move_assignable::value)) + _NOEXCEPT_(__alloc_traits::propagate_on_container_move_assignment::value && + is_nothrow_move_assignable::value) { __map_ = _STD::move(__c.__map_); __start_ = __c.__start_; @@ -1204,11 +1209,8 @@ public: deque(deque&& __c) _NOEXCEPT_(is_nothrow_move_constructible<__base>::value); deque(deque&& __c, const allocator_type& __a); deque& operator=(deque&& __c) - _NOEXCEPT_( - (__alloc_traits::propagate_on_container_move_assignment::value && - is_nothrow_move_assignable::value) || - (!__alloc_traits::propagate_on_container_move_assignment::value && - is_nothrow_move_assignable::value)); + _NOEXCEPT_(__alloc_traits::propagate_on_container_move_assignment::value && + is_nothrow_move_assignable::value); #endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES template @@ -1269,7 +1271,7 @@ public: {return __alloc_traits::max_size(__base::__alloc());} void resize(size_type __n); void resize(size_type __n, const value_type& __v); - void shrink_to_fit(); + void shrink_to_fit() _NOEXCEPT; _LIBCPP_INLINE_VISIBILITY bool empty() const _NOEXCEPT {return __base::size() == 0;} @@ -1386,7 +1388,8 @@ private: void __copy_assign_alloc(const deque& __c, false_type) {} - void __move_assign(deque& __c, true_type); + void __move_assign(deque& __c, true_type) + _NOEXCEPT_(is_nothrow_move_assignable::value); void __move_assign(deque& __c, false_type); }; @@ -1494,11 +1497,8 @@ template inline _LIBCPP_INLINE_VISIBILITY deque<_Tp, _Allocator>& deque<_Tp, _Allocator>::operator=(deque&& __c) - _NOEXCEPT_( - (__alloc_traits::propagate_on_container_move_assignment::value && - is_nothrow_move_assignable::value) || - (!__alloc_traits::propagate_on_container_move_assignment::value && - is_nothrow_move_assignable::value)) + _NOEXCEPT_(__alloc_traits::propagate_on_container_move_assignment::value && + is_nothrow_move_assignable::value) { __move_assign(__c, integral_constant()); @@ -1521,6 +1521,7 @@ deque<_Tp, _Allocator>::__move_assign(deque& __c, false_type) template void deque<_Tp, _Allocator>::__move_assign(deque& __c, true_type) + _NOEXCEPT_(is_nothrow_move_assignable::value) { clear(); shrink_to_fit(); @@ -1606,7 +1607,7 @@ deque<_Tp, _Allocator>::resize(size_type __n, const value_type& __v) template void -deque<_Tp, _Allocator>::shrink_to_fit() +deque<_Tp, _Allocator>::shrink_to_fit() _NOEXCEPT { allocator_type& __a = __base::__alloc(); if (empty()) diff --git a/include/memory b/include/memory index 37700995..67f9937c 100644 --- a/include/memory +++ b/include/memory @@ -1591,6 +1591,8 @@ public: typedef const _Tp& const_reference; typedef _Tp value_type; + typedef true_type propagate_on_container_move_assignment; + template struct rebind {typedef allocator<_Up> other;}; _LIBCPP_INLINE_VISIBILITY allocator() _NOEXCEPT {}