[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