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.

llvm-svn: 132490
This commit is contained in:
Howard Hinnant 2011-06-02 21:38:57 +00:00
parent f7600949f4
commit b58f59cdb3
2 changed files with 23 additions and 20 deletions

View File

@ -48,14 +48,18 @@ public:
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 @@ 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<allocator_type>::value);
void clear() noexcept;
};
@ -137,7 +143,7 @@ template <class T, class Allocator>
// 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 @@ 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<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 @@ 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<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 @@ 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<allocator_type>::value);
void __move_assign(deque& __c, false_type);
};
@ -1494,11 +1497,8 @@ template <class _Tp, class _Allocator>
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 @@ deque<_Tp, _Allocator>::__move_assign(deque& __c, false_type)
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 @@ deque<_Tp, _Allocator>::resize(size_type __n, const value_type& __v)
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())

View File

@ -1591,6 +1591,8 @@ public:
typedef const _Tp& const_reference;
typedef _Tp value_type;
typedef true_type propagate_on_container_move_assignment;
template <class _Up> struct rebind {typedef allocator<_Up> other;};
_LIBCPP_INLINE_VISIBILITY allocator() _NOEXCEPT {}