diff options
-rw-r--r-- | libcxx/include/tuple | 51 | ||||
-rw-r--r-- | libcxx/test/std/utilities/tuple/tuple.tuple/tuple.cnstr/convert_copy.pass.cpp | 16 |
2 files changed, 47 insertions, 20 deletions
diff --git a/libcxx/include/tuple b/libcxx/include/tuple index de30e86c72b..031d25a9854 100644 --- a/libcxx/include/tuple +++ b/libcxx/include/tuple @@ -601,6 +601,25 @@ class _LIBCPP_TEMPLATE_VIS tuple } }; + template <class _Tuple, bool _DisableIfLValue> + using _EnableImplicitTupleLikeConstructor = _EnableIf< + _CheckTupleLikeConstructor< + __tuple_like_with_size<_Tuple, sizeof...(_Tp)>::value + && !_PackExpandsToThisTuple<_Tuple>::value + && (!is_lvalue_reference<_Tuple>::value || !_DisableIfLValue) + >::template __enable_implicit<_Tuple>(), + bool + >; + + template <class _Tuple, bool _DisableIfLValue> + using _EnableExplicitTupleLikeConstructor = _EnableIf< + _CheckTupleLikeConstructor< + __tuple_like_with_size<_Tuple, sizeof...(_Tp)>::value + && !_PackExpandsToThisTuple<_Tuple>::value + && (!is_lvalue_reference<_Tuple>::value || !_DisableIfLValue) + >::template __enable_explicit<_Tuple>(), + bool + >; template <size_t _Jp, class ..._Up> friend _LIBCPP_CONSTEXPR_AFTER_CXX11 typename tuple_element<_Jp, tuple<_Up...> >::type& get(tuple<_Up...>&) _NOEXCEPT; template <size_t _Jp, class ..._Up> friend _LIBCPP_CONSTEXPR_AFTER_CXX11 @@ -815,35 +834,27 @@ public: typename __make_tuple_types<tuple, sizeof...(_Tp), sizeof...(_Up)>::type(), _VSTD::forward<_Up>(__u)...) {} - template <class _Tuple, - typename enable_if - < - _CheckTupleLikeConstructor< - __tuple_like_with_size<_Tuple, sizeof...(_Tp)>::value - && !_PackExpandsToThisTuple<_Tuple>::value - >::template __enable_implicit<_Tuple>(), - bool - >::type = false - > + template <class _Tuple, _EnableImplicitTupleLikeConstructor<_Tuple, true> = false> _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 tuple(_Tuple&& __t) _NOEXCEPT_((is_nothrow_constructible<_BaseT, _Tuple>::value)) : __base_(_VSTD::forward<_Tuple>(__t)) {} - template <class _Tuple, - typename enable_if - < - _CheckTupleLikeConstructor< - __tuple_like_with_size<_Tuple, sizeof...(_Tp)>::value - && !_PackExpandsToThisTuple<_Tuple>::value - >::template __enable_explicit<_Tuple>(), - bool - >::type = false - > + template <class _Tuple, _EnableImplicitTupleLikeConstructor<const _Tuple&, false> = false> + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 + tuple(const _Tuple& __t) _NOEXCEPT_((is_nothrow_constructible<_BaseT, const _Tuple&>::value)) + : __base_(__t) {} + template <class _Tuple, _EnableExplicitTupleLikeConstructor<_Tuple, true> = false> _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 explicit tuple(_Tuple&& __t) _NOEXCEPT_((is_nothrow_constructible<_BaseT, _Tuple>::value)) : __base_(_VSTD::forward<_Tuple>(__t)) {} + template <class _Tuple, _EnableExplicitTupleLikeConstructor<const _Tuple&, false> = false> + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 + explicit + tuple(const _Tuple& __t) _NOEXCEPT_((is_nothrow_constructible<_BaseT, const _Tuple&>::value)) + : __base_(__t) {} + template <class _Alloc, class _Tuple, typename enable_if < diff --git a/libcxx/test/std/utilities/tuple/tuple.tuple/tuple.cnstr/convert_copy.pass.cpp b/libcxx/test/std/utilities/tuple/tuple.tuple/tuple.cnstr/convert_copy.pass.cpp index 41f73328ab7..89f67a227bd 100644 --- a/libcxx/test/std/utilities/tuple/tuple.tuple/tuple.cnstr/convert_copy.pass.cpp +++ b/libcxx/test/std/utilities/tuple/tuple.tuple/tuple.cnstr/convert_copy.pass.cpp @@ -31,6 +31,15 @@ struct Implicit { Implicit(int x) : value(x) {} }; +struct ExplicitTwo { + ExplicitTwo() {} + ExplicitTwo(ExplicitTwo const&) {} + ExplicitTwo(ExplicitTwo &&) {} + + template <class T, class = typename std::enable_if<!std::is_same<T, ExplicitTwo>::value>::type> + explicit ExplicitTwo(T) {} +}; + struct B { int id_; @@ -136,6 +145,13 @@ int main(int, char**) std::tuple<Implicit> t2 = t1; assert(std::get<0>(t2).value == 42); } + { + static_assert(std::is_convertible<ExplicitTwo&&, ExplicitTwo>::value, ""); + static_assert(std::is_convertible<std::tuple<ExplicitTwo&&>&&, const std::tuple<ExplicitTwo>&>::value, ""); + ExplicitTwo e; + std::tuple<ExplicitTwo> t = std::tuple<ExplicitTwo&&>(std::move(e)); + ((void)t); + } return 0; } |