EricWF updated this revision to Diff 60636.
EricWF added a comment.
Get all but 1 test passing.
http://reviews.llvm.org/D21314
Files:
include/tuple
include/utility
test/test.pass.cpp
Index: test/test.pass.cpp
===================================================================
--- /dev/null
+++ test/test.pass.cpp
@@ -0,0 +1,68 @@
+#include <utility>
+#include <tuple>
+#include <type_traits>
+#include <memory>
+
+#include "test_macros.h"
+
+struct NonAssignable {
+private:
+ NonAssignable& operator=(NonAssignable const&) _LIBCPP_EQUAL_DELETE;
+#if TEST_STD_VER >= 11
+ NonAssignable& operator=(NonAssignable&&) _LIBCPP_EQUAL_DELETE;
+#endif
+};
+
+int main() {
+ typedef std::unique_ptr<int> Ptr;
+ typedef NonAssignable NA;
+ {
+ typedef std::pair<int, int> T;
+ const T x(1, 2);
+ T y;
+ y = x;
+ static_assert(std::is_copy_assignable<T>::value, "");
+ static_assert(std::is_move_assignable<T>::value, "");
+ }
+#if TEST_STD_VER >= 11
+ {
+ using T = std::pair<int, Ptr>;
+ static_assert(!std::is_copy_assignable<T>::value, "");
+ static_assert(std::is_move_assignable<T>::value, "");
+ }
+ {
+ using T = std::pair<int, Ptr&>;
+ static_assert(!std::is_copy_assignable<T>::value, "");
+ static_assert(std::is_move_assignable<T>::value, "");
+ }
+ {
+ using T = std::pair<int, Ptr&&>;
+ static_assert(!std::is_copy_assignable<T>::value, "");
+ static_assert(std::is_move_assignable<T>::value, "");
+ }
+ {
+ using T = std::pair<int, Ptr const&>;
+ static_assert(!std::is_copy_assignable<T>::value, "");
+ static_assert(!std::is_move_assignable<T>::value, "");
+ }
+ {
+ using T = std::pair<int&, int&&>;
+ static_assert(std::is_copy_assignable<T>::value, "");
+ static_assert(std::is_move_assignable<T>::value, "");
+ }
+ {
+ using T = std::tuple<int, Ptr>;
+ static_assert(!std::is_copy_assignable<T>::value, "");
+ }
+ {
+ using T = std::pair<int, NA>;
+ static_assert(!std::is_copy_assignable<T>::value, "");
+ static_assert(!std::is_move_assignable<T>::value, "");
+ }
+ {
+ using T = std::tuple<int, NA>;
+ static_assert(!std::is_copy_assignable<T>::value, "");
+ static_assert(!std::is_move_assignable<T>::value, "");
+ }
+#endif
+}
\ No newline at end of file
Index: include/utility
===================================================================
--- include/utility
+++ include/utility
@@ -276,6 +276,7 @@
constexpr piecewise_construct_t piecewise_construct = piecewise_construct_t();
#endif
+
template <class _T1, class _T2>
struct _LIBCPP_TYPE_VIS_ONLY pair
{
@@ -310,10 +311,7 @@
)
: first(__p.first), second(__p.second) {}
-#if !defined(_LIBCPP_HAS_NO_DEFAULTED_FUNCTIONS) && _LIBCPP_TRIVIAL_PAIR_COPY_CTOR
- _LIBCPP_INLINE_VISIBILITY
- pair(const pair& __p) = default;
-#elif !defined(_LIBCPP_HAS_NO_RVALUE_REFERENCES) || !_LIBCPP_TRIVIAL_PAIR_COPY_CTOR
+#if defined(_LIBCPP_HAS_NO_RVALUE_REFERENCES) || !_LIBCPP_TRIVIAL_PAIR_COPY_CTOR
_LIBCPP_INLINE_VISIBILITY
pair(const pair& __p)
_NOEXCEPT_(is_nothrow_copy_constructible<first_type>::value &&
@@ -323,11 +321,20 @@
{
}
#endif
+ typedef typename remove_reference<_T1>::type _T1Unref;
+ typedef typename remove_reference<_T2>::type _T2Unref;
+
+ typedef integral_constant<bool,
+ (is_reference<_T1>::value || is_reference<_T2>::value)
+ && is_copy_assignable<_T1Unref>::value
+ && is_copy_assignable<_T2Unref>::value> _CanCopyAssign;
+
_LIBCPP_INLINE_VISIBILITY
- pair& operator=(const pair& __p)
- _NOEXCEPT_(is_nothrow_copy_assignable<first_type>::value &&
- is_nothrow_copy_assignable<second_type>::value)
+ pair&
+ operator=(typename conditional<_CanCopyAssign::value == true, pair const&, __nat&>::type __p)
+ _NOEXCEPT_(is_nothrow_copy_assignable<_T1Unref>::value &&
+ is_nothrow_copy_assignable<_T2Unref>::value)
{
first = __p.first;
second = __p.second;
@@ -353,23 +360,25 @@
: first(_VSTD::forward<_U1>(__p.first)),
second(_VSTD::forward<_U2>(__p.second)) {}
-#ifndef _LIBCPP_HAS_NO_DEFAULTED_FUNCTIONS
- _LIBCPP_INLINE_VISIBILITY
- pair(pair&& __p) = default;
-#else
+#ifdef _LIBCPP_HAS_NO_DEFAULTED_FUNCTIONS
_LIBCPP_INLINE_VISIBILITY
pair(pair&& __p) _NOEXCEPT_(is_nothrow_move_constructible<first_type>::value &&
is_nothrow_move_constructible<second_type>::value)
: first(_VSTD::forward<first_type>(__p.first)),
second(_VSTD::forward<second_type>(__p.second))
{
}
#endif
+ typedef integral_constant<bool,
+ (is_reference<_T1>::value || is_reference<_T2>::value)
+ && is_move_assignable<_T1Unref>::value
+ && is_move_assignable<_T2Unref>::value> _CanMoveAssign;
_LIBCPP_INLINE_VISIBILITY
pair&
- operator=(pair&& __p) _NOEXCEPT_(is_nothrow_move_assignable<first_type>::value &&
- is_nothrow_move_assignable<second_type>::value)
+ operator=(typename conditional<_CanMoveAssign::value, pair&&, __nat&&>::type __p)
+ _NOEXCEPT_(is_nothrow_move_assignable<_T1Unref>::value &&
+ is_nothrow_move_assignable<_T2Unref>::value)
{
first = _VSTD::forward<first_type>(__p.first);
second = _VSTD::forward<second_type>(__p.second);
Index: include/tuple
===================================================================
--- include/tuple
+++ include/tuple
@@ -184,7 +184,6 @@
{
_Hp value;
- __tuple_leaf& operator=(const __tuple_leaf&);
public:
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR __tuple_leaf()
_NOEXCEPT_(is_nothrow_default_constructible<_Hp>::value) : value()
@@ -215,7 +214,9 @@
template <class _Tp,
class = typename enable_if<
__lazy_and<
- __lazy_not<is_same<typename decay<_Tp>::type, __tuple_leaf>>
+ __lazy_not<is_same<_Tp&&, __tuple_leaf const&>>,
+ __lazy_not<is_same<_Tp&&, __tuple_leaf&&>>
+
, is_constructible<_Hp, _Tp>
>::value
>::type
@@ -277,12 +278,32 @@
>::value)),
"Attempted to construct a reference element in a tuple with an rvalue");}
- __tuple_leaf(const __tuple_leaf& __t) = default;
- __tuple_leaf(__tuple_leaf&& __t) = default;
+ using _HpUnref = typename remove_reference<_Hp>::type;
+ using _CanCopyAssign = integral_constant<bool,
+ __lazy_and<is_reference<_Hp>, is_copy_assignable<_HpUnref>>::value>;
+ using _CanMoveAssign = integral_constant<bool,
+ __lazy_and<is_reference<_Hp>, is_move_assignable<_HpUnref>>::value>;
+
+ constexpr __tuple_leaf(typename conditional<is_reference<_Hp>::value, __tuple_leaf, __nat>::type const& __other)
+ : value(_VSTD::forward<decltype(__other.value)>(__other.value)) {}
+
+ __tuple_leaf&
+ operator=(typename conditional<_CanCopyAssign::value, __tuple_leaf, __nat>::type const& __v) {
+ value = __v.value;
+ return *this;
+ }
+
+ __tuple_leaf&
+ operator=(typename conditional<_CanMoveAssign::value, __tuple_leaf, __nat>::type&& __v) {
+ value = _VSTD::move(__v.value);
+ return *this;
+ }
template <class _Tp>
_LIBCPP_INLINE_VISIBILITY
- __tuple_leaf&
+ typename enable_if<is_assignable<_Hp&, _Tp&&>::value
+ && !is_same<_Tp&&, __tuple_leaf const&>::value
+ && !is_same<_Tp&&, __tuple_leaf&&>::value, __tuple_leaf&>::type
operator=(_Tp&& __t) _NOEXCEPT_((is_nothrow_assignable<_Hp&, _Tp>::value))
{
value = _VSTD::forward<_Tp>(__t);
@@ -302,10 +323,9 @@
template <size_t _Ip, class _Hp>
class __tuple_leaf<_Ip, _Hp, true>
- : private _Hp
+ : _Hp
{
- __tuple_leaf& operator=(const __tuple_leaf&);
public:
_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR __tuple_leaf()
_NOEXCEPT_(is_nothrow_default_constructible<_Hp>::value) {}
@@ -327,7 +347,9 @@
template <class _Tp,
class = typename enable_if<
__lazy_and<
- __lazy_not<is_same<typename decay<_Tp>::type, __tuple_leaf>>
+ __lazy_not<is_same<_Tp&&, __tuple_leaf const&>>,
+ __lazy_not<is_same<_Tp&&, __tuple_leaf &&>>
+
, is_constructible<_Hp, _Tp>
>::value
>::type
@@ -351,12 +373,9 @@
explicit __tuple_leaf(integral_constant<int, 2>, const _Alloc& __a, _Tp&& __t)
: _Hp(_VSTD::forward<_Tp>(__t), __a) {}
- __tuple_leaf(__tuple_leaf const &) = default;
- __tuple_leaf(__tuple_leaf &&) = default;
-
template <class _Tp>
_LIBCPP_INLINE_VISIBILITY
- __tuple_leaf&
+ typename enable_if<is_assignable<_Hp&, _Tp&&>::value, __tuple_leaf&>::type
operator=(_Tp&& __t) _NOEXCEPT_((is_nothrow_assignable<_Hp&, _Tp>::value))
{
_Hp::operator=(_VSTD::forward<_Tp>(__t));
@@ -475,24 +494,6 @@
return *this;
}
- __tuple_impl(const __tuple_impl&) = default;
- __tuple_impl(__tuple_impl&&) = default;
-
- _LIBCPP_INLINE_VISIBILITY
- __tuple_impl&
- operator=(const __tuple_impl& __t) _NOEXCEPT_((__all<is_nothrow_copy_assignable<_Tp>::value...>::value))
- {
- __swallow(__tuple_leaf<_Indx, _Tp>::operator=(static_cast<const __tuple_leaf<_Indx, _Tp>&>(__t).get())...);
- return *this;
- }
-
- _LIBCPP_INLINE_VISIBILITY
- __tuple_impl&
- operator=(__tuple_impl&& __t) _NOEXCEPT_((__all<is_nothrow_move_assignable<_Tp>::value...>::value))
- {
- __swallow(__tuple_leaf<_Indx, _Tp>::operator=(_VSTD::forward<_Tp>(static_cast<__tuple_leaf<_Indx, _Tp>&>(__t).get()))...);
- return *this;
- }
_LIBCPP_INLINE_VISIBILITY
void swap(__tuple_impl& __t)
_______________________________________________
cfe-commits mailing list
[email protected]
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits