summaryrefslogtreecommitdiffstats
path: root/libcxx/include
diff options
context:
space:
mode:
authorEric Fiselier <eric@efcs.ca>2019-07-12 23:01:48 +0000
committerEric Fiselier <eric@efcs.ca>2019-07-12 23:01:48 +0000
commit882fdf68b74d3199cb84b062709b702ed610f547 (patch)
tree9eac114da019a5e0c19d173d975d9730dda50aa8 /libcxx/include
parent1dfae6fe505ffedf97e9f36d207cb8bbdc9255d8 (diff)
downloadbcm5719-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/tuple51
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
<
OpenPOWER on IntegriCloud