summaryrefslogtreecommitdiff
path: root/libcxx/include/tuple
diff options
context:
space:
mode:
authorA. Jiang <de34@live.cn>2025-01-14 23:26:15 +0800
committerGitHub <noreply@github.com>2025-01-14 10:26:15 -0500
commite03c435d2a4900eb442c1f68b044c21cbc89acbe (patch)
tree43357a53e2b5c013d11cf3c73434ddfb08f16240 /libcxx/include/tuple
parent438e2ccd4ad18d23fc800d0ad9f4f667a547f868 (diff)
[libc++] Fix `tuple_cat` for element with unconstrained constructor (#122433)
Currently, when the result type is 1-`tuple`, `tuple_cat` possibly tests an undesired constructor of the element, due to conversion from the reference tuple to the result type. If the element type has an unconstrained constructor template, there can be extraneous hard error which shouldn't happen. This patch introduces a helper function template to select the element-wise constructor template of `tuple`, which can avoid such error. Fixes #41034.
Diffstat (limited to 'libcxx/include/tuple')
-rw-r--r--libcxx/include/tuple19
1 files changed, 16 insertions, 3 deletions
diff --git a/libcxx/include/tuple b/libcxx/include/tuple
index aca14ba408d3..0c96786ae6d0 100644
--- a/libcxx/include/tuple
+++ b/libcxx/include/tuple
@@ -1338,12 +1338,25 @@ struct __tuple_cat<tuple<_Types...>, __tuple_indices<_I0...>, __tuple_indices<_J
}
};
+template <class _TupleDst, class _TupleSrc, size_t... _Indices>
+inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 _TupleDst
+__tuple_cat_select_element_wise(_TupleSrc&& __src, __tuple_indices<_Indices...>) {
+ static_assert(tuple_size<_TupleDst>::value == tuple_size<_TupleSrc>::value,
+ "misuse of __tuple_cat_select_element_wise with tuples of different sizes");
+ return _TupleDst(std::get<_Indices>(std::forward<_TupleSrc>(__src))...);
+}
+
template <class _Tuple0, class... _Tuples>
inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 typename __tuple_cat_return<_Tuple0, _Tuples...>::type
tuple_cat(_Tuple0&& __t0, _Tuples&&... __tpls) {
- using _T0 _LIBCPP_NODEBUG = __libcpp_remove_reference_t<_Tuple0>;
- return __tuple_cat<tuple<>, __tuple_indices<>, typename __make_tuple_indices<tuple_size<_T0>::value>::type>()(
- tuple<>(), std::forward<_Tuple0>(__t0), std::forward<_Tuples>(__tpls)...);
+ using _T0 _LIBCPP_NODEBUG = __libcpp_remove_reference_t<_Tuple0>;
+ using _TRet _LIBCPP_NODEBUG = typename __tuple_cat_return<_Tuple0, _Tuples...>::type;
+ using _T0Indices _LIBCPP_NODEBUG = typename __make_tuple_indices<tuple_size<_T0>::value>::type;
+ using _TRetIndices _LIBCPP_NODEBUG = typename __make_tuple_indices<tuple_size<_TRet>::value>::type;
+ return std::__tuple_cat_select_element_wise<_TRet>(
+ __tuple_cat<tuple<>, __tuple_indices<>, _T0Indices>()(
+ tuple<>(), std::forward<_Tuple0>(__t0), std::forward<_Tuples>(__tpls)...),
+ _TRetIndices());
}
template <class... _Tp, class _Alloc>