[v3 PATCH] Implement C++17 make_from_tuple.
Jonathan Wakely
jwakely@redhat.com
Mon Aug 15 10:13:00 GMT 2016
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>...)>)
More information about the Libstdc++
mailing list