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<T> 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
diff --git a/include/deque b/include/deque
index 1ffd9d8..a492059 100644
--- a/include/deque
+++ b/include/deque
@@ -48,14 +48,18 @@
template <class InputIterator>
deque(InputIterator f, InputIterator l, const allocator_type& a);
deque(const deque& c);
- deque(deque&& c);
+ deque(deque&& c)
+ noexcept(is_nothrow_move_constructible<allocator_type>::value);
deque(initializer_list<value_type> 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<allocator_type>::value);
deque& operator=(initializer_list<value_type> il);
template <class InputIterator>
@@ -118,7 +122,9 @@
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<allocator_type>::value);
void clear() noexcept;
};
@@ -137,7 +143,7 @@
// specialized algorithms:
template <class T, class Allocator>
- void swap(deque<T,Allocator>& x, deque<T,Allocator>& y);
+ void swap(deque<T,Allocator>& x, deque<T,Allocator>& y) noexcept(x.swap(y));
} // std
@@ -950,9 +956,8 @@
_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<allocator_type>::value))
+ _NOEXCEPT_(__alloc_traits::propagate_on_container_move_assignment::value &&
+ is_nothrow_move_assignable<allocator_type>::value)
{
__map_ = _STD::move(__c.__map_);
__start_ = __c.__start_;
@@ -1204,11 +1209,8 @@
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<allocator_type>::value) ||
- (!__alloc_traits::propagate_on_container_move_assignment::value &&
- is_nothrow_move_assignable<value_type>::value));
+ _NOEXCEPT_(__alloc_traits::propagate_on_container_move_assignment::value &&
+ is_nothrow_move_assignable<allocator_type>::value);
#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
template <class _InputIter>
@@ -1269,7 +1271,7 @@
{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 @@
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<allocator_type>::value);
void __move_assign(deque& __c, false_type);
};
@@ -1494,11 +1497,8 @@
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<allocator_type>::value) ||
- (!__alloc_traits::propagate_on_container_move_assignment::value &&
- is_nothrow_move_assignable<value_type>::value))
+ _NOEXCEPT_(__alloc_traits::propagate_on_container_move_assignment::value &&
+ is_nothrow_move_assignable<allocator_type>::value)
{
__move_assign(__c, integral_constant<bool,
__alloc_traits::propagate_on_container_move_assignment::value>());
@@ -1521,6 +1521,7 @@
template <class _Tp, class _Allocator>
void
deque<_Tp, _Allocator>::__move_assign(deque& __c, true_type)
+ _NOEXCEPT_(is_nothrow_move_assignable<allocator_type>::value)
{
clear();
shrink_to_fit();
@@ -1606,7 +1607,7 @@
template <class _Tp, class _Allocator>
void
-deque<_Tp, _Allocator>::shrink_to_fit()
+deque<_Tp, _Allocator>::shrink_to_fit() _NOEXCEPT
{
allocator_type& __a = __base::__alloc();
if (empty())