[clang] [libcxx] [libc++] Implement LWG3528 (`make_from_tuple` can perform (the equivalent of) a C-style cast) (PR #85263)
A. Jiang via cfe-commits
cfe-commits at lists.llvm.org
Wed Mar 20 02:39:28 PDT 2024
================
@@ -1386,9 +1386,19 @@ inline _LIBCPP_HIDE_FROM_ABI constexpr decltype(auto) apply(_Fn&& __f, _Tuple&&
std::forward<_Tuple>(__t),
typename __make_tuple_indices<tuple_size_v<remove_reference_t<_Tuple>>>::type{}))
+#if _LIBCPP_STD_VER >= 20
template <class _Tp, class _Tuple, size_t... _Idx>
inline _LIBCPP_HIDE_FROM_ABI constexpr _Tp __make_from_tuple_impl(_Tuple&& __t, __tuple_indices<_Idx...>)
+ noexcept(noexcept(_Tp(std::get<_Idx>(std::forward<_Tuple>(__t))...)))
+ requires is_constructible_v<_Tp, decltype(std::get<_Idx>(std::forward<_Tuple>(__t)))...> {
+ return _Tp(std::get<_Idx>(std::forward<_Tuple>(__t))...);
+}
+#else
+template <class _Tp, class _Tuple, size_t... _Idx>
+inline _LIBCPP_HIDE_FROM_ABI constexpr _Tp __make_from_tuple_impl(_Tuple&& __t, __tuple_indices<_Idx...>,
+ enable_if_t<is_constructible_v<_Tp, decltype(std::get<_Idx>(std::forward<_Tuple>(__t)))...>> * = nullptr)
_LIBCPP_NOEXCEPT_RETURN(_Tp(std::get<_Idx>(std::forward<_Tuple>(__t))...))
+#endif // _LIBCPP_STD_VER >= 20
template <class _Tp, class _Tuple>
----------------
frederick-vs-ja wrote:
Just making `__make_from_tuple_impl` SFINAE-friendly is insufficient and leads to worse diagnostic messages.
I guess we can write the following to make `make_from_tuple` SFINAE-friendly. `(requires` can be used since C++20 to make the implemenation clearer.)
```C++
template <class _Tp, class _Tuple,
class _Seq = typename __make_tuple_indices<tuple_size_v<remove_reference_t<_Tuple>>>::type, class = void>
inline constexpr bool __can_make_from_tuple = false;
template <class _Tp, class _Tuple, size_t... _Idx>
inline constexpr bool __can_make_from_tuple<
_Tp, _Tuple, index_sequence<_Idx...>,
enable_if_t<is_constructible_v<_Tp, decltype(std::get<_Idx>(std::declval<_Tuple>()))...>>> = true;
template <class _Tp, class _Tuple, enable_if_t<__can_make_from_tuple<_Tp, _Tuple>, int> = 0>
inline _LIBCPP_HIDE_FROM_ABI constexpr _Tp make_from_tuple(_Tuple&& __t)
_LIBCPP_NOEXCEPT_RETURN(std::__make_from_tuple_impl<_Tp>(
std::forward<_Tuple>(__t), typename __make_tuple_indices<tuple_size_v<remove_reference_t<_Tuple>>>::type{}))
```
And perhaps we shouldn't touch `__make_from_tuple_impl` if it's OK to constrain `make_from_tuple`.
https://github.com/llvm/llvm-project/pull/85263
More information about the cfe-commits
mailing list