This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Re: [v3 PATCH] Implement C++17 make_from_tuple.
- From: Jonathan Wakely <jwakely at redhat dot com>
- To: Ville Voutilainen <ville dot voutilainen at gmail dot com>
- Cc: libstdc++ <libstdc++ at gcc dot gnu dot org>, "gcc-patches at gcc dot gnu dot org" <gcc-patches at gcc dot gnu dot org>, Paolo Carlini <paolo dot carlini at oracle dot com>
- Date: Mon, 15 Aug 2016 11:13:30 +0100
- Subject: Re: [v3 PATCH] Implement C++17 make_from_tuple.
- Authentication-results: sourceware.org; auth=none
- References: <CAFk2RUbzcCFwjCf5tzR5iNnVANdyYKOcMzKe8rnQNB9KB7ZfRQ@mail.gmail.com>
On 11/08/16 03:04 +0300, Ville Voutilainen wrote:
+
+ template <typename _Tp, typename _Tuple, size_t... _Idx>
+ constexpr _Tp
+ __make_from_tuple_impl(_Tuple&& __t, index_sequence<_Idx...>)
+ { return _Tp(get<_Idx>(std::forward<_Tuple>(__t))...); }
We need to use std::get here.
+
+ template <typename _Tp, typename _Tuple>
+ constexpr _Tp
+ make_from_tuple(_Tuple&& __t)
+ {
+ return __make_from_tuple_impl<_Tp>(
+ std::forward<_Tuple>(__t),
+ make_index_sequence<tuple_size_v<decay_t<_Tuple>>>{});
+ }
#endif // C++17
It would be nice to add a conditional 'noexcept' to this function, but
doing so is a bit complicated, as I discovered when trying to do it
for std::apply().
What we need is a version of tuple_element which gives you the result
of std::get<I> on the tuple, taking into account its value category,
something like:
template<size_t _Nm, typename _Tuple>
struct __tuple_element_ref
: add_lvalue_reference<tuple_element_t<_Nm, _Tuple>> { };
template<size_t _Nm, typename _Tuple>
struct __tuple_element_ref<_Nm, _Tuple&&>
: add_rvalue_reference<tuple_element_t<_Nm, _Tuple>> { };
template<size_t _Nm, typename _Tuple>
struct __tuple_element_ref<_Nm, _Tuple&>
: add_lvalue_reference<tuple_element_t<_Nm, _Tuple>> { };
template<size_t _Nm, typename _Tuple>
using __tuple_element_ref_t
= typename __tuple_element_ref<_Nm, _Tuple>::type;
And then for std::__make_from_tuple_impl use:
noexcept(is_nothrow_constructible_v<_Tp, __tuple_element_ref_t<_Idx, _Tuple>...>)
And for std::__apply_impl use:
noexcept(is_nothrow_callable_v<_Fn&&(__tuple_element_ref_t<_Idx, _Tuple>...)>)