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
This commit is contained in:
parent
0a612b0891
commit
18884f4e9f
@ -48,14 +48,18 @@ public:
|
|||||||
template <class InputIterator>
|
template <class InputIterator>
|
||||||
deque(InputIterator f, InputIterator l, const allocator_type& a);
|
deque(InputIterator f, InputIterator l, const allocator_type& a);
|
||||||
deque(const deque& c);
|
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(initializer_list<value_type> il, const Allocator& a = allocator_type());
|
||||||
deque(const deque& c, const allocator_type& a);
|
deque(const deque& c, const allocator_type& a);
|
||||||
deque(deque&& c, const allocator_type& a);
|
deque(deque&& c, const allocator_type& a);
|
||||||
~deque();
|
~deque();
|
||||||
|
|
||||||
deque& operator=(const deque& c);
|
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);
|
deque& operator=(initializer_list<value_type> il);
|
||||||
|
|
||||||
template <class InputIterator>
|
template <class InputIterator>
|
||||||
@ -118,7 +122,9 @@ public:
|
|||||||
void pop_back();
|
void pop_back();
|
||||||
iterator erase(const_iterator p);
|
iterator erase(const_iterator p);
|
||||||
iterator erase(const_iterator f, const_iterator l);
|
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;
|
void clear() noexcept;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -137,7 +143,7 @@ template <class T, class Allocator>
|
|||||||
|
|
||||||
// specialized algorithms:
|
// specialized algorithms:
|
||||||
template <class T, class Allocator>
|
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
|
} // std
|
||||||
|
|
||||||
@ -950,9 +956,8 @@ protected:
|
|||||||
|
|
||||||
_LIBCPP_INLINE_VISIBILITY
|
_LIBCPP_INLINE_VISIBILITY
|
||||||
void __move_assign(__deque_base& __c)
|
void __move_assign(__deque_base& __c)
|
||||||
_NOEXCEPT_(is_nothrow_move_assignable<__map>::value &&
|
_NOEXCEPT_(__alloc_traits::propagate_on_container_move_assignment::value &&
|
||||||
(!__alloc_traits::propagate_on_container_move_assignment::value ||
|
is_nothrow_move_assignable<allocator_type>::value)
|
||||||
is_nothrow_move_assignable<allocator_type>::value))
|
|
||||||
{
|
{
|
||||||
__map_ = _STD::move(__c.__map_);
|
__map_ = _STD::move(__c.__map_);
|
||||||
__start_ = __c.__start_;
|
__start_ = __c.__start_;
|
||||||
@ -1204,11 +1209,8 @@ public:
|
|||||||
deque(deque&& __c) _NOEXCEPT_(is_nothrow_move_constructible<__base>::value);
|
deque(deque&& __c) _NOEXCEPT_(is_nothrow_move_constructible<__base>::value);
|
||||||
deque(deque&& __c, const allocator_type& __a);
|
deque(deque&& __c, const allocator_type& __a);
|
||||||
deque& operator=(deque&& __c)
|
deque& operator=(deque&& __c)
|
||||||
_NOEXCEPT_(
|
_NOEXCEPT_(__alloc_traits::propagate_on_container_move_assignment::value &&
|
||||||
(__alloc_traits::propagate_on_container_move_assignment::value &&
|
is_nothrow_move_assignable<allocator_type>::value);
|
||||||
is_nothrow_move_assignable<allocator_type>::value) ||
|
|
||||||
(!__alloc_traits::propagate_on_container_move_assignment::value &&
|
|
||||||
is_nothrow_move_assignable<value_type>::value));
|
|
||||||
#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
|
#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
|
||||||
|
|
||||||
template <class _InputIter>
|
template <class _InputIter>
|
||||||
@ -1269,7 +1271,7 @@ public:
|
|||||||
{return __alloc_traits::max_size(__base::__alloc());}
|
{return __alloc_traits::max_size(__base::__alloc());}
|
||||||
void resize(size_type __n);
|
void resize(size_type __n);
|
||||||
void resize(size_type __n, const value_type& __v);
|
void resize(size_type __n, const value_type& __v);
|
||||||
void shrink_to_fit();
|
void shrink_to_fit() _NOEXCEPT;
|
||||||
_LIBCPP_INLINE_VISIBILITY
|
_LIBCPP_INLINE_VISIBILITY
|
||||||
bool empty() const _NOEXCEPT {return __base::size() == 0;}
|
bool empty() const _NOEXCEPT {return __base::size() == 0;}
|
||||||
|
|
||||||
@ -1386,7 +1388,8 @@ private:
|
|||||||
void __copy_assign_alloc(const deque& __c, false_type)
|
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);
|
void __move_assign(deque& __c, false_type);
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -1494,11 +1497,8 @@ template <class _Tp, class _Allocator>
|
|||||||
inline _LIBCPP_INLINE_VISIBILITY
|
inline _LIBCPP_INLINE_VISIBILITY
|
||||||
deque<_Tp, _Allocator>&
|
deque<_Tp, _Allocator>&
|
||||||
deque<_Tp, _Allocator>::operator=(deque&& __c)
|
deque<_Tp, _Allocator>::operator=(deque&& __c)
|
||||||
_NOEXCEPT_(
|
_NOEXCEPT_(__alloc_traits::propagate_on_container_move_assignment::value &&
|
||||||
(__alloc_traits::propagate_on_container_move_assignment::value &&
|
is_nothrow_move_assignable<allocator_type>::value)
|
||||||
is_nothrow_move_assignable<allocator_type>::value) ||
|
|
||||||
(!__alloc_traits::propagate_on_container_move_assignment::value &&
|
|
||||||
is_nothrow_move_assignable<value_type>::value))
|
|
||||||
{
|
{
|
||||||
__move_assign(__c, integral_constant<bool,
|
__move_assign(__c, integral_constant<bool,
|
||||||
__alloc_traits::propagate_on_container_move_assignment::value>());
|
__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>
|
template <class _Tp, class _Allocator>
|
||||||
void
|
void
|
||||||
deque<_Tp, _Allocator>::__move_assign(deque& __c, true_type)
|
deque<_Tp, _Allocator>::__move_assign(deque& __c, true_type)
|
||||||
|
_NOEXCEPT_(is_nothrow_move_assignable<allocator_type>::value)
|
||||||
{
|
{
|
||||||
clear();
|
clear();
|
||||||
shrink_to_fit();
|
shrink_to_fit();
|
||||||
@ -1606,7 +1607,7 @@ deque<_Tp, _Allocator>::resize(size_type __n, const value_type& __v)
|
|||||||
|
|
||||||
template <class _Tp, class _Allocator>
|
template <class _Tp, class _Allocator>
|
||||||
void
|
void
|
||||||
deque<_Tp, _Allocator>::shrink_to_fit()
|
deque<_Tp, _Allocator>::shrink_to_fit() _NOEXCEPT
|
||||||
{
|
{
|
||||||
allocator_type& __a = __base::__alloc();
|
allocator_type& __a = __base::__alloc();
|
||||||
if (empty())
|
if (empty())
|
||||||
|
@ -1591,6 +1591,8 @@ public:
|
|||||||
typedef const _Tp& const_reference;
|
typedef const _Tp& const_reference;
|
||||||
typedef _Tp value_type;
|
typedef _Tp value_type;
|
||||||
|
|
||||||
|
typedef true_type propagate_on_container_move_assignment;
|
||||||
|
|
||||||
template <class _Up> struct rebind {typedef allocator<_Up> other;};
|
template <class _Up> struct rebind {typedef allocator<_Up> other;};
|
||||||
|
|
||||||
_LIBCPP_INLINE_VISIBILITY allocator() _NOEXCEPT {}
|
_LIBCPP_INLINE_VISIBILITY allocator() _NOEXCEPT {}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user