summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--libcxx/include/__tuple12
-rw-r--r--libcxx/include/tuple57
-rw-r--r--libcxx/include/type_traits48
-rw-r--r--libcxx/include/utility34
4 files changed, 111 insertions, 40 deletions
diff --git a/libcxx/include/__tuple b/libcxx/include/__tuple
index ddd507ca44d..b5d80e149c1 100644
--- a/libcxx/include/__tuple
+++ b/libcxx/include/__tuple
@@ -78,27 +78,27 @@ template <class _Tp, size_t _Size> struct __tuple_like<array<_Tp, _Size> > : tru
template <size_t _Ip, class ..._Tp>
typename tuple_element<_Ip, tuple<_Tp...> >::type&
-get(tuple<_Tp...>&);
+get(tuple<_Tp...>&) _NOEXCEPT;
template <size_t _Ip, class ..._Tp>
const typename tuple_element<_Ip, tuple<_Tp...> >::type&
-get(const tuple<_Tp...>&);
+get(const tuple<_Tp...>&) _NOEXCEPT;
template <size_t _Ip, class ..._Tp>
typename tuple_element<_Ip, tuple<_Tp...> >::type&&
-get(tuple<_Tp...>&&);
+get(tuple<_Tp...>&&) _NOEXCEPT;
template <size_t _Ip, class _T1, class _T2>
typename tuple_element<_Ip, pair<_T1, _T2> >::type&
-get(pair<_T1, _T2>&);
+get(pair<_T1, _T2>&) _NOEXCEPT;
template <size_t _Ip, class _T1, class _T2>
const typename tuple_element<_Ip, pair<_T1, _T2> >::type&
-get(const pair<_T1, _T2>&);
+get(const pair<_T1, _T2>&) _NOEXCEPT;
template <size_t _Ip, class _T1, class _T2>
typename tuple_element<_Ip, pair<_T1, _T2> >::type&&
-get(pair<_T1, _T2>&&);
+get(pair<_T1, _T2>&&) _NOEXCEPT;
template <size_t _Ip, class _Tp, size_t _Size>
_Tp&
diff --git a/libcxx/include/tuple b/libcxx/include/tuple
index 63ce4cc32a0..49f220d0c02 100644
--- a/libcxx/include/tuple
+++ b/libcxx/include/tuple
@@ -25,7 +25,7 @@ public:
template <class... U>
explicit tuple(U&&...);
tuple(const tuple&) = default;
- tuple(tuple&&);
+ tuple(tuple&&) = default;
template <class... U>
tuple(const tuple<U...>&);
template <class... U>
@@ -56,7 +56,8 @@ public:
tuple(allocator_arg_t, const Alloc& a, pair<U1, U2>&&);
tuple& operator=(const tuple&);
- tuple& operator=(tuple&&);
+ tuple&
+ operator=(tuple&&) noexcept(AND(is_nothrow_move_assignable<T>::value ...));
template <class... U>
tuple& operator=(const tuple<U...>&);
template <class... U>
@@ -66,14 +67,14 @@ public:
template <class U1, class U2>
tuple& operator=(pair<U1, U2>&&); //iffsizeof...(T) == 2
- void swap(tuple&);
+ void swap(tuple&) noexcept(AND(swap(declval<T&>(), declval<T&>())...));
};
const unspecified ignore;
template <class... T> tuple<V...> make_tuple(T&&...);
-template <class... T> tuple<ATypes...> forward_as_tuple(T&&...);
-template <class... T> tuple<T&...> tie(T&...);
+template <class... T> tuple<ATypes...> forward_as_tuple(T&&...) noexcept;
+template <class... T> tuple<T&...> tie(T&...) noexcept;
template <class... Tuples> tuple<CTypes...> tuple_cat(Tuples&&... tpls);
// 20.4.1.4, tuple helper classes:
@@ -83,9 +84,15 @@ template <intsize_t I, class T> class tuple_element; // undefined
template <intsize_t I, class... T> class tuple_element<I, tuple<T...>>;
// 20.4.1.5, element access:
-template <intsize_t I, class... T> typename tuple_element<I, tuple<T...>>::type& get(tuple<T...>&);
-template <intsize_t I, class... T> typename tuple_element<I, tuple<T...>>::type const& get(const tuple<T...>&);
-template <intsize_t I, class... T> typename tuple_element<I, tuple<T...>>::type&& get(tuple<T...>&&);
+template <intsize_t I, class... T>
+ typename tuple_element<I, tuple<T...>>::type&
+ get(tuple<T...>&) noexcept;
+template <intsize_t I, class... T>
+ typename tuple_element<I, tuple<T...>>::type const&
+ get(const tuple<T...>&) noexcept;
+template <intsize_t I, class... T>
+ typename tuple_element<I, tuple<T...>>::type&&
+ get(tuple<T...>&&) noexcept;
// 20.4.1.6, relational operators:
template<class... T, class... U> bool operator==(const tuple<T...>&, const tuple<U...>&);
@@ -99,7 +106,8 @@ template <class... Types, class Alloc>
struct uses_allocator<tuple<Types...>, Alloc>;
template <class... Types>
- void swap(tuple<Types...>& x, tuple<Types...>& y);
+ void
+ swap(tuple<Types...>& x, tuple<Types...>& y) noexcept(noexcept(x.swap(y)));
} // std
@@ -142,6 +150,7 @@ class __tuple_leaf;
template <size_t _Ip, class _Hp, bool _Ep>
inline _LIBCPP_INLINE_VISIBILITY
void swap(__tuple_leaf<_Ip, _Hp, _Ep>& __x, __tuple_leaf<_Ip, _Hp, _Ep>& __y)
+ _NOEXCEPT_(__is_nothrow_swappable<_Hp>::value)
{
swap(__x.get(), __y.get());
}
@@ -256,7 +265,7 @@ public:
}
_LIBCPP_INLINE_VISIBILITY
- int swap(__tuple_leaf& __t)
+ int swap(__tuple_leaf& __t) _NOEXCEPT_(__is_nothrow_swappable<__tuple_leaf>::value)
{
_STD::swap(*this, __t);
return 0;
@@ -324,7 +333,9 @@ public:
return *this;
}
- _LIBCPP_INLINE_VISIBILITY int swap(__tuple_leaf& __t)
+ _LIBCPP_INLINE_VISIBILITY
+ int
+ swap(__tuple_leaf& __t) _NOEXCEPT_(__is_nothrow_swappable<__tuple_leaf>::value)
{
_STD::swap(*this, __t);
return 0;
@@ -338,6 +349,20 @@ template <class ..._Tp>
_LIBCPP_INLINE_VISIBILITY
void __swallow(_Tp&&...) {}
+template <bool ...> struct __all;
+
+template <>
+struct __all<>
+{
+ static const bool value = true;
+};
+
+template <bool _B0, bool ... _B>
+struct __all<_B0, _B...>
+{
+ static const bool value = _B0 && __all<_B...>::value;
+};
+
// __tuple_impl
template<class _Indx, class ..._Tp> struct __tuple_impl;
@@ -412,6 +437,7 @@ struct __tuple_impl<__tuple_indices<_Indx...>, _Tp...>
_LIBCPP_INLINE_VISIBILITY
void swap(__tuple_impl& __t)
+ _NOEXCEPT_(__all<__is_nothrow_swappable<_Tp>::value...>::value)
{
__swallow(__tuple_leaf<_Indx, _Tp>::swap(static_cast<__tuple_leaf<_Indx, _Tp>&>(__t))...);
}
@@ -533,7 +559,8 @@ public:
}
_LIBCPP_INLINE_VISIBILITY
- void swap(tuple& __t) {base_.swap(__t.base_);}
+ void swap(tuple& __t) _NOEXCEPT_(__all<__is_nothrow_swappable<_Tp>::value...>::value)
+ {base_.swap(__t.base_);}
};
template <>
@@ -555,13 +582,15 @@ public:
_LIBCPP_INLINE_VISIBILITY
tuple(allocator_arg_t, const _Alloc&, array<_U, 0>) {}
_LIBCPP_INLINE_VISIBILITY
- void swap(tuple&) {}
+ void swap(tuple&) _NOEXCEPT {}
};
template <class ..._Tp>
inline _LIBCPP_INLINE_VISIBILITY
void
-swap(tuple<_Tp...>& __t, tuple<_Tp...>& __u) {__t.swap(__u);}
+swap(tuple<_Tp...>& __t, tuple<_Tp...>& __u)
+ _NOEXCEPT_(__all<__is_nothrow_swappable<_Tp>::value...>::value)
+ {__t.swap(__u);}
// get
diff --git a/libcxx/include/type_traits b/libcxx/include/type_traits
index 09f03d7e4ee..40adc273ba4 100644
--- a/libcxx/include/type_traits
+++ b/libcxx/include/type_traits
@@ -3019,6 +3019,54 @@ iter_swap(_ForwardIterator1 __a, _ForwardIterator2 __b)
swap(*__a, *__b);
}
+// __swappable
+
+__nat swap(__any, __any);
+
+template <class _Tp>
+struct __swappable
+{
+ typedef decltype(swap(_STD::declval<_Tp&>(), _STD::declval<_Tp&>())) type;
+ static const bool value = !is_same<type, __nat>::value;
+};
+
+template <class _Tp>
+struct __is_swappable
+ : public integral_constant<bool, __swappable<_Tp>::value>
+{
+};
+
+#if __has_feature(cxx_noexcept)
+
+template <bool, class _Tp>
+struct __is_nothrow_swappable_imp
+ : public integral_constant<bool, noexcept(swap(_STD::declval<_Tp&>(),
+ _STD::declval<_Tp&>()))>
+{
+};
+
+template <class _Tp>
+struct __is_nothrow_swappable_imp<false, _Tp>
+ : public false_type
+{
+};
+
+template <class _Tp>
+struct __is_nothrow_swappable
+ : public __is_nothrow_swappable_imp<__is_swappable<_Tp>::value, _Tp>
+{
+};
+
+#else // __has_feature(cxx_noexcept)
+
+template <class _Tp>
+struct __is_nothrow_swappable
+ : public false_type
+{
+};
+
+#endif // __has_feature(cxx_noexcept)
+
_LIBCPP_END_NAMESPACE_STD
#endif // _LIBCPP_TYPE_TRAITS
diff --git a/libcxx/include/utility b/libcxx/include/utility
index 1d1b579897e..d0ad1ec86e0 100644
--- a/libcxx/include/utility
+++ b/libcxx/include/utility
@@ -181,8 +181,7 @@ swap_ranges(_ForwardIterator1 __first1, _ForwardIterator1 __last1, _ForwardItera
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&>())))
+swap(_Tp (&__a)[_N], _Tp (&__b)[_N]) _NOEXCEPT_(__is_nothrow_swappable<_Tp>::value)
{
_STD::swap_ranges(__a, __a + _N, __b);
}
@@ -311,13 +310,8 @@ struct _LIBCPP_VISIBLE pair
#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
_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&>())))
+ swap(pair& __p) _NOEXCEPT_(__is_nothrow_swappable<first_type>::value &&
+ __is_nothrow_swappable<second_type>::value)
{
_STD::iter_swap(&first, &__p.first);
_STD::iter_swap(&second, &__p.second);
@@ -385,8 +379,8 @@ 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>&>()))))
+ _NOEXCEPT_((__is_nothrow_swappable<_T1>::value &&
+ __is_nothrow_swappable<_T2>::value))
{
__x.swap(__y);
}
@@ -481,13 +475,13 @@ struct __get_pair<0>
static
_LIBCPP_INLINE_VISIBILITY
_T1&
- get(pair<_T1, _T2>& __p) {return __p.first;}
+ get(pair<_T1, _T2>& __p) _NOEXCEPT {return __p.first;}
template <class _T1, class _T2>
static
_LIBCPP_INLINE_VISIBILITY
const _T1&
- get(const pair<_T1, _T2>& __p) {return __p.first;}
+ get(const pair<_T1, _T2>& __p) _NOEXCEPT {return __p.first;}
#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
@@ -495,7 +489,7 @@ struct __get_pair<0>
static
_LIBCPP_INLINE_VISIBILITY
_T1&&
- get(pair<_T1, _T2>&& __p) {return _STD::forward<_T1>(__p.first);}
+ get(pair<_T1, _T2>&& __p) _NOEXCEPT {return _STD::forward<_T1>(__p.first);}
#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
};
@@ -507,13 +501,13 @@ struct __get_pair<1>
static
_LIBCPP_INLINE_VISIBILITY
_T2&
- get(pair<_T1, _T2>& __p) {return __p.second;}
+ get(pair<_T1, _T2>& __p) _NOEXCEPT {return __p.second;}
template <class _T1, class _T2>
static
_LIBCPP_INLINE_VISIBILITY
const _T2&
- get(const pair<_T1, _T2>& __p) {return __p.second;}
+ get(const pair<_T1, _T2>& __p) _NOEXCEPT {return __p.second;}
#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
@@ -521,7 +515,7 @@ struct __get_pair<1>
static
_LIBCPP_INLINE_VISIBILITY
_T2&&
- get(pair<_T1, _T2>&& __p) {return _STD::forward<_T2>(__p.second);}
+ get(pair<_T1, _T2>&& __p) _NOEXCEPT {return _STD::forward<_T2>(__p.second);}
#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
};
@@ -529,7 +523,7 @@ struct __get_pair<1>
template <size_t _Ip, class _T1, class _T2>
_LIBCPP_INLINE_VISIBILITY inline
typename tuple_element<_Ip, pair<_T1, _T2> >::type&
-get(pair<_T1, _T2>& __p)
+get(pair<_T1, _T2>& __p) _NOEXCEPT
{
return __get_pair<_Ip>::get(__p);
}
@@ -537,7 +531,7 @@ get(pair<_T1, _T2>& __p)
template <size_t _Ip, class _T1, class _T2>
_LIBCPP_INLINE_VISIBILITY inline
const typename tuple_element<_Ip, pair<_T1, _T2> >::type&
-get(const pair<_T1, _T2>& __p)
+get(const pair<_T1, _T2>& __p) _NOEXCEPT
{
return __get_pair<_Ip>::get(__p);
}
@@ -547,7 +541,7 @@ get(const pair<_T1, _T2>& __p)
template <size_t _Ip, class _T1, class _T2>
_LIBCPP_INLINE_VISIBILITY inline
typename tuple_element<_Ip, pair<_T1, _T2> >::type&&
-get(pair<_T1, _T2>&& __p)
+get(pair<_T1, _T2>&& __p) _NOEXCEPT
{
return __get_pair<_Ip>::get(_STD::move(__p));
}
OpenPOWER on IntegriCloud