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>...)>)