diff options
| author | Eric Fiselier <eric@efcs.ca> | 2019-07-12 23:01:48 +0000 |
|---|---|---|
| committer | Eric Fiselier <eric@efcs.ca> | 2019-07-12 23:01:48 +0000 |
| commit | 882fdf68b74d3199cb84b062709b702ed610f547 (patch) | |
| tree | 9eac114da019a5e0c19d173d975d9730dda50aa8 /libcxx/include | |
| parent | 1dfae6fe505ffedf97e9f36d207cb8bbdc9255d8 (diff) | |
| download | bcm5719-llvm-882fdf68b74d3199cb84b062709b702ed610f547.tar.gz bcm5719-llvm-882fdf68b74d3199cb84b062709b702ed610f547.zip | |
Fix non-conformance it `std::tuple`.
Previously we implemented all one trillion tuple-like constructors using
a single generic overload. This worked fairly well, except that it
differed in behavior from the standard version because it didn't
consider both T&& and T const&. This was observable for certain
types.
This patch addresses that issue by splitting the generic constructor
in two. We now provide both T&& and T const& versions of the
tuple-like constructors (sort of).
llvm-svn: 365973
Diffstat (limited to 'libcxx/include')
| -rw-r--r-- | libcxx/include/tuple | 51 |
1 files changed, 31 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 < |

