diff --git a/include/algorithm b/include/algorithm index 4909221bb..4789b0bb2 100644 --- a/include/algorithm +++ b/include/algorithm @@ -1659,13 +1659,7 @@ move_backward(_BidirectionalIterator1 __first, _BidirectionalIterator1 __last, // iter_swap -template -inline _LIBCPP_INLINE_VISIBILITY -void -iter_swap(_ForwardIterator1 __a, _ForwardIterator2 __b) -{ - swap(*__a, *__b); -} +// moved to for better swap / noexcept support // transform diff --git a/include/type_traits b/include/type_traits index dd6a325db..09f03d7e4 100644 --- a/include/type_traits +++ b/include/type_traits @@ -1296,7 +1296,7 @@ struct is_destructible template inline _LIBCPP_INLINE_VISIBILITY typename remove_reference<_Tp>::type&& -move(_Tp&& __t) +move(_Tp&& __t) _NOEXCEPT { typedef typename remove_reference<_Tp>::type _Up; return static_cast<_Up&&>(__t); @@ -1305,7 +1305,7 @@ move(_Tp&& __t) template inline _LIBCPP_INLINE_VISIBILITY _Tp&& -forward(typename std::remove_reference<_Tp>::type& __t) +forward(typename std::remove_reference<_Tp>::type& __t) _NOEXCEPT { return static_cast<_Tp&&>(__t); } @@ -1313,7 +1313,7 @@ forward(typename std::remove_reference<_Tp>::type& __t) template inline _LIBCPP_INLINE_VISIBILITY _Tp&& -forward(typename std::remove_reference<_Tp>::type&& __t) +forward(typename std::remove_reference<_Tp>::type&& __t) _NOEXCEPT { static_assert(!std::is_lvalue_reference<_Tp>::value, "Can not forward an rvalue as an lvalue."); @@ -3000,13 +3000,25 @@ struct __invoke_of template inline _LIBCPP_INLINE_VISIBILITY void -swap(_Tp& __x, _Tp& __y) +swap(_Tp& __x, _Tp& __y) _NOEXCEPT_(is_nothrow_move_constructible<_Tp>::value && + is_nothrow_move_assignable<_Tp>::value) { _Tp __t(_STD::move(__x)); __x = _STD::move(__y); __y = _STD::move(__t); } +template +inline _LIBCPP_INLINE_VISIBILITY +void +iter_swap(_ForwardIterator1 __a, _ForwardIterator2 __b) + // _NOEXCEPT_(_NOEXCEPT_(swap(*__a, *__b))) + _NOEXCEPT_(_NOEXCEPT_(swap(*_STD::declval<_ForwardIterator1>(), + *_STD::declval<_ForwardIterator2>()))) +{ + swap(*__a, *__b); +} + _LIBCPP_END_NAMESPACE_STD #endif // _LIBCPP_TYPE_TRAITS diff --git a/include/utility b/include/utility index afb9e739e..1d1b57989 100644 --- a/include/utility +++ b/include/utility @@ -29,11 +29,19 @@ namespace rel_ops template bool operator>=(const T&, const T&); } -template void swap(T& a, T& b); -template void swap(T (&a)[N], T (&b)[N]); +template +void +swap(T& a, T& b) noexcept(is_nothrow_move_constructible::value && + is_nothrow_move_assignable::value); -template T&& forward(U&&); -template typename remove_reference::type&& move(T&&); +template +void +swap(T (&a)[N], T (&b)[N]) noexcept(noexcept(swap(*a, *b))); + +template T&& forward(typename remove_reference::type& t) noexcept; +template T&& forward(typename remove_reference::type&& t) noexcept; + +template typename remove_reference::type&& move(T&&) noexcept; template typename conditional @@ -42,7 +50,7 @@ template const T&, T&& >::type - move_if_noexcept(T& x); + move_if_noexcept(T& x) noexcept; template typename add_rvalue_reference::type declval() noexcept; @@ -56,6 +64,7 @@ struct pair T2 second; pair(const pair&) = default; + pair(pair&&) = default; constexpr pair(); pair(const T1& x, const T2& y); template pair(U&& x, V&& y); @@ -66,10 +75,12 @@ struct pair tuple second_args); template pair& operator=(const pair& p); - pair& operator=(pair&& p); + pair& operator=(pair&& p) noexcept(is_nothrow_move_assignable::value && + is_nothrow_move_assignable::value); template pair& operator=(pair&& p); - void swap(pair& p); + void swap(pair& p) noexcept(noexcept(swap(first, p.first)) && + noexcept(swap(second, p.second))); }; template bool operator==(const pair&, const pair&); @@ -80,7 +91,9 @@ template bool operator>=(const pair&, const pair bool operator<=(const pair&, const pair&); template pair make_pair(T1&&, T2&&); -template void swap(pair& x, pair& y); +template +void +swap(pair& x, pair& y) noexcept(noexcept(x.swap(y))); struct piecewise_construct_t { }; constexpr piecewise_construct_t piecewise_construct = piecewise_construct_t(); @@ -94,15 +107,15 @@ template struct tuple_element<1, std::pair >; template typename tuple_element >::type& - get(std::pair&); + get(std::pair&) noexcept; template const typename const tuple_element >::type& - get(const std::pair&); + get(const std::pair&) noexcept; template typename tuple_element >::type&& - get(std::pair&&); + get(std::pair&&) noexcept; } // std @@ -169,6 +182,7 @@ template inline _LIBCPP_INLINE_VISIBILITY void swap(_Tp (&__a)[_N], _Tp (&__b)[_N]) + _NOEXCEPT_(_NOEXCEPT_(swap(_STD::declval<_Tp&>(), _STD::declval<_Tp&>()))) { _STD::swap_ranges(__a, __a + _N, __b); } @@ -185,7 +199,7 @@ typename conditional #else // _LIBCPP_HAS_NO_RVALUE_REFERENCES const _Tp& #endif -move_if_noexcept(_Tp& __x) +move_if_noexcept(_Tp& __x) _NOEXCEPT { return _STD::move(__x); } @@ -194,9 +208,6 @@ struct _LIBCPP_VISIBLE piecewise_construct_t { }; //constexpr extern const piecewise_construct_t piecewise_construct;// = piecewise_construct_t(); -template struct pair; -template void swap(pair<_T1, _T2>&, pair<_T1, _T2>&); - template struct _LIBCPP_VISIBLE pair { @@ -206,6 +217,9 @@ struct _LIBCPP_VISIBLE pair _T1 first; _T2 second; + // pair(const pair&) = default; + // pair(pair&&) = default; + _LIBCPP_INLINE_VISIBILITY pair() : first(), second() {} _LIBCPP_INLINE_VISIBILITY pair(const _T1& __x, const _T2& __y) @@ -218,6 +232,14 @@ struct _LIBCPP_VISIBLE pair is_convertible<_U2, _T2>::value>::type* = 0) : first(__p.first), second(__p.second) {} + _LIBCPP_INLINE_VISIBILITY + pair& operator=(const pair& __p) + { + first = __p.first; + second = __p.second; + return *this; + } + #ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES template (__p.first)), second(_STD::forward<_U2>(__p.second)) {} + _LIBCPP_INLINE_VISIBILITY + pair& + operator=(pair&& __p) _NOEXCEPT_(is_nothrow_move_assignable::value && + is_nothrow_move_assignable::value) + { + first = _STD::forward(__p.first); + second = _STD::forward(__p.second); + return *this; + } + #ifndef _LIBCPP_HAS_NO_VARIADICS template(), + &_STD::declval())) && + _NOEXCEPT_(_STD::iter_swap(&_STD::declval(), + &_STD::declval()))) + { + _STD::iter_swap(&first, &__p.first); + _STD::iter_swap(&second, &__p.second); + } private: #ifndef _LIBCPP_HAS_NO_VARIADICS @@ -341,9 +385,10 @@ template inline _LIBCPP_INLINE_VISIBILITY void swap(pair<_T1, _T2>& __x, pair<_T1, _T2>& __y) +// _NOEXCEPT_(_NOEXCEPT_(__x.swap(__y))) + _NOEXCEPT_(_NOEXCEPT_((_STD::declval&>().swap(_STD::declval&>())))) { - swap(__x.first, __y.first); - swap(__x.second, __y.second); + __x.swap(__y); } #ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES