diff options
-rw-r--r-- | libcxx/include/algorithm | 8 | ||||
-rw-r--r-- | libcxx/include/type_traits | 20 | ||||
-rw-r--r-- | libcxx/include/utility | 81 |
3 files changed, 80 insertions, 29 deletions
diff --git a/libcxx/include/algorithm b/libcxx/include/algorithm index 4909221bb09..4789b0bb2a1 100644 --- a/libcxx/include/algorithm +++ b/libcxx/include/algorithm @@ -1659,13 +1659,7 @@ move_backward(_BidirectionalIterator1 __first, _BidirectionalIterator1 __last, // iter_swap -template <class _ForwardIterator1, class _ForwardIterator2> -inline _LIBCPP_INLINE_VISIBILITY -void -iter_swap(_ForwardIterator1 __a, _ForwardIterator2 __b) -{ - swap(*__a, *__b); -} +// moved to <type_traits> for better swap / noexcept support // transform diff --git a/libcxx/include/type_traits b/libcxx/include/type_traits index dd6a325db1b..09f03d7e4ee 100644 --- a/libcxx/include/type_traits +++ b/libcxx/include/type_traits @@ -1296,7 +1296,7 @@ struct is_destructible template <class _Tp> 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 <class _Tp> 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 <class _Tp> 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 <class _Tp> 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 <class _ForwardIterator1, class _ForwardIterator2> +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/libcxx/include/utility b/libcxx/include/utility index afb9e739e33..1d1b579897e 100644 --- a/libcxx/include/utility +++ b/libcxx/include/utility @@ -29,11 +29,19 @@ namespace rel_ops template<class T> bool operator>=(const T&, const T&); } -template<class T> void swap(T& a, T& b); -template <class T, size_t N> void swap(T (&a)[N], T (&b)[N]); +template<class T> +void +swap(T& a, T& b) noexcept(is_nothrow_move_constructible<T>::value && + is_nothrow_move_assignable<T>::value); + +template <class T, size_t N> +void +swap(T (&a)[N], T (&b)[N]) noexcept(noexcept(swap(*a, *b))); + +template <class T> T&& forward(typename remove_reference<T>::type& t) noexcept; +template <class T> T&& forward(typename remove_reference<T>::type&& t) noexcept; -template <class T, class U> T&& forward(U&&); -template <class T> typename remove_reference<T>::type&& move(T&&); +template <class T> typename remove_reference<T>::type&& move(T&&) noexcept; template <class T> typename conditional @@ -42,7 +50,7 @@ template <class T> const T&, T&& >::type - move_if_noexcept(T& x); + move_if_noexcept(T& x) noexcept; template <class T> typename add_rvalue_reference<T>::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 <class U, class V> pair(U&& x, V&& y); @@ -66,10 +75,12 @@ struct pair tuple<Args2...> second_args); template <class U, class V> pair& operator=(const pair<U, V>& p); - pair& operator=(pair&& p); + pair& operator=(pair&& p) noexcept(is_nothrow_move_assignable<T1>::value && + is_nothrow_move_assignable<T2>::value); template <class U, class V> pair& operator=(pair<U, V>&& p); - void swap(pair& p); + void swap(pair& p) noexcept(noexcept(swap(first, p.first)) && + noexcept(swap(second, p.second))); }; template <class T1, class T2> bool operator==(const pair<T1,T2>&, const pair<T1,T2>&); @@ -80,7 +91,9 @@ template <class T1, class T2> bool operator>=(const pair<T1,T2>&, const pair<T1, template <class T1, class T2> bool operator<=(const pair<T1,T2>&, const pair<T1,T2>&); template <class T1, class T2> pair<V1, V2> make_pair(T1&&, T2&&); -template <class T1, class T2> void swap(pair<T1, T2>& x, pair<T1, T2>& y); +template <class T1, class T2> +void +swap(pair<T1, T2>& x, pair<T1, T2>& y) noexcept(noexcept(x.swap(y))); struct piecewise_construct_t { }; constexpr piecewise_construct_t piecewise_construct = piecewise_construct_t(); @@ -94,15 +107,15 @@ template <class T1, class T2> struct tuple_element<1, std::pair<T1, T2> >; template<size_t I, class T1, class T2> typename tuple_element<I, std::pair<T1, T2> >::type& - get(std::pair<T1, T2>&); + get(std::pair<T1, T2>&) noexcept; template<size_t I, class T1, class T2> const typename const tuple_element<I, std::pair<T1, T2> >::type& - get(const std::pair<T1, T2>&); + get(const std::pair<T1, T2>&) noexcept; template<size_t I, class T1, class T2> typename tuple_element<I, std::pair<T1, T2> >::type&& - get(std::pair<T1, T2>&&); + get(std::pair<T1, T2>&&) noexcept; } // std @@ -169,6 +182,7 @@ template<class _Tp, size_t _N> 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 <class _T1, class _T2> struct pair; -template <class _T1, class _T2> void swap(pair<_T1, _T2>&, pair<_T1, _T2>&); - template <class _T1, class _T2> 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 <class _U1, class _U2, @@ -237,6 +259,16 @@ struct _LIBCPP_VISIBLE pair : first(_STD::forward<_U1>(__p.first)), second(_STD::forward<_U2>(__p.second)) {} + _LIBCPP_INLINE_VISIBILITY + pair& + operator=(pair&& __p) _NOEXCEPT_(is_nothrow_move_assignable<first_type>::value && + is_nothrow_move_assignable<second_type>::value) + { + first = _STD::forward<first_type>(__p.first); + second = _STD::forward<second_type>(__p.second); + return *this; + } + #ifndef _LIBCPP_HAS_NO_VARIADICS template<class _Tuple, @@ -277,7 +309,19 @@ struct _LIBCPP_VISIBLE pair #endif // _LIBCPP_HAS_NO_VARIADICS #endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES - void _LIBCPP_INLINE_VISIBILITY swap(pair& __p) {_STD::swap(*this, __p);} + _LIBCPP_INLINE_VISIBILITY + void + swap(pair& __p) _NOEXCEPT_( +// _NOEXCEPT_(_STD::iter_swap(&first, &__p.first)) && +// _NOEXCEPT_(_STD::iter_swap(&second, &__p.second))) + _NOEXCEPT_(_STD::iter_swap(&_STD::declval<first_type&>(), + &_STD::declval<first_type&>())) && + _NOEXCEPT_(_STD::iter_swap(&_STD::declval<second_type&>(), + &_STD::declval<second_type&>()))) + { + _STD::iter_swap(&first, &__p.first); + _STD::iter_swap(&second, &__p.second); + } private: #ifndef _LIBCPP_HAS_NO_VARIADICS @@ -341,9 +385,10 @@ template <class _T1, class _T2> inline _LIBCPP_INLINE_VISIBILITY void swap(pair<_T1, _T2>& __x, pair<_T1, _T2>& __y) +// _NOEXCEPT_(_NOEXCEPT_(__x.swap(__y))) + _NOEXCEPT_(_NOEXCEPT_((_STD::declval<pair<_T1, _T2>&>().swap(_STD::declval<pair<_T1, _T2>&>())))) { - swap(__x.first, __y.first); - swap(__x.second, __y.second); + __x.swap(__y); } #ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES |